## 3 The exact definitions of Multiboot Specification ¶

There are three main aspects of a boot loader/OS image interface:

1. The format of an OS image as seen by a boot loader.
2. The state of a machine when a boot loader starts an operating system.
3. The format of information passed by a boot loader to an operating system.

### 3.1 OS image format ¶

An OS image may be an ordinary 32-bit executable file in the standard format for that particular operating system, except that it may be linked at a non-default load address to avoid loading on top of the PC’s I/O region or other reserved areas, and of course it should not use shared libraries or other fancy features.

An OS image must contain an additional header called Multiboot header, besides the headers of the format used by the OS image. The Multiboot header must be contained completely within the first 8192 bytes of the OS image, and must be longword (32-bit) aligned. In general, it should come as early as possible, and may be embedded in the beginning of the text segment after the real executable header.

#### 3.1.1 The layout of Multiboot header ¶

The layout of the Multiboot header must be as follows:

Offset | Type | Field Name | Note
0 | u32 | magic | required
4 | u32 | flags | required
8 | u32 | checksum | required
12 | u32 | header_addr | if flags[16] is set
16 | u32 | load_addr | if flags[16] is set
20 | u32 | load_end_addr | if flags[16] is set
24 | u32 | bss_end_addr | if flags[16] is set
28 | u32 | entry_addr | if flags[16] is set
32 | u32 | mode_type | if flags[2] is set
36 | u32 | width | if flags[2] is set
40 | u32 | height | if flags[2] is set
44 | u32 | depth | if flags[2] is set

The fields ‘`magic`’, ‘`flags`’ and ‘`checksum`’ are defined in The magic fields of Multiboot header, the fields ‘`header_addr`’, ‘`load_addr`’, ‘`load_end_addr`’, ‘`bss_end_addr`’ and ‘`entry_addr`’ are defined in The address fields of Multiboot header, and the fields ‘`mode_type`’, ‘`width`’, ‘`height`’ and ‘`depth`’ are defined in The graphics fields of Multiboot header.

#### 3.1.2 The magic fields of Multiboot header ¶

‘`magic`’

  The field ‘`magic`’ is the magic number identifying the header, which must be the hexadecimal value `0x1BADB002`.

‘`flags`’

  The field ‘`flags`’ specifies features that the OS image requests or requires of an boot loader. Bits 0-15 indicate requirements; if the boot loader sees any of these bits set but doesn’t understand the flag or can’t fulfill the requirements it indicates for some reason, it must notify the user and fail to load the OS image. Bits 16-31 indicate optional features; if any bits in this range are set but the boot loader doesn’t understand them, it may simply ignore them and proceed as usual. Naturally, all as-yet-undefined bits in the ‘`flags`’ word must be set to zero in OS images. This way, the ‘`flags`’ fields serves for version control as well as simple feature selection.

  If bit 0 in the ‘`flags`’ word is set, then all boot modules loaded along with the operating system must be aligned on page (4KB) boundaries. Some operating systems expect to be able to map the pages containing boot modules directly into a paged address space during startup, and thus need the boot modules to be page-aligned.

  If bit 1 in the ‘`flags`’ word is set, then information on available memory via at least the ‘`mem_*`’ fields of the Multiboot information structure (see Boot information format) must be included. If the boot loader is capable of passing a memory map (the ‘`mmap_*`’ fields) and one exists, then it may be included as well.

  If bit 2 in the ‘`flags`’ word is set, information about the video mode table (see Boot information format) must be available to the kernel.

  If bit 16 in the ‘`flags`’ word is set, then the fields at offsets 12-28 in the Multiboot header are valid, and the boot loader should use them instead of the fields in the actual executable header to calculate where to load the OS image. This information does not need to be provided if the kernel image is in ELF format, but it must be provided if the images is in a.out format or in some other format. Compliant boot loaders must be able to load images that either are in ELF format or contain the load address information embedded in the Multiboot header; they may also directly support other executable formats, such as particular a.out variants, but are not required to.

