NKBootman is a custom two-stage x86 bootloader written entirely in 16-bit and 32-bit NASM assembly. Stage 1 occupies exactly 512 bytes — the Master Boot Record — and its sole job is to load Stage 2 from sectors 1–16 of the disk image into memory at 0x7E00 and jump to it. Stage 2 handles the heavier lifting: enabling the A20 address line, loading the flat kernel binary from disk, setting up a minimal GDT, switching the CPU into 32-bit protected mode, relocating the kernel to its permanent home at 0x100000, and jumping to it. As an alternative, GRUB’s Multiboot protocol can load the ELF kernel image directly — this is the recommended path for development and testing.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/pastaboy12345/NKLegacy/llms.txt
Use this file to discover all available pages before exploring further.
Stage 1 — MBR (boot/stage1/mbr.asm)
Stage 1 is assembled with nasm -f bin and written to sector 0 of the disk image. It is exactly 512 bytes, padded to byte 510 with zeros and terminated by the 0xAA55 boot signature that the BIOS checks before transferring control.
On entry the BIOS passes the boot drive number in DL; Stage 1 immediately saves it to the boot_drive variable so it can be forwarded to Stage 2. After setting up a minimal real-mode stack (growing downward from 0x7C00) and clearing the screen, Stage 1 uses INT 13h AH=02h to read 16 consecutive sectors from the disk starting at CHS sector 2 (the sector immediately after the MBR) into the buffer at 0x7E00:
DISK ERROR! and halts with cli / hlt. On success it passes the saved boot drive number in DL and executes a far jump to 0x0000:0x7E00 to hand control to Stage 2.
The 0xAA55 boot signature is placed by the times 510 - ($ - $$) db 0 / dw 0xAA55 idiom — a compile-time assertion that the entire Stage 1 body fits within 510 bytes.
Stage 2 — Protected-Mode Loader (boot/stage2/stage2.asm)
Stage 2 is assembled at origin 0x7E00 and may use up to the 16 sectors (8 KB) that Stage 1 loaded. It performs four major steps before reaching the kernel.
1. A20 enable. Stage 2 uses the “fast A20” method: it reads port 0x92, sets bit 1 (A20 enable) while masking bit 0 (to avoid a system reset), and writes the value back.
0x1000 (physical address 0x10000).
3. Protected-mode entry. Stage 2 defines its own minimal flat GDT (null, code, data descriptors) in-line, calls lgdt [gdt_descriptor], sets bit 0 of CR0 to enable protected mode, and performs a far jump to flush the prefetch queue and load the 32-bit code segment selector:
protected_mode_entry (32-bit code), Stage 2 sets all data segment registers to the flat data selector 0x10, establishes a temporary stack at 0x90000, and uses rep movsd to copy the kernel from its temporary buffer at 0x10000 to its permanent location at 0x100000:
GRUB / Multiboot (ntoskrnl/arch/i386/boot.asm)
The kernel ELF image embeds a Multiboot header in its .multiboot section. The linker script guarantees this section is placed at the very start of the image (before .text) so that it falls within the first 8 KB as the Multiboot specification requires.
_start symbol declared in section .text. The entry stub sets up the kernel stack, pushes the Multiboot magic value (EAX) and the Multiboot info pointer (EBX) as arguments, and calls kmain:
Floppy Disk Image Layout
Themake image target assembles a 1.44 MB floppy image using dd to place each component at its correct sector offset:
| Sectors | Content |
|---|---|
| 0 | MBR — Stage 1 (512 bytes) |
| 1–16 | Stage 2 (up to 8 KB) |
| 17+ | Flat kernel binary (nklegacy.bin) |
objcopy -O binary build/nklegacy.elf build/nklegacy.bin and contains only the loadable sections starting at 0x100000. Stage 2 reads up to 128 sectors (64 KB) from sector 18 onward — note that Stage 2’s disk-read code uses sector 18 (CHS sector 18 = zero-indexed offset 17), matching the seek=17 in the Makefile.
make run builds the GRUB ISO (build/nklegacy.iso) and boots it with qemu-system-i386 -cdrom. This path is recommended for development because GRUB provides a full Multiboot environment, accurate memory maps, and faster iteration — no floppy emulation quirks. Use make run-bootman to test the NKBootman floppy path specifically.