2.9 KiB
layout, title, related_posts
| layout | title | related_posts |
|---|---|---|
| post | [DRAFT] Rust OS Part 1: Booting | null |
Multiboot
Fortunately there is a bootloader standard: the Multiboot Specification. So our kernel just needs to indicate that it supports Multiboot and every Multiboot-compliant bootloader can boot it. We will use the GRUB 2 bootloader together with the Multiboot 2 specification (PDF).
To indicate our Multiboot 2 support to the bootloader, our kernel must contain a Multiboot Header, which has the following format:
| Field | Type | Value |
|---|---|---|
| magic number | u32 | 0xE85250D6 |
| architecture | u32 | 0 for i386, 4 for MIPS |
| header length | u32 | total header size, including tags |
| checksum | u32 | -(magic + architecture + header length) |
| tags | variable | |
| end tag | (u16, u16, u32) | (0, 0, 8) |
Converted to a x86 assembly file it looks like this (Intel syntax):
section .multiboot_header
header_start:
dd 0xe85250d6 ; magic number (multiboot 2)
dd 0 ; architecture 0 (protected mode i386)
dd header_end - header_start ; header length
; checksum
dd 0x100000000 - (0xe85250d6 + 0 + (header_end - header_start))
; insert optional multiboot tags here
; required end tag
dw 0 ; type
dw 0 ; flags
dd 8 ; size
header_end:
If you don't know x86 assembly, here is some quick guide:
- the header will be written to a section named
.multiboot_header(we need this later) header_startandheader_endare labels that mark a memory location. We use them to calculate the header length easilyddstands fordefine double(32bit) anddwstands fordefine word(16bit)- the additional
0x100000000in the checksum calculation is a small hack1 to avoid a compiler warning
We can already assemble this file (which I called multiboot_header.asm) using nasm. As it produces a flat binary by default, the resulting file just contains our 24 bytes (in little endian if you work on a x86 machine):
> nasm multiboot_header.asm
> hexdump -x multiboot_header
0000000 50d6 e852 0000 0000 0018 0000 af12 17ad
0000010 0000 0000 0008 0000
0000018
Booting
-
The formula from the table,
-(magic + architecture + header length), creates a negative value that doesn't fit into 32bit. By subtracting from0x100000000instead, we keep the value positive without changing its truncated value. Without the additional sign bit(s) the result fits into 32bit and the compiler is happy. ↩︎