‘`checksum`’

  The field ‘`checksum`’ is a 32-bit unsigned value which, when added to the other magic fields (i.e. ‘`magic`’ and ‘`flags`’), must have a 32-bit unsigned sum of zero.

#### 3.1.3 The address fields of Multiboot header ¶

All of the address fields enabled by flag bit 16 are physical addresses. The meaning of each is as follows:

`header_addr`

  Contains the address corresponding to the beginning of the Multiboot header — the physical memory location at which the magic value is supposed to be loaded. This field serves to synchronize the mapping between OS image offsets and physical memory addresses.

`load_addr`

  Contains the physical address of the beginning of the text segment. The offset in the OS image file at which to start loading is defined by the offset at which the header was found, minus (header_addr - load_addr). load_addr must be less than or equal to header_addr.

`load_end_addr`

  Contains the physical address of the end of the data segment. (load_end_addr - load_addr) specifies how much data to load. This implies that the text and data segments must be consecutive in the OS image; this is true for existing a.out executable formats. If this field is zero, the boot loader assumes that the text and data segments occupy the whole OS image file.

`bss_end_addr`

  Contains the physical address of the end of the bss segment. The boot loader initializes this area to zero, and reserves the memory it occupies to avoid placing boot modules and other data relevant to the operating system in that area. If this field is zero, the boot loader assumes that no bss segment is present.

`entry_addr`

  The physical address to which the boot loader should jump in order to start running the operating system.

#### 3.1.4 The graphics fields of Multiboot header ¶

All of the graphics fields are enabled by flag bit 2. They specify the preferred graphics mode. Note that that is only a recommended mode by the OS image. Boot loader may choose a different mode if it sees fit.

The meaning of each is as follows:

`mode_type`

  Contains ‘`0`’ for linear graphics mode or ‘`1`’ for EGA-standard text mode. Everything else is reserved for future expansion. Note that the boot loader may set a text mode even if this field contains ‘`0`’, or set a video mode even if this field contains ‘`1`’.

`width`

  Contains the number of the columns. This is specified in pixels in a graphics mode, and in characters in a text mode. The value zero indicates that the OS image has no preference.

`height`

  Contains the number of the lines. This is specified in pixels in a graphics mode, and in characters in a text mode. The value zero indicates that the OS image has no preference.

`depth`

  Contains the number of bits per pixel in a graphics mode, and zero in a text mode. The value zero indicates that the OS image has no preference.

### 3.2 Machine state ¶

When the boot loader invokes the 32-bit operating system, the machine must have the following state:

‘`EAX`’

  Must contain the magic value ‘`0x2BADB002`’; the presence of this value indicates to the operating system that it was loaded by a Multiboot-compliant boot loader (e.g. as opposed to another type of boot loader that the operating system can also be loaded from).

‘`EBX`’

  Must contain the 32-bit physical address of the Multiboot information structure provided by the boot loader (see Boot information format).

‘`CS`’

  Must be a 32-bit read/execute code segment with an offset of ‘`0`’ and a limit of ‘`0xFFFFFFFF`’. The exact value is undefined.

‘`DS`’
‘`ES`’
‘`FS`’
‘`GS`’
‘`SS`’

  Must be a 32-bit read/write data segment with an offset of ‘`0`’ and a limit of ‘`0xFFFFFFFF`’. The exact values are all undefined.

‘`A20 gate`’

  Must be enabled.

‘`CR0`’

  Bit 31 (PG) must be cleared. Bit 0 (PE) must be set. Other bits are all undefined.

‘`EFLAGS`’

  Bit 17 (VM) must be cleared. Bit 9 (IF) must be cleared. Other bits are all undefined.

All other processor registers and flag bits are undefined. This includes, in particular:

‘`ESP`’

  The OS image must create its own stack as soon as it needs one.

‘`GDTR`’

  Even though the segment registers are set up as described above, the ‘`GDTR`’ may be invalid, so the OS image must not load any segment registers (even just reloading the same values!) until it sets up its own ‘`GDT`’.

‘`IDTR`’

  The OS image must leave interrupts disabled until it sets up its own `IDT`.

