Commit dec04cff authored by H. Peter Anvin's avatar H. Peter Anvin Committed by Linus Torvalds

Further update of the i386 boot documentation

A number of items in the i386 boot documentation have been either
vague, outdated or hard to read.  This text revision adds several more
examples, including a memory map for a modern kernel load.  It also
adds a field-by-field detailed description of the setup header, and a
bootloader ID for Qemu.
Signed-off-by: default avatarH. Peter Anvin <hpa@zytor.com>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 66123549
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
---------------------------- ----------------------------
H. Peter Anvin <hpa@zytor.com> H. Peter Anvin <hpa@zytor.com>
Last update 2007-05-07 Last update 2007-05-16
On the i386 platform, the Linux kernel uses a rather complicated boot On the i386 platform, the Linux kernel uses a rather complicated boot
convention. This has evolved partially due to historical aspects, as convention. This has evolved partially due to historical aspects, as
...@@ -52,7 +52,8 @@ zImage kernels, typically looks like: ...@@ -52,7 +52,8 @@ zImage kernels, typically looks like:
0A0000 +------------------------+ 0A0000 +------------------------+
| Reserved for BIOS | Do not use. Reserved for BIOS EBDA. | Reserved for BIOS | Do not use. Reserved for BIOS EBDA.
09A000 +------------------------+ 09A000 +------------------------+
| Stack/heap/cmdline | For use by the kernel real-mode code. | Command line |
| Stack/heap | For use by the kernel real-mode code.
098000 +------------------------+ 098000 +------------------------+
| Kernel setup | The kernel real-mode code. | Kernel setup | The kernel real-mode code.
090200 +------------------------+ 090200 +------------------------+
...@@ -74,9 +75,8 @@ When using bzImage, the protected-mode kernel was relocated to ...@@ -74,9 +75,8 @@ When using bzImage, the protected-mode kernel was relocated to
0x100000 ("high memory"), and the kernel real-mode block (boot sector, 0x100000 ("high memory"), and the kernel real-mode block (boot sector,
setup, and stack/heap) was made relocatable to any address between setup, and stack/heap) was made relocatable to any address between
0x10000 and end of low memory. Unfortunately, in protocols 2.00 and 0x10000 and end of low memory. Unfortunately, in protocols 2.00 and
2.01 the command line is still required to live in the 0x9XXXX memory 2.01 the 0x90000+ memory range is still used internally by the kernel;
range, and that memory range is still overwritten by the early kernel. the 2.02 protocol resolves that problem.
The 2.02 protocol resolves that problem.
It is desirable to keep the "memory ceiling" -- the highest point in It is desirable to keep the "memory ceiling" -- the highest point in
low memory touched by the boot loader -- as low as possible, since low memory touched by the boot loader -- as low as possible, since
...@@ -93,6 +93,35 @@ zImage or old bzImage kernels, which need data written into the ...@@ -93,6 +93,35 @@ zImage or old bzImage kernels, which need data written into the
0x90000 segment, the boot loader should make sure not to use memory 0x90000 segment, the boot loader should make sure not to use memory
above the 0x9A000 point; too many BIOSes will break above that point. above the 0x9A000 point; too many BIOSes will break above that point.
For a modern bzImage kernel with boot protocol version >= 2.02, a
memory layout like the following is suggested:
~ ~
| Protected-mode kernel |
100000 +------------------------+
| I/O memory hole |
0A0000 +------------------------+
| Reserved for BIOS | Leave as much as possible unused
~ ~
| Command line | (Can also be below the X+10000 mark)
X+10000 +------------------------+
| Stack/heap | For use by the kernel real-mode code.
X+08000 +------------------------+
| Kernel setup | The kernel real-mode code.
| Kernel boot sector | The kernel legacy boot sector.
X +------------------------+
| Boot loader | <- Boot sector entry point 0000:7C00
001000 +------------------------+
| Reserved for MBR/BIOS |
000800 +------------------------+
| Typically used by MBR |
000600 +------------------------+
| BIOS use only |
000000 +------------------------+
... where the address X is as low as the design of the boot loader
permits.
**** THE REAL-MODE KERNEL HEADER **** THE REAL-MODE KERNEL HEADER
...@@ -160,24 +189,131 @@ e.g. protocol version 2.01 will contain 0x0201 in this field. When ...@@ -160,24 +189,131 @@ e.g. protocol version 2.01 will contain 0x0201 in this field. When
setting fields in the header, you must make sure only to set fields setting fields in the header, you must make sure only to set fields
supported by the protocol version in use. supported by the protocol version in use.
The "kernel_version" field, if set to a nonzero value, contains a
pointer to a null-terminated human-readable kernel version number **** DETAILS OF HEADER FIELDS
string, less 0x200. This can be used to display the kernel version to
the user. This value should be less than (0x200*setup_sects). For For each field, some are information from the kernel to the bootloader
example, if this value is set to 0x1c00, the kernel version number ("read"), some are expected to be filled out by the bootloader
string can be found at offset 0x1e00 in the kernel file. This is a ("write"), and some are expected to be read and modified by the
valid value if and only if the "setup_sects" field contains the value bootloader ("modify").
14 or higher.
All general purpose boot loaders should write the fields marked
Most boot loaders will simply load the kernel at its target address (obligatory). Boot loaders who want to load the kernel at a
directly. Such boot loaders do not need to worry about filling in nonstandard address should fill in the fields marked (reloc); other
most of the fields in the header. The following fields should be boot loaders can ignore those fields.
filled out, however:
Field name: setup_secs
vid_mode: Type: read
Offset/size: 0x1f1/1
Protocol: ALL
The size of the setup code in 512-byte sectors. If this field is
0, the real value is 4. The real-mode code consists of the boot
sector (always one 512-byte sector) plus the setup code.
Field name: root_flags
Type: modify (optional)
Offset/size: 0x1f2/2
Protocol: ALL
If this field is nonzero, the root defaults to readonly. The use of
this field is deprecated; use the "ro" or "rw" options on the
command line instead.
Field name: syssize
Type: read
Offset/size: 0x1f4/4 (protocol 2.04+) 0x1f4/2 (protocol ALL)
Protocol: 2.04+
The size of the protected-mode code in units of 16-byte paragraphs.
For protocol versions older than 2.04 this field is only two bytes
wide, and therefore cannot be trusted for the size of a kernel if
the LOAD_HIGH flag is set.
Field name: ram_size
Type: kernel internal
Offset/size: 0x1f8/2
Protocol: ALL
This field is obsolete.
Field name: vid_mode
Type: modify (obligatory)
Offset/size: 0x1fa/2
Please see the section on SPECIAL COMMAND LINE OPTIONS. Please see the section on SPECIAL COMMAND LINE OPTIONS.
type_of_loader: Field name: root_dev
Type: modify (optional)
Offset/size: 0x1fc/2
Protocol: ALL
The default root device device number. The use of this field is
deprecated, use the "root=" option on the command line instead.
Field name: boot_flag
Type: read
Offset/size: 0x1fe/2
Protocol: ALL
Contains 0xAA55. This is the closest thing old Linux kernels have
to a magic number.
Field name: jump
Type: read
Offset/size: 0x200/2
Protocol: 2.00+
Contains an x86 jump instruction, 0xEB followed by a signed offset
relative to byte 0x202. This can be used to determine the size of
the header.
Field name: header
Type: read
Offset/size: 0x202/4
Protocol: 2.00+
Contains the magic number "HdrS" (0x53726448).
Field name: version
Type: read
Offset/size: 0x206/2
Protocol: 2.00+
Contains the boot protocol version, e.g. 0x0204 for version 2.04.
Field name: readmode_swtch
Type: modify (optional)
Offset/size: 0x208/4
Protocol: 2.00+
Boot loader hook (see separate chapter.)
Field name: start_sys
Type: read
Offset/size: 0x20c/4
Protocol: 2.00+
The load low segment (0x1000). Obsolete.
Field name: kernel_version
Type: read
Offset/size: 0x20e/2
Protocol: 2.00+
If set to a nonzero value, contains a pointer to a NUL-terminated
human-readable kernel version number string, less 0x200. This can
be used to display the kernel version to the user. This value
should be less than (0x200*setup_sects). For example, if this value
is set to 0x1c00, the kernel version number string can be found at
offset 0x1e00 in the kernel file. This is a valid value if and only
if the "setup_sects" field contains the value 14 or higher.
Field name: type_of_loader
Type: write (obligatory)
Offset/size: 0x210/1
Protocol: 2.00+
If your boot loader has an assigned id (see table below), enter If your boot loader has an assigned id (see table below), enter
0xTV here, where T is an identifier for the boot loader and V is 0xTV here, where T is an identifier for the boot loader and V is
a version number. Otherwise, enter 0xFF here. a version number. Otherwise, enter 0xFF here.
...@@ -193,60 +329,145 @@ filled out, however: ...@@ -193,60 +329,145 @@ filled out, however:
8 U-BOOT 8 U-BOOT
9 Xen 9 Xen
A Gujin A Gujin
B Qemu
Please contact <hpa@zytor.com> if you need a bootloader ID Please contact <hpa@zytor.com> if you need a bootloader ID
value assigned. value assigned.
loadflags, heap_end_ptr: Field name: loadflags
If the protocol version is 2.01 or higher, enter the Type: modify (obligatory)
offset limit of the setup heap into heap_end_ptr and set the Offset/size: 0x211/1
0x80 bit (CAN_USE_HEAP) of loadflags. heap_end_ptr appears to Protocol: 2.00+
be relative to the start of setup (offset 0x0200).
This field is a bitmask.
setup_move_size:
When using protocol 2.00 or 2.01, if the real mode Bit 0 (read): LOADED_HIGH
kernel is not loaded at 0x90000, it gets moved there later in - If 0, the protected-mode code is loaded at 0x10000.
the loading sequence. Fill in this field if you want - If 1, the protected-mode code is loaded at 0x100000.
additional data (such as the kernel command line) moved in
addition to the real-mode kernel itself. Bit 7 (write): CAN_USE_HEAP
Set this bit to 1 to indicate that the value entered in the
The unit is bytes starting with the beginning of the boot heap_end_ptr is valid. If this field is clear, some setup code
sector. functionality will be disabled.
ramdisk_image, ramdisk_size: Field name: setup_move_size
If your boot loader has loaded an initial ramdisk (initrd), Type: modify (obligatory)
set ramdisk_image to the 32-bit pointer to the ramdisk data Offset/size: 0x212/2
and the ramdisk_size to the size of the ramdisk data. Protocol: 2.00-2.01
The initrd should typically be located as high in memory as When using protocol 2.00 or 2.01, if the real mode kernel is not
possible, as it may otherwise get overwritten by the early loaded at 0x90000, it gets moved there later in the loading
kernel initialization sequence. However, it must never be sequence. Fill in this field if you want additional data (such as
located above the address specified in the initrd_addr_max the kernel command line) moved in addition to the real-mode kernel
field. The initrd should be at least 4K page aligned. itself.
cmd_line_ptr: The unit is bytes starting with the beginning of the boot sector.
If the protocol version is 2.02 or higher, this is a 32-bit
pointer to the kernel command line. The kernel command line This field is can be ignored when the protocol is 2.02 or higher, or
can be located anywhere between the end of setup and 0xA0000. if the real-mode code is loaded at 0x90000.
Field name: code32_start
Type: modify (optional, reloc)
Offset/size: 0x214/4
Protocol: 2.00+
The address to jump to in protected mode. This defaults to the load
address of the kernel, and can be used by the boot loader to
determine the proper load address.
This field can be modified for two purposes:
1. as a boot loader hook (see separate chapter.)
2. if a bootloader which does not install a hook loads a
relocatable kernel at a nonstandard address it will have to modify
this field to point to the load address.
Field name: ramdisk_image
Type: write (obligatory)
Offset/size: 0x218/4
Protocol: 2.00+
The 32-bit linear address of the initial ramdisk or ramfs. Leave at
zero if there is no initial ramdisk/ramfs.
Field name: ramdisk_size
Type: write (obligatory)
Offset/size: 0x21c/4
Protocol: 2.00+
Size of the initial ramdisk or ramfs. Leave at zero if there is no
initial ramdisk/ramfs.
Field name: bootsect_kludge
Type: kernel internal
Offset/size: 0x220/4
Protocol: 2.00+
This field is obsolete.
Field name: heap_end_ptr
Type: write (obligatory)
Offset/size: 0x224/2
Protocol: 2.01+
Set this field to the offset (from the beginning of the real-mode
code) of the end of the setup stack/heap, minus 0x0200.
Field name: cmd_line_ptr
Type: write (obligatory)
Offset/size: 0x228/4
Protocol: 2.02+
Set this field to the linear address of the kernel command line.
The kernel command line can be located anywhere between the end of
the setup heap and 0xA0000; it does not have to be located in the
same 64K segment as the real-mode code itself.
Fill in this field even if your boot loader does not support a Fill in this field even if your boot loader does not support a
command line, in which case you can point this to an empty command line, in which case you can point this to an empty string
string (or better yet, to the string "auto".) If this field (or better yet, to the string "auto".) If this field is left at
is left at zero, the kernel will assume that your boot loader zero, the kernel will assume that your boot loader does not support
does not support the 2.02+ protocol. the 2.02+ protocol.
ramdisk_max: Field name: initrd_addr_max
The maximum address that may be occupied by the initrd Type: read
contents. For boot protocols 2.02 or earlier, this field is Offset/size: 0x22c/4
not present, and the maximum address is 0x37FFFFFF. (This Protocol: 2.03+
address is defined as the address of the highest safe byte, so
if your ramdisk is exactly 131072 bytes long and this field is The maximum address that may be occupied by the initial
ramdisk/ramfs contents. For boot protocols 2.02 or earlier, this
field is not present, and the maximum address is 0x37FFFFFF. (This
address is defined as the address of the highest safe byte, so if
your ramdisk is exactly 131072 bytes long and this field is
0x37FFFFFF, you can start your ramdisk at 0x37FE0000.) 0x37FFFFFF, you can start your ramdisk at 0x37FE0000.)
cmdline_size: Field name: kernel_alignment
Type: read (reloc)
Offset/size: 0x230/4
Protocol: 2.05+
Alignment unit required by the kernel (if relocatable_kernel is true.)
Field name: relocatable_kernel
Type: read (reloc)
Offset/size: 0x234/1
Protocol: 2.05+
If this field is nonzero, the protected-mode part of the kernel can
be loaded at any address that satisfies the kernel_alignment field.
After loading, the boot loader must set the code32_start field to
point to the loaded code, or to a boot loader hook.
Field name: cmdline_size
Type: read
Offset/size: 0x238/4
Protocol: 2.06+
The maximum size of the command line without the terminating The maximum size of the command line without the terminating
zero. This means that the command line can contain at most zero. This means that the command line can contain at most
cmdline_size characters. With protocol version 2.05 and cmdline_size characters. With protocol version 2.05 and earlier, the
earlier, the maximum size was 255. maximum size was 255.
**** THE KERNEL COMMAND LINE **** THE KERNEL COMMAND LINE
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment