Booting the Kernel

This article is a description of the steps required to boot the Linux kernel. While this kind of information is not relevant to the system's functionality, it is interesting to see how the different architectures bring up the system.
Booting a SPARC Station

Bringing up a SPARC computer is similar to booting the Alpha on the user side, and similar to booting the PC on the software side.

The user sees that the firmware loads and executes a program, which in turn is able to retrieve and uncompress a file found on a disk partition. The “program” in question is called SILO, and it can read files from either a ext2 or a ufs partition. Unlike MILO (like LILO), SILO is able to boot another operating system. There is no need for this ability on the Alpha, because the firmware can boot multiple systems; once you run MILO, you have already made your choice (the right choice—Linux).

When a SPARC computer boots, the firmware loads a boot sector after performing all the hardware checks and device initialization. It's interesting to note that Sbus devices are platform independent, and their initialization code is portable Forth code rather than machine language bound to a particular processor.

The boot sector loaded is what you find in /boot/first.b in your Linux-SPARC system and is a bare 512 bytes. It is loaded to address 0x4000, and its role is retrieving /boot/second.b from disk and writing it to address 0x280000 (2.5 MB); this address was chosen because the SPARC specifications state that at least 3MB of RAM must be mapped at boot time.

The second-stage boot loader then does everything else. It is linked with libext2.a to access system partitions and can thus load a kernel image from your Linux file system. It can also uncompress the image, since it includes the inflate.c routine from the gzip program.

The routine second.b accesses a configuration file called /etc/silo.conf, similar in shape to lilo.conf. Since the file is read at boot time, there's no need to re-install the kernel maps when a new kernel is added to the boot choices. When SILO shows its prompt, you can choose any kernel image (or other operating system) specified in the silo.conf file, or you can specify a complete device/path name pair to load a different kernel image without editing the configuration file.

SILO loads the disk file to address 0x4000. This means the kernel must be smaller than 2.5MB; if it is larger, SILO will refuse to overwrite its own image. No conceivable Linux-SPARC kernel currently exceeds that size, unless it was compiled with -g to have debugging information available. In this case, the kernel image must be stripped before being handed to SILO.

Finally, SILO performs kernel decompression and/or remapping to place the image at virtual address 0xf0004000. The code that takes over after SILO is finished is arch/sparc/kernel/head.S. The source includes all the trap tables for the processor and the actual code to set the machine up and call start_kernel(). The SPARC version of head.S is quite big.

start_kernel and On

After architecture-specific initialization is complete, the init/main.c program takes control of whichever processor you are using.

The start_kernel() function first calls setup_arch(), which is the last architecture-specific function. Unlike other code, however, setup_arch() can exploit all the processor's features and is a much easier source file to deal with than those described earlier. This function is defined in the kernel/setup.c code under each architecture source tree.

The start_kernel() function then initializes all the kernel's subsystems—IPC, networking, buffer cache and so on. After all initialization is done, these two lines complete the code:

kernel_thread(init, NULL, 0);

The init thread is process number 1: it mounts the root partition, executes /linuxrc if CONFIG_INITRD has been selected at compile time, and then executes the init program. If init can't be found, /etc/rc is executed. In general, using rc is discouraged, since init is much more flexible than a shell script in handling system configuration. As a matter of fact, version 2.1.21 of the kernel removed the /etc/rc{/} option, making it obsolete. If neither init nor /etc/rc will run or if they exit, /bin/sh is executed repeatedly (but 2.1.21 and later kernels will execute it only once). This feature only exists as a safeguard in case the init file is removed or corrupted by mistake. If you remove a.out support from the kernel without recompiling your old init, you'll enjoy having at least a shell running after reboot. The kernel has no more tasks to do after spawning process number 1, and all other functions are handled in user space by init, /etc/rc or /bin/sh. And process 0? The so called “idle” task executes cpu_idle(), a function that calls idle() in an endless loop. idle() in turn is an architecture-dependent function that is usually in charge of turning off the processor to save power and increase the processor's lifetime.

Alessandro is a Linux enthusiast who writes documentation because he's not smart enough to write software. His 486 is specialized in grepping through source code, and humbly leaves real jobs to the Alpha and the SPARC. He can be reached via e-mail at



Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Good one

Anonymous's picture

Good one