However, other machine state should be left by the boot loader in normal working order, i.e. as initialized by the BIOS (or DOS, if that’s what the boot loader runs from). In other words, the operating system should be able to make BIOS calls and such after being loaded, as long as it does not overwrite the BIOS data structures before doing so. Also, the boot loader must leave the PIC programmed with the normal BIOS/DOS values, even if it changed them during the switch to 32-bit mode.

### 3.3 Boot information format ¶

FIXME: Split this chapter like the chapter “OS image format”.

Upon entry to the operating system, the `EBX` register contains the physical address of a Multiboot information data structure, through which the boot loader communicates vital information to the operating system. The operating system can use or ignore any parts of the structure as it chooses; all information passed by the boot loader is advisory only.

The Multiboot information structure and its related substructures may be placed anywhere in memory by the boot loader (with the exception of the memory reserved for the kernel and boot modules, of course). It is the operating system’s responsibility to avoid overwriting this memory until it is done using it.

The format of the Multiboot information structure (as defined so far) follows:

            +-------------------+
    0       | flags             |    (required)
            +-------------------+
    4       | mem_lower         |    (present if flags[0] is set)
    8       | mem_upper         |    (present if flags[0] is set)
            +-------------------+
    12      | boot_device       |    (present if flags[1] is set)
            +-------------------+
    16      | cmdline           |    (present if flags[2] is set)
            +-------------------+
    20      | mods_count        |    (present if flags[3] is set)
    24      | mods_addr         |    (present if flags[3] is set)
            +-------------------+
    28 - 40 | syms              |    (present if flags[4] or
            |                   |                flags[5] is set)
            +-------------------+
    44      | mmap_length       |    (present if flags[6] is set)
    48      | mmap_addr         |    (present if flags[6] is set)
            +-------------------+
    52      | drives_length     |    (present if flags[7] is set)
    56      | drives_addr       |    (present if flags[7] is set)
            +-------------------+
    60      | config_table      |    (present if flags[8] is set)
            +-------------------+
    64      | boot_loader_name  |    (present if flags[9] is set)
            +-------------------+
    68      | apm_table         |    (present if flags[10] is set)
            +-------------------+
    72      | vbe_control_info  |    (present if flags[11] is set)
    76      | vbe_mode_info     |
    80      | vbe_mode          |
    82      | vbe_interface_seg |
    84      | vbe_interface_off |
    86      | vbe_interface_len |
            +-------------------+
    88      | framebuffer_addr  |    (present if flags[12] is set)
    96      | framebuffer_pitch |
    100     | framebuffer_width |
    104     | framebuffer_height|
    108     | framebuffer_bpp   |
    109     | framebuffer_type  |
    110-115 | color_info        |
            +-------------------+

The first longword indicates the presence and validity of other fields in the Multiboot information structure. All as-yet-undefined bits must be set to zero by the boot loader. Any set bits that the operating system does not understand should be ignored. Thus, the ‘`flags`’ field also functions as a version indicator, allowing the Multiboot information structure to be expanded in the future without breaking anything.

If bit 0 in the ‘`flags`’ word is set, then the ‘`mem_*`’ fields are valid. ‘`mem_lower`’ and ‘`mem_upper`’ indicate the amount of lower and upper memory, respectively, in kilobytes. Lower memory starts at address 0, and upper memory starts at address 1 megabyte. The maximum possible value for lower memory is 640 kilobytes. The value returned for upper memory is maximally the address of the first upper memory hole minus 1 megabyte. It is not guaranteed to be this value.

If bit 1 in the ‘`flags`’ word is set, then the ‘`boot_device`’ field is valid, and indicates which BIOS disk device the boot loader loaded the OS image from. If the OS image was not loaded from a BIOS disk, then this field must not be present (bit 3 must be clear). The operating system may use this field as a hint for determining its own root device, but is not required to. The ‘`boot_device`’ field is laid out in four one-byte subfields as follows:

    +-------+-------+-------+-------+
    | part3 | part2 | part1 | drive |
    +-------+-------+-------+-------+
    Least significant             Most significant

