News Archive (1999-2012) | 2013-current at LinuxGizmos | Current Tech News Portal |    About   

Running Linux on the Sega Dreamcast (Part 4)

Sep 24, 1997 — by Rick Lehrbaum — from the LinuxDevices Archive — 14 views

Building a Dreamcast Linux kernel

Now that we have a complete cross development toolchain, it's time to put the tools to work. As I mentioned before, I have pre-configured our Linux kernel sources so that they are already set up for the Dreamcast, so all that's needed now is to run the commands in Figure 6 to actually compile and link the kernel. The result is a file called zImage, located in kernel/arch/sh/boot/; this file contains a compressed kernel image, wrapped by a short procedure that knows how to decompress the kernel into memory.

Later on, after you have successfully booted this kernel as-is, feel free to use menuconfig to adjust kernel settings. Recompile using the procedure in Figure 6, and observe the results by booting (or not, as the case may be) the new kernel on the Dreamcast. One useful exercise is to see just how small a kernel image you can produce that still contains the functionality you need.

    # cd kernel
    # make ARCH=sh CROSS_COMPILE=sh4-linux-
    clean dep zImage
    # cd ..

Figure 6: Building the Dreamcast Linux kernel

Building a Dreamcast Bootloader

With a successfully compiled kernel image, it would seem that the next step would be to produce a bootloader for loading the kernel image into the Dreamcast's memory at startup.

As it turns out, however, we aren't ready to do that just yet. Recall that the Dreamcast's firmware loads a single executable image into RAM at the end of the boot process, and unless that application knows how to work with the Dreamcast's GD-ROM drive there is no way to load additional data from the disk. The bootloader we will use does not know how to operate the GD-ROM drive, so we must load everything we will need at runtime in one fell swoop: the bootloader, the kernel image, and the ramdisk image.

Once everything is loaded, the bootloader needs to dissect memory back into a distinct kernel and ramdisk image, which requires the bootloader to know their exact sizes prior to startup. The only way to determine this is to actually build the kernel (which we have now done) and ramdisk image, compute their sizes, and then provide this information to the bootloader's source code during its build process.

So, we will build some applications, populate a ramdisk image with them, and then return to build the bootloader/kernel/ramdisk image for the Dreamcast's boot firmware to load into memory.

Building an application

Perhaps the most important application in a basic Linux system is a command shell. Without a shell, it is impossible to interactively instruct the operating system to load other programs, mount remote directories, or simply probe the system's setup to troubleshoot problems or just see what's going on.

If you don't have a keyboard for your Dreamcast, then you may not find the availability of an interactive shell to be all that interesting: you don't have any way to type commands! Build a shell anyway, however, because a shell can also be used to run command scripts that you include on the ramdisk. And once you have seen the procedure for getting a shell up and running on the Dreamcast, you will be able to replace the shell with any other program you want to run.

The procedure in Figure 7 describes how to build BusyBox for the Dreamcast. In addition to a basic shell facility, Busybox also includes small versions of several other useful utilities, including the mount, ls and modprobe programs.

The first steps in Figure 7 create a directory called initrd, which will contain the contents of the initial ramdisk. (initrd is the traditional name for an initial ramdisk.) The PREFIX parameter passed to make causes Busybox to install itself properly relative to the location of this directory. The DOSTATIC setting tells sh4-linux-gcc to not use shared libraries for Busybox, which is what we want because we have not installed a dynamic linker.

    # mkdir -p initrd
    # export INITRD=`pwd`/initrd

    # tar xzf busybox-0.60.1.tar.gz
    # patch -p0 < busybox-0.60.1-sh-linux.diff

    # cd busybox-0.60.1
    # make CROSS=sh4-linux- DOSTATIC=true
    CFLAGS_EXTRA="-I ${PREFIX}/${TARGET}/include"
    PREFIX=${INITRD} clean all install

    # cd ..

Figure 7: Commands to build and install Busybox

Like all the other software we have used so far, Busybox is highly configurable. Its most important settings can be found in Config.h and libbb/libbb.h.

Make device nodes on the initial ramdisk

Since the contents of the ${INITRD} directory will be the contents of Linux's root directory on the Dreamcast, it has to contain everything the kernel could possibly need at run time. In addition to a shell or some other application, then, we must also provide device nodes so that applications can communicate with Linux's device drivers.

On the Dreamcast, there is only one absolutely essential device node: the /dev/console node. Without this node, text-mode applications cannot communicate with the console device, which means you cannot see any text output on the Dreamcast's display. Use the commands in Figure 8 to create the console device node.

    # mkdir -p ${INITRD}/dev
    # mknod ${INITRD}/dev/console c 5 1

Figure 8: Commands to create the /dev/console device node

Creating a ramdisk image

Now that we have populated a directory structure to look like our ramdisk, it is time to take an image of that directory structure so that we can bind it to the Dreamcast's bootloader. The commands in Figure 9 use the loop device to create a compressed snapshot of the ${INITRD} directory in the file initrd.bin. The file initrd.img is the uncompressed snapshot.

    # dd if=/dev/zero of=initrd.img bs=1k count=4096
    # mke2fs -F -vm0 initrd.img
    # mkdir initrd.dir
    # mount -o loop initrd.img initrd.dir
    # (cd initrd ; tar cf - .) | (cd initrd.dir ; tar xvf -)
    # umount initrd.dir
    # gzip -c -9 initrd.img > initrd.bin

Figure 9: Creating a compressed ramdisk image

Building the bootloader

The Dreamcast bootloader is part of a collection of Hitachi SH bootloaders called sh-boot. The Dreamcast-specific code is buried deep inside the sh-boot directory tree, in the subdirectory tools/dreamcast/, and includes both a Makefile for building the bootloader image itself, and a script called that can be used to build a bootable Dreamcast CD from the bootloader image. Sh-boot also includes a utility called scramble, which “scrambles” the contents of the Dreamcast CD's ISO9660 data into a primitive encryption format expected by the Dreamcast's boot firmware.

The procedure for building the Dreamcast bootloader image is shown in Figure 10. Do those commands now.

    # tar xzf sh-boot-20010831-1455.tar.gz
    # patch -p0 < sh-boot-20010831-1455.diff
    # cd sh-boot/tools/dreamcast
    # cp ../../../kernel/arch/sh/boot/zImage ./zImage.bin
    # cp ../../../initrd.bin .
    # make scramble kernel-boot.bin

Figure 10: Commands to make a bootloader image

The bootloader image is the file kernel-boot.bin. This file contains the bootloader itself, plus the compressed Linux kernel and initial ramdisk images.


Story navigation . . .

This article was originally published on and has been donated to the open source community by QuinStreet Inc. Please visit for up-to-date news and articles about Linux and open source.

Comments are closed.