Bootloader & Multiboot
Kernel Loading and Boot Process
Overview
The bootloader is the first code executed when the computer powers on. In AOS, we use the Multiboot 2 standard, which allows a compatible bootloader (like GRUB) to load our kernel without needing to write bootloader code from scratch.
What is Multiboot?
Multiboot is a specification that defines how a bootloader and kernel communicate. Instead of requiring kernel developers to write bootloaders, they can rely on bootloaders like GRUB that already support the standard.
Multiboot Versions
- Multiboot 1 - Legacy, 32-bit only
- Multiboot 2 - Modern, supports 32 and 64-bit
AOS supports Multiboot 2 for both BIOS and UEFI boot methods.
Multiboot Header
The Multiboot header tells the bootloader information about the kernel. It's placed in the first 32KB of the kernel file and contains specific magic numbers and configuration flags.
Multiboot 2 Header Structure
// Multiboot 2 header (architecture-independent)
struct mb2_header {
uint32_t magic; // MULTIBOOT2_MAGIC = 0xE85250D6
uint32_t architecture; // 0 = x86 (32-bit)
uint32_t length; // Header length in bytes
uint32_t checksum; // -(magic + architecture + length)
// Followed by tags...
struct {
uint16_t type; // Tag type
uint16_t flags; // Flags (optional, end tags, etc.)
uint32_t size; // Tag size in bytes
// Tag-specific data...
} tags[];
};
Kernel Entry Point
When the bootloader loads AOS, it:
- Loads kernel segments into memory
- Sets up 32-bit protected mode
-
Jumps to entry point with:
- EAX = Multiboot magic number (0x36D76289)
- EBX = Address of Multiboot info structure
Boot Process Timeline
Memory Information from Bootloader
The memory map tag provides crucial information about available RAM. AOS uses this to initialize the Physical Memory Manager (PMM):
struct multiboot_mmap_entry {
uint64_t addr; // Start address
uint64_t len; // Length in bytes
uint32_t type; // 1=RAM, 2=Reserved, 3=ACPIReclaimable
uint32_t zero; // Reserved (padding)
} __attribute__((packed));
Framebuffer Information
Modern systems use graphical framebuffers instead of VGA text mode. The bootloader provides framebuffer details:
struct multiboot_tag_framebuffer {
uint64_t common_addr; // Framebuffer physical address
uint32_t common_pitch; // Bytes per scanline
uint32_t common_width; // Width in pixels
uint32_t common_height; // Height in pixels
uint8_t common_bpp; // Bits per pixel
uint8_t common_type; // Type (0=indexed, 1=RGB)
// ... color field info
};
ISO Building and Boot
AOS uses GRUB's Multiboot 2 support for ISO generation:
GRUB Configuration
# iso/boot/grub/grub.cfg
menuentry 'AOS' {
multiboot2 /boot/kernel.elf
boot
}
menuentry 'AOS (UEFI)' {
multiboot2 /boot/kernel.elf
boot
}
ISO Creation
# Create ISO with GRUB bootloader
grub-mkrescue -o aos.iso iso/
⚠️ Important: Magic Number Validation
The kernel MUST verify the Multiboot magic number before using the information structure. This ensures the bootloader is Multiboot-compliant.
Kernel Transition: 32-bit to 64-bit
After bootloader loads kernel in 32-bit protected mode:
- Bootloader passes control to kernel_entry() (32-bit code)
- Kernel checks magic to ensure Multiboot compliant bootloader
- Kernel sets up paging for 64-bit addressing
- Kernel enables long mode via MSR registers
- Kernel enters 64-bit mode with ljmp instruction
- 64-bit code continues initialization
Key Takeaways
- ✓ Multiboot 2 standard simplifies bootloader integration
- ✓ GRUB provides bootloader functionality for free
- ✓ Bootloader loads kernel in 32-bit protected mode
- ✓ Multiboot info contains memory, framebuffer, and module data
- ✓ Kernel must validate magic before using Multiboot info
- ✓ Memory map from bootloader initializes PMM
- ✓ Framebuffer allows graphics output without BIOS calls