GRUB loads the CrisOS v2 kernel ELF at physical addressDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/CRISTOP-bot/cris-os-v2/llms.txt
Use this file to discover all available pages before exploring further.
0x00100000 (the 1 MB mark), validates the embedded Multiboot header, and transfers control to the start symbol defined in boot/boot.S. From that moment the CPU is already in 32-bit protected mode, and the assembly entry point is responsible for establishing a clean execution environment before calling the C kernel entry point kmain.
GRUB Configuration
The ISO image ships with the following GRUB configuration. The singlemultiboot line loads the kernel binary and passes the rootfs image as a Multiboot module — both are picked up by GRUB before any kernel code runs.
Multiboot Header
The very first section of the kernel image is.multiboot, placed at address 0x00100000 by the linker script. It contains three 32-bit magic numbers that GRUB scans for to identify a compliant kernel:
magic + flags + checksum == 0 (mod 2^32). GRUB verifies this sum before handing off control. The flags value 0x00000003 is a bitmask: bit 0 requests that all boot modules are loaded on page-aligned boundaries, and bit 1 requests that the bootloader populate a memory map in the Multiboot information structure passed to the kernel.
The Multiboot flags value
0x00000003 is the bitwise OR of two requests: bit 0 (0x1) — page-align all loaded modules; bit 1 (0x2) — provide a BIOS memory map. Both bits are required by CrisOS v2 to locate and mount the rootfs module reliably.Boot Sequence
GRUB validates the Multiboot header
GRUB scans the first 8 KB of the kernel image for the magic value
0x1BADB002. Once found it verifies that magic + flags + checksum == 0. On success, GRUB loads all modules specified on the multiboot line, builds the multiboot_info structure in memory, and prepares to transfer control.CPU enters 32-bit protected mode
GRUB switches the CPU from real mode into 32-bit protected mode before jumping to the kernel entry point. Segment registers are left in their GRUB-initialized state; CrisOS v2 will re-initialize them with a proper GDT shortly after
kmain is entered.Assembly entry point `start` runs
Control arrives at the
start label in boot/boot.S. The assembly stub performs five critical actions in order:cli— disables hardware interrupts so no IRQ can fire before the IDT is installed.- Clear segment registers — zeroes
%ds,%es,%fs, and%gsto avoid stale GRUB values interfering with memory accesses. - Set up the stack — loads
$stack_topinto%espand 16-byte-aligns the stack pointer withand $-16, %esp. The stack is an 8 KB.bssregion (.lcomm stack, 8192);stack_topis the symbolstack + 8192. - Push the Multiboot info pointer —
push %ebxpasses the pointer to themultiboot_infostructure (placed there by GRUB in%ebx) as the first argument tokmain. - Call
kmain— transfers control to the C kernel entry point.
kmain receives the Multiboot info pointer
kmain(unsigned long mbi_addr) receives the physical address of the Multiboot information structure as its sole argument. It uses this to locate loaded modules (e.g. the rootfs image) by checking mbi->flags & 0x8 and iterating mbi->mods_addr. The full initialization sequence is described in the Kernel page.Linker Script and Memory Layout
The linker scriptlinker.ld produces a flat 32-bit ELF image loaded starting at 0x00100000:
| Section | Contents |
|---|---|
.multiboot | Multiboot header (three magic longwords) |
.text | All executable code |
.rodata | Read-only data (string literals, lookup tables) |
.data | Initialized global/static variables |
.bss | Zero-initialized data, stack (8192 bytes), bump heap |