# The Linux Kernel/Booting

What does the kernel do when you boot your computer? There are several major steps that happen prior to the logon screen appearing when you boot the GNU/Linux system. In order they are:

## Firmware/Post

Your computer firmware/BIOS (Basic Input Output System) is a small computer program whose starting address is loaded into the program counter register of your computer's CPU when power is applied to your system. The firmware/POST (Power-On Self Test) performs a few rudimentary tests on your computer system (usually memory checks, including possibly a barber-pole memory sieve routine to check your memory, checks to see if you have a keyboard, mouse, hard drive, etc. on your system. It then goes through a user defined list of devices, looking for a small program called a boot loader. The list of devices could be a CD-ROM, DVD drive, hard disk, etc. When it finds a bootloader, it loads the boot loader's starting address into the CPU's program counter register.

## Bootloader

The Linux bootloader may be LILO, or now more commonly GRUB. The bootloader may have only one operating system to boot, or it may have several, and if it has several, it presents a list of which system to load. The operating system need not be GNU/Linux.
If the GNU/Linux operating system is selected, and the system is on Intel X86/32 hardware, then the bootloader is running in "real" x86 mode (running as if the CPU is an 8086), even though the processor may be a Pentium 4/Celeron/Xeon.
The job of the bootloader is to reset all CPU registers, load an operating system into memory and start it running by loading the starting address into the CPU's Program Counter. Since the Intel 8086 couldn't support more than 640k of memory and the modern Linux kernel is bigger than 640k, special jump instructions (trampoline) are used to load the compressed Linux kernel called the zImage into memory.
The bootloader loads several programs to help it do this job, including setup.S and system.
setup.S is responsible for getting the system data from the BIOS, and putting it into appropriate places in system memory. setup.S asks the BIOS for memory, disk, and other parameters, and relocates itself and system from the low memory location where it was loaded, to a "safe" place: 0x90000-0x901FF (INITSEG), where the boot-block used to be. setup.S then uncompresses the compressed (zImage) kernel image at starting address 0x10000 or 64K, just beyond the firmware's data space (SYSSEG). It then moves the uncompressed kernel from address 0x10000 to address 0x1000 (4k, leaving one page of low memory free) switches from "real" x86 mode to emm386 mode, and loads the kernels' starting address into the CPU's Program Counter register (starts the kernel running).
One of the last things setup.S does is run the video setup and detection code, video.S. The shuffling of the kernel back and forth in memory is to overcome limitations of the PC BIOS memory addressability (640k), and free up several hundred kilobytes of system memory (the actual amount freed is reported by the system). The 4k is used for handling virtual memory. The special load instructions (trampoline) are required to 'cheat' the system, as the instructions load part of the kernel into memory locations beyond the 640k barrier that the (then currently running "real mode") system knows about. In the process of shuffling the kernel around, the memory originally written to by the BIOS, and also where the setup and system programs were loaded are overwritten by the kernel image, hence the need for moving them to a safe place, beyond where the uncompressed kernel image is loaded. The actual load is slightly more complicated on x86 systems as not all BIOSs report their memory on the same registers, report information in different ways, or map their memory/system resources in unconventional ways. Also, some BIOSs must be prodded for information several times or have A20 Gate problems.
Other computer architectures may not have the limitations of the Intel x86 processor, and so loading the Linux kernel is done in a much more straightforward manner.