Multiboot
The Multiboot specification is an open standard that provides kernels with a uniform way to be booted by Multiboot-compliant bootloaders. The reference implementation of the Multiboot specification is provided by GRUB.
Multiboot 1
The original Multiboot specification was created by Bryan Ford and Erich Stefan Boleyn in 1995. It has evolved and been updated by the Free Software Foundation ever since.
Multiboot 1 compliant kernels used the magic number 0x1BADB002, and Multiboot-compliant bootloaders report themselves with magic number 0x2BADB002.
You can check whether a program has a valid Multiboot 1 header by running grub-file which is quiet but will exit 0 if it finds a header, and 1 otherwise.
grub-file --is-x86-multiboot myos.bin
You can boot a multiboot v1 kernel with the following command in your menuentry:
multiboot /boot/kernel-file
Multiboot 2
The newer Multiboot specification was created to solve some of the problems that the original specification had. It is not backwards compatible, uses different structures and different magic numbers.
Multiboot 2 compliant kernels used the magic number 0xE85250D6, and Multiboot-compliant bootloaders report themselves with magic number 0x36D76289. On x86, this magic number is stored in EAX just before the kernel is invoked.
You can check whether a program has a valid Multiboot 2 header by running grub-file which is quiet but will exit 0 if it finds a header, and 1 otherwise.
grub-file --is-x86-multiboot2 myos.bin
Note: GNU LD has default page size of 0x00200000 for elf64, which will fail multiboot2 test. You can use "-z max-page-size=SIZE" to get around this.
GNU GRUB is compatible with the Multiboot2 specification as of version 2.02.
You can boot a multiboot v2 kernel with the following command in your menuentry:
multiboot2 /boot/kernel-file
Header Format
The first part of the Multiboot2 header is a struct aligned on an 8-byte boundary containing four "magic" 32-bit integers. These fields contain the magic number 0xE85250D6, flags describing the architecture, the total length of the header including the subsequent tags, and the checksum of the magic fields respectively.
The magic fields in the header are followed by a list of 8-byte aligned structures referred to in the specification as tags. The tags are used as hints by the bootloader to provide information about the kernel image and to request that it provide additional information in the boot information struct.
The available tags and their structure vary by platform and are documented in the Multiboot2 specification. See #External Links below for the latest draft. This list of tags must end with a tag of type 0 and size 8.
Information Structure
A Multiboot2-compliant bootloader provides an information structure when the kernel boots. On x86, a physical pointer is stored in EBX, while the magic number is stored in EAX. It's a well-known practice to check the magic number to verify the bootloader passed the correct information. This physical pointer information structure is 8-byte aligned, and contains tags. These tags may contain useful information about the system, for example: the memory map, ELF sections of the image and information about the framebuffer.
struct multiboot_tag {
uint32_t type;
uint32_t size;
};
struct multiboot_info {
uint32_t total_size;
uint32_t reserved;
struct multiboot_tag tags[0];
};
Multiboot 2 modules
(Note that this section may or may not be 100% accurate, has yet to be tested.)
The Multiboot 2 specification supports boot modules, which are pieces of data loaded into memory when the bootloader boots your kernel. Normally these are just files residing on the boot media, which are loaded by your boot loader, but the exact implementation is up to your bootloader. For GRUB, these modules are loaded using the "module2" command before booting your kernel.
Once your kernel is booted, you can use the multiboot information structure to locate and identify these modules. Note that in the case of GRUB, the module's string will also include the text after the module name, for example, if you load a module using "module video 1024x768", the string field of that module's structure will contain "video 1024x768". In this way, you can specify 'arguments' to modules when you load them. (This seems to be the behavior intended by the multiboot spec.)
GRUB may support decompressing modules before loading them, this seems to be driven by the extension of the file.
Placing the Multiboot struct
As said before, the struct must be 8 byte aligned and placed in the first 8K of the executable. The simplest solution to assure this is to create a new section for the struct with an attribute:
struct multiboot_header {
...
} __attribute__((section(".multiboot")));
Then tell the linker in the linker script to start the file with this section with proper alignment:
... .text: { /* link the multiboot struct here */ . = ALIGN(8); KEEP(*(.multiboot)) /* place all of your code afterwards */ *(.text) } ...
The keyword ALIGN guarantees the alignment, and KEEP tells the linker to keep that section at the beginning of the text segment.