Writing an OS Kernel from Scratch | How BIOS/UEFI/GRUB Hand Control to the OS After Boot

Have you ever wondered: in the instant you press the power button, where does the CPU’s CS:IP register point? Who set it to that value? Why does the screen light up showing a selection menu instead of black?

This isn’t magic. It’s a long relay chain — from the moment the CPU powers on to when GRUB hands control to the kernel, at least three stages: BIOS/UEFI firmware → Bootloader (GRUB) → OS entry point. Each handoff has strict procedures.


BIOS Era Boot: Where 0xFFFF0 Comes From

CPU’s First Jump on Power

After x86 CPU powers on, the first thing isn’t reading the disk — it’s hardwired: CS = 0xFFFF, IP = 0x0000, forming physical address CS << 4 + IP = 0xFFFF0. This address is outside 640KB main memory (near the 1MB top), reserved for BIOS ROM.

Bash
CPU power-on instant:
CS = 0xFFFF
IP = 0x0000
────────────────
Physical address = 0xFFFF0 (ROM BIOS entry point)

BIOS ROM places a jmp instruction at this address, jumping to the real initialization code. This is the first instruction of the entire system software — not Linux, not GRUB, but a jump burned into BIOS ROM.

POST and Hardware Self-Check

BIOS’s first real task is POST (Power-On Self Test): check CPU, memory, GPU, keyboard controller. If POST fails, you hear beep codes; if successful, the screen lights up showing the manufacturer logo.

Real Mode Disk Boot

After POST, BIOS follows the Boot Order to try each boot device. For legacy BIOS mode, BIOS reads the disk’s first sector (MBR, 512 bytes) into memory at 0x7C00, checks if the last 2 bytes are 0x55AA (bootable flag). If yes, BIOS jumps to 0x7C00 — handing control to the first leg of the Bootloader.

Last modified: 2024年11月28日

Author

Comments

Write a Reply or Comment

Your email address will not be published.