x64 Bootloader with C-Kernel

2026-08-19

Stack Overflow: View Question

Tags: assembly, operating-system, x86-64, bootloader

Score: 1 | Views: 101

The asker is writing a school-project x64 bootloader in NASM that transitions CPU from Real Mode → Protected Mode → Long Mode, sets up 4-level paging (PML4/PDPT/PD), loads a C kernel at 0x100000, and jumps to it. The kernel never runs — control transfer fails silently.

This is one of the most unforgiving problems in systems programming because everything must be correct simultaneously before you get any feedback. There's no debugger, no printf, no exception trace — just a hung machine or a triple-fault reboot loop.

Why it's hard

Direction toward a solution

  1. Run under QEMU with -d int,cpu_reset -no-reboot -no-shutdown. This dumps the register state at the moment of triple fault — often revealing exactly which instruction faulted and in which mode.
  2. Attach GDB: qemu-system-x86_64 -s -S then target remote :1234, set architecture i386:x86-64. Step through the mode transition and inspect CR0/CR3/CR4/EFER after each write.
  3. Verify kernel bytes actually landed at 0x100000 before the far jump (x/16bx 0x100000 in GDB).
  4. Confirm the GDT has a valid 64-bit code segment (L-bit set, D-bit clear) and the far jump uses that selector.

Gotcha: A 512-byte MBR bootloader cannot fit the disk-read code, GDT, paging tables, and mode-switch logic. Most working designs use a stage 2 loader that the stage-1 MBR reads off disk first.

The challenge: A working long-mode transition requires ~a dozen CPU state changes in exact order with zero diagnostic feedback until QEMU/GDB is wired up as a virtual logic analyzer.

All newsletters