The most significant byte contains the BIOS drive number as understood by the BIOS INT 0x13 low-level disk interface: e.g. 0x00 for the first floppy disk or 0x80 for the first hard disk.

The three remaining bytes specify the boot partition. ‘`part1`’ specifies the top-level partition number, ‘`part2`’ specifies a sub-partition in the top-level partition, etc. Partition numbers always start from zero. Unused partition bytes must be set to 0xFF. For example, if the disk is partitioned using a simple one-level DOS partitioning scheme, then ‘`part1`’ contains the DOS partition number, and ‘`part2`’ and ‘`part3`’ are both 0xFF. As another example, if a disk is partitioned first into DOS partitions, and then one of those DOS partitions is subdivided into several BSD partitions using BSD’s disklabel strategy, then ‘`part1`’ contains the DOS partition number, ‘`part2`’ contains the BSD sub-partition within that DOS partition, and ‘`part3`’ is 0xFF.

DOS extended partitions are indicated as partition numbers starting from 4 and increasing, rather than as nested sub-partitions, even though the underlying disk layout of extended partitions is hierarchical in nature. For example, if the boot loader boots from the second extended partition on a disk partitioned in conventional DOS style, then ‘`part1`’ will be 5, and ‘`part2`’ and ‘`part3`’ will both be 0xFF.

If bit 2 of the ‘`flags`’ longword is set, the ‘`cmdline`’ field is valid, and contains the physical address of the command line to be passed to the kernel. The command line is a normal C-style zero-terminated string. The exact format of command line is left to OS developpers. General-purpose boot loaders should allow user a complete control on command line independently of other factors like image name. Boot loaders with specific payload in mind may completely or partially generate it algorithmically.

If bit 3 of the ‘`flags`’ is set, then the ‘`mods`’ fields indicate to the kernel what boot modules were loaded along with the kernel image, and where they can be found. ‘`mods_count`’ contains the number of modules loaded; ‘`mods_addr`’ contains the physical address of the first module structure. ‘`mods_count`’ may be zero, indicating no boot modules were loaded, even if bit 3 of ‘`flags`’ is set. Each module structure is formatted as follows:

            +-------------------+
    0       | mod_start         |
    4       | mod_end           |
            +-------------------+
    8       | string            |
            +-------------------+
    12      | reserved (0)      |
            +-------------------+

The first two fields contain the start and end addresses of the boot module itself. The ‘`string`’ field provides an arbitrary string to be associated with that particular boot module; it is a zero-terminated ASCII string, just like the kernel command line. The ‘`string`’ field may be 0 if there is no string associated with the module. Typically the string might be a command line (e.g. if the operating system treats boot modules as executable programs), or a pathname (e.g. if the operating system treats boot modules as files in a file system), but its exact use is specific to the operating system. The ‘`reserved`’ field must be set to 0 by the boot loader and ignored by the operating system.

Caution: Bits 4 & 5 are mutually exclusive.

If bit 4 in the ‘`flags`’ word is set, then the following fields in the Multiboot information structure starting at byte 28 are valid:

            +-------------------+
    28      | tabsize           |
    32      | strsize           |
    36      | addr              |
    40      | reserved (0)      |
            +-------------------+

These indicate where the symbol table from an a.out kernel image can be found. ‘`addr`’ is the physical address of the size (4-byte unsigned long) of an array of a.out format nlist structures, followed immediately by the array itself, then the size (4-byte unsigned long) of a set of zero-terminated ASCII strings (plus sizeof(unsigned long) in this case), and finally the set of strings itself. ‘`tabsize`’ is equal to its size parameter (found at the beginning of the symbol section), and ‘`strsize`’ is equal to its size parameter (found at the beginning of the string section) of the following string table to which the symbol table refers. Note that ‘`tabsize`’ may be 0, indicating no symbols, even if bit 4 in the ‘`flags`’ word is set.

If bit 5 in the ‘`flags`’ word is set, then the following fields in the Multiboot information structure starting at byte 28 are valid:

            +-------------------+
    28      | num               |
    32      | size              |
    36      | addr              |
    40      | shndx             |
            +-------------------+

These indicate where the section header table from an ELF kernel is, the size of each entry, number of entries, and the string table used as the index of names. They correspond to the ‘`shdr_*`’ entries (‘`shdr_num`’, etc.) in the Executable and Linkable Format (ELF) specification in the program header. All sections are loaded, and the physical address fields of the ELF section header then refer to where the sections are in memory (refer to the i386 ELF documentation for details as to how to read the section header(s)). Note that ‘`shdr_num`’ may be 0, indicating no symbols, even if bit 5 in the ‘`flags`’ word is set.

If bit 6 in the ‘`flags`’ word is set, then the ‘`mmap_*`’ fields are valid, and indicate the address and length of a buffer containing a memory map of the machine provided by the BIOS. ‘`mmap_addr`’ is the address, and ‘`mmap_length`’ is the total size of the buffer. The buffer consists of one or more of the following size/structure pairs (‘`size`’ is really used for skipping to the next pair):

            +-------------------+
    -4      | size              |
            +-------------------+
    0       | base_addr         |
    8       | length            |
    16      | type              |
            +-------------------+

where ‘`size`’ is the size of the associated structure in bytes, which can be greater than the minimum of 20 bytes. ‘`base_addr`’ is the starting address. ‘`length`’ is the size of the memory region in bytes. ‘`type`’ is the variety of address range represented, where a value of 1 indicates available RAM, value of 3 indicates usable memory holding ACPI information, value of 4 indicates reserved memory which needs to be preserved on hibernation, value of 5 indicates a memory which is occupied by defective RAM modules and all other values currently indicated a reserved area.

The map provided is guaranteed to list all standard RAM that should be available for normal use.

If bit 7 in the ‘`flags`’ is set, then the ‘`drives_*`’ fields are valid, and indicate the address of the physical address of the first drive structure and the size of drive structures. ‘`drives_addr`’ is the address, and ‘`drives_length`’ is the total size of drive structures. Note that ‘`drives_length`’ may be zero. Each drive structure is formatted as follows:

            +-------------------+
    0       | size              |
            +-------------------+
    4       | drive_number      |
            +-------------------+
    5       | drive_mode        |
            +-------------------+
    6       | drive_cylinders   |
    8       | drive_heads       |
    9       | drive_sectors     |
            +-------------------+
    10 - xx | drive_ports       |
            +-------------------+

The ‘`size`’ field specifies the size of this structure. The size varies, depending on the number of ports. Note that the size may not be equal to (10 + 2 * the number of ports), because of an alignment.

The ‘`drive_number`’ field contains the BIOS drive number. The ‘`drive_mode`’ field represents the access mode used by the boot loader. Currently, the following modes are defined:

‘`0`’

  CHS mode (traditional cylinder/head/sector addressing mode).

‘`1`’

  LBA mode (Logical Block Addressing mode).

The three fields, ‘`drive_cylinders`’, ‘`drive_heads`’ and ‘`drive_sectors`’, indicate the geometry of the drive detected by the BIOS. ‘`drive_cylinders`’ contains the number of the cylinders. ‘`drive_heads`’ contains the number of the heads. ‘`drive_sectors`’ contains the number of the sectors per track.

The ‘`drive_ports`’ field contains the array of the I/O ports used for the drive in the BIOS code. The array consists of zero or more unsigned two-bytes integers, and is terminated with zero. Note that the array may contain any number of I/O ports that are not related to the drive actually (such as DMA controller’s ports).

If bit 8 in the ‘`flags`’ is set, then the ‘`config_table`’ field is valid, and indicates the address of the ROM configuration table returned by the GET CONFIGURATION BIOS call. If the BIOS call fails, then the size of the table must be zero.

If bit 9 in the ‘`flags`’ is set, the ‘`boot_loader_name`’ field is valid, and contains the physical address of the name of a boot loader booting the kernel. The name is a normal C-style zero-terminated string.

If bit 10 in the ‘`flags`’ is set, the ‘`apm_table`’ field is valid, and contains the physical address of an APM table defined as below:

            +----------------------+
    0       | version              |
    2       | cseg                 |
    4       | offset               |
    8       | cseg_16              |
    10      | dseg                 |
    12      | flags                |
    14      | cseg_len             |
    16      | cseg_16_len          |
    18      | dseg_len             |
            +----------------------+

The fields ‘`version`’, ‘`cseg`’, ‘`offset`’, ‘`cseg_16`’, ‘`dseg`’, ‘`flags`’, ‘`cseg_len`’, ‘`cseg_16_len`’, ‘`dseg_len`’ indicate the version number, the protected mode 32-bit code segment, the offset of the entry point, the protected mode 16-bit code segment, the protected mode 16-bit data segment, the flags, the length of the protected mode 32-bit code segment, the length of the protected mode 16-bit code segment, and the length of the protected mode 16-bit data segment, respectively. Only the field ‘`offset`’ is 4 bytes, and the others are 2 bytes. See Advanced Power Management (APM) BIOS Interface Specification, for more information.

If bit 11 in the ‘`flags`’ is set, the VBE table is available.

The fields ‘`vbe_control_info`’ and ‘`vbe_mode_info`’ contain the physical addresses of VBE control information returned by the VBE Function 00h and VBE mode information returned by the VBE Function 01h, respectively.

The field ‘`vbe_mode`’ indicates current video mode in the format specified in VBE 3.0.

The rest fields ‘`vbe_interface_seg`’, ‘`vbe_interface_off`’, and ‘`vbe_interface_len`’ contain the table of a protected mode interface defined in VBE 2.0+. If this information is not available, those fields contain zero. Note that VBE 3.0 defines another protected mode interface which is incompatible with the old one. If you want to use the new protected mode interface, you will have to find the table yourself.

The fields for the graphics table are designed for VBE, but Multiboot boot loaders may simulate VBE on non-VBE modes, as if they were VBE modes.

If bit 12 in the ‘`flags`’ is set, the FRAMEBUFFER table is available.

The field ‘`framebuffer_addr`’ contains framebuffer physical address. This field is 64-bit wide but bootloader should set it under 4 GiB if possible for compatibility with kernels which aren’t aware of PAE or AMD64. The field ‘`framebuffer_pitch`’ contains the framebuffer pitch in bytes. The fields ‘`framebuffer_width`’, ‘`framebuffer_height`’ contain the framebuffer dimensions in pixels. The field ‘`framebuffer_bpp`’ contains the number of bits per pixel. If ‘`framebuffer_type`’ is set to ‘`0`’ it means indexed color will be used. In this case color_info is defined as follows:

            +----------------------------------+
    110     | framebuffer_palette_addr         |
    114     | framebuffer_palette_num_colors   |
            +----------------------------------+

‘`framebuffer_palette_addr`’ contains the address of the color palette, which is an array of color descriptors. Each color descriptor has the following structure:

            +-------------+
    0       | red_value   |
    1       | green_value |
    2       | blue_value  |
            +-------------+

If ‘`framebuffer_type`’ is set to ‘`1`’ it means direct RGB color will be used. Then color_type is defined as follows:

            +----------------------------------+
    110     | framebuffer_red_field_position   |
    111     | framebuffer_red_mask_size        |
    112     | framebuffer_green_field_position |
    113     | framebuffer_green_mask_size      |
    114     | framebuffer_blue_field_position  |
    115     | framebuffer_blue_mask_size       |
            +----------------------------------+

If ‘`framebuffer_type`’ is set to ‘`2`’ it means EGA-standard text mode will be used. In this case ‘`framebuffer_width`’ and ‘`framebuffer_height`’ are expressed in characters instead of pixels. ‘`framebuffer_bpp`’ is equal to 16 (bits per character) and ‘`framebuffer_pitch`’ is expressed in bytes per text line. All further values of ‘`framebuffer_type`’ are reserved for future expansion.