So far we have arrived at the gate leading to the real kernel. And we’d better stop for a short break in order that we would have more energy to go ahead. Now let’s examine what we do to memory these days. 

Virtually what we want to do is drawing some pictures to describe the layout of the memory in various phases. For the layout is related to the bootloader, we’d better make our work based on the following assumption:
The machine has two systems installed (Windows XP and Linux) and uses LILO as the bootloader. Let us look at the LILO configuration:

/* LILO Configuration – /etc/lilo.conf */
boot=/dev/hda
map=/boot/map
install=/boot/boot.b
prompt
timeout=100
compact
default=Linux
image=/boot/vmlinuz-2.6.15.3
         label=Linux
         root=/dev/hda2
         read-only
other=/dev/hda1
         label=WindowsXP

Here the ‘boot=/dev/hda’ indicates it installed the LILO on the MBR of first hard disk. ‘root=/dev/had2′ indicates it installs linux system on the second partition of the first disk and ‘other=/dev/hda1′ indicates it installs windows system on the first partition of the first disk. Since lilo.conf is not read at boot time, the MBR needs to be "refreshed" when this is changed. If you do not do this upon rebooting, none of your changes to lilo.conf will be reflected at startup. Like getting LILO into the MBR in the first place, you need to run: ‘$ /sbin/lilo -v -v’. The ‘-v -v’ flags give you very verbose output.

Now we could switch on our machine! (‘<->’ means ‘begin from … end before …’)
1. Power on <-> BIOS routine
Chaos, that is the character of memory at this time.

2. BIOS routine <–> Bootloader 1st stage(MBR)
BIOS routine runs over and prepares to execute the code loaded from MBR. MBR contains the 1st stage bootloader of the LILO.

       |                        |
0A0000 +————————+
       |                        |
010000 +————————+
       |          MBR           | <- MBR (07C00 ~ 07E00)
001000 +————————+
       |                        |
000600 +————————+ 
       |      BIOS use only     |
000000 +————————+

3. Bootloader 1st stage(MBR) <-> Bootloader 2nd stage
The bootloader 1st stage moves itself to 0×090000, sets up the Real Mode stack (ranging from 0x09b000 to 0x09a200) and loads the 2nd stage of the LILO from 0x09b000.

          |                        |
0A0000 +————————+
       |      2nd bootloader    |
09b000 +————————+
       |     Real mode stack    |
09A200 +————————+
       |     1st bootloader     |
09A000 +————————+
       |                        |
010000 +————————+
       |      MBR(useless)      | <- MBR (07C00 ~ 07E00)
001000 +————————+
       |  Reserved for MBR/BIOS |
000800 +————————+
       |  Typically used by MBR |
000600 +————————+ 
       |      BIOS use only     |
000000 +————————+

4. Bootloader 2nd stage <-> setup.S
The 2nd bootloader copies the integrated boot loader of the kernel image to address 0×090000, the setup() code to address 0×090200, and the rest of the kernel image to address 0×00010000(called ‘low address’ for small Kernel Images compiled with ‘make zImage’) or 0×00100000(‘high address’ for big Kernel Images compiled with ‘make bzImage’).

zImage:

       |                        |
0A0000 +————————+
       |      2nd bootloader    |
09b000 +————————+
       |     Real mode stack    |
09A200 +————————+
       |     1st bootloader     |
09A000 +————————+
       |  Stack/heap/cmdline    | For use by the kernel real-mode code.
098000 +————————+ 
       |         Kernel setup   | The kernel real-mode code.
090200 +————————+
       |    Kernel boot sector  | The kernel legacy boot sector.
090000 +————————+
       |          zImage        | The bulk of the kernel image.
010000 +————————+
       |       MBR(useless)     | <- MBR (07C00 ~ 07E00)
001000 +————————+
       |  Reserved for MBR/BIOS |
000800 +————————+
       |  Typically used by MBR |
000600 +————————+
       |      BIOS use only     |
000000 +————————+

bzImage:

       +————————+
       |          bzImage       |
0100000+————————+
       |                        |
0A0000 +————————+
       |      2nd bootloader    |
09b000 +————————+
       |     Real mode stack    |
09A200 +————————+
       |     1st bootloader     |
09A000 +————————+
       |    Stack/heap/cmdline  | For use by the kernel real-mode code.
098000 +————————+ 
       |        Kernel setup    | The kernel real-mode code.
090200 +————————+
       |  Kernel boot sector    | The kernel legacy boot sector.
090000 +————————+
       |                        |
010000 +————————+
       |       MBR(useless)     | <- MBR (07C00 ~ 07E00)
001000 +————————+
       |  Reserved for MBR/BIOS |
000800 +————————+
       |  Typically used by MBR |
000600 +————————+
       |      BIOS use only     |
000000 +————————+

5. setup.S <-> head.S
The setup() checks the position of the Kernel Image loaded in RAM. If loaded "low" in RAM (when using zImage, at physical address 0×00010000) it is moved to "high" in RAM (at physical address 0×00001000). But, if the Kernel image is a "bzImage" loaded in "high" of RAM already, then it’s NOT moved anywhere. It also move the system to its rightful place (0×00000 ~ [<0x090000]). Some system parameters were placed from 0×090000 to 0×090200, which stores the legecy boot sector.

           +————————+
       |         bzImage        |
0100000+————————+
       |                        |
098000 +————————+ 
>       |      Kernel setup      |
090200 +————————+
       |     System parameters  | collected by setup()
090000 +————————+
       |                        |
       |                        |
       |          System        |
       |                        |
       |                        |
000000 +————————+

OK, it is much clear. and now we can walk through the door to the real kernel!

© 2006, bigwhite. 版权所有.

Related posts:

  1. Goto 'Bootstrap'
  2. Retired 'bootsect.S'
  3. Begin 'setup.S'
  4. Inside the 'i386'
  5. C单元测试包设计与实现