Originally Published: Thursday, 19 July 2001 Author: Subhasish Ghosh
Published to: learn_articles_firststep/General Page: 5/6 - [Printable]

Bootstrapping a Linux system - An Analysis

Ever wonder what happens between powering on your system and the logon prompt? You see all the screen messages, but what do they mean? Linux.com writer Subhasish Ghosh wondered the same thing, and went to find out in Bootstrapping a Linux System.

  << Page 5 of 6  >>

The startup_32( ) function - 1st function. What does it do?

Okay, let's get to the confusing parts straight away. There are two functions called startup_32( ). Though both these two startup_32( ) functions are assembly language functions and are required for bootstrap process they are totally different functions. The one we refer to here is coded in the /usr/src/linux-2.4.2/arch/i386/boot/compressed/head.S file. After setup( ) code is executed this function has been moved either to physical address 0x00100000 or to physical address 0x00001000, depending on whether the Kernel Image was loaded "high" or "low" in RAM.

When executed this function performs the following operations:

  1. The segmentation registers are initialized along with a provisional stack.
  2. The area of uninitialized data in the Kernel is filled with zeroes. It is identified by symbols _edata and _end.
  3. It then executes a function decompress_kernel( ). This function is used to decompress the Linux Kernel image. As a result, the "Uncompressing Linux . . ." message is displayed on the screen. After the Linux Kernel image has been decompressed correctly, the "OK, booting the kernel." message is shown. One very significant question here is: Okay, we understand the Linux Kernel image is decompressed, but where is it loaded? The answer is: If the Linux Kernel image was loaded "low", then the decompressed kernel is placed at physical address 0x00100000. Otherwise, if the Linux Kernel image was loaded "high", the decompressed kernel is placed in a temporary buffer located after the compressed image. The decompressed kernel image is then moved to its final position, which starts at physical address 0x00100000.
  4. Finally code execution jumps to the physical address 0x00100000.

Now, after this 4th operation code execution is taken over by the other startup_32( ) function. In other words, the second one takes over the bootstrapping process.

The startup_32( ) function - 2nd function. What does it do?

The decompressed Linux kernel image begins with another startup_32( ) function. This function exists in the /usr/src/linux-2.4.2/arch/i386/kernel/head.S file.

At this point you might be tempted to ask: Hey, using two different functions having the same name... Doesn't this cause problem? The answer is: Well, no it doesn't at all. Both functions are executed by jumping to their initial physical addresses and hence they are executed in their own execution environments. No problem at all!

Now, let's look at the second startup_32( ) function's functionality. What does it do? When executed this function essentially sets up the execution environment for the first Linux process (process 0). The function performs the following operations:

  1. The segmentation registers are initialized with their final values.
  2. Sets up the Kernel Mode stack for process 0.
  3. It then invokes and executes a function setup_idt( ) that fills the IDT (Interrupt Descriptor Table) with null interrupt handlers.
  4. The system parameters obtained from BIOS is put in the first page frame.
  5. The "Model" of the processor is identified.
  6. Loads the gdtr and idtr registers with the addresses of the GDT and IDT tables.
  7. It finally makes a jump to the start_kernel( ) function.




  << Page 5 of 6  >>