Skip to content
Lesson 2 of 24

Step 1 of 5 · Reading · ~4 min

Read

Boot & Memory

Boot Process

Between the power button and your kernel's first instruction lies a fixed choreography. Every stage exists because the previous one was too small to do the next job. In this lesson you will read the first thing that choreography touches on a BIOS machine: the 512-byte master boot record. Your program will take a real sector as hex, check it, decode its partition table and say which partition the BIOS would boot.

The chain, in order

  1. Reset vector. The CPU starts at 0xFFFFFFF0, 16 bytes below 4 GiB, where the firmware ROM is mapped, in real mode: the 16-bit mode of the 1978 8086. Every x86 chip still wakes up pretending to be one.
  2. Firmware (BIOS POST). It tests RAM, discovers devices, picks a boot disk and reads exactly one sector (the first 512 bytes) to physical address 0x7C00. If the last two bytes of that sector are 55 AA it jumps to 0x7C00. That is the entire BIOS-to-OS interface: 512 bytes at a fixed address, no filesystem, no negotiation.
  3. Bootloader. 446 bytes cannot hold a filesystem driver, so stage 1 only loads a larger stage 2 (GRUB's core image) from a fixed place. Stage 2 can read files, loads your kernel ELF, and records the E820 memory map, the hardware's one-time list of which RAM ranges are usable. A Multiboot kernel is entered with a pointer to that information.
  4. Mode switches. Enable the A20 line, load a GDT, set CR0.PE for protected mode; for 64-bit build page tables, set EFER.LME and turn on paging.
  5. Kernel early init. Zero .bss, set a stack, bring up a console, load your own GDT and IDT, parse the memory map, then allocator, paging, scheduler, and finally start PID 1.

UEFI replaces steps 2 and 3 with a FAT "EFI System Partition" holding the bootloader as an ordinary executable, but the handshake (memory map in, kernel entry out) is the same.

Anatomy of the sector

offset    size  field
0         440   bootstrap code
440       4     disk signature (little-endian, e.g. what fdisk calls "Disk identifier")
444       2     usually 00 00
446       16    partition entry 1
462       16    partition entry 2
478       16    partition entry 3
494       16    partition entry 4
510       2     boot signature: bytes 55 AA

Read the last two bytes in order: the byte at 510 is 0x55, the byte at 511 is 0xAA. As a little-endian 16-bit word that is 0xAA55, which is why you see both spellings.

Each 16-byte partition entry:

OffsetSizeMeaning
01boot flag: 0x80 active, 0x00 inactive, anything else is invalid
13CHS address of the first sector (obsolete)
41partition type (0x83 Linux, 0x07 NTFS, 0xEE GPT protective, 0x00 empty slot)
53CHS address of the last sector (obsolete)
84LBA of the first sector, little-endian
124number of sectors, little-endian

Worked example, one real entry:

80 20 21 00 83 FE FF FF 00 08 00 00 00 20 03 00

Flag 80 is active, type 83 is Linux. The start field is the bytes 00 08 00 00; reversed they are 0x00000800 = 2048 (the 1 MiB alignment every modern partitioner uses). The count 00 20 03 00 reverses to 0x00032000 = 204800 sectors = 100 MiB. Read it big-endian by mistake and the start becomes 0x00080000 = 524288. The last sector is start + count - 1 = 206847.

Common mistakes

  • Reading the LBA or count most-significant byte first.
  • Treating the signature as 0x55AA instead of the bytes 55 AA (a word of 0x55AA means the bytes were swapped and the BIOS refuses the disk).
  • Computing last in 32 bits: a GPT protective entry (type 0xEE) has start 1 and count 0xFFFFFFFF, so start + count - 1 needs more than 32 bits of room before you subtract.
  • Counting an entry with an invalid flag as bootable.

Your exercise

The program receives the sector as hex text and prints the report described in the exercise. The starter parses the hex into a 512-byte array for you; you write the decoding.

Up nextThe VGA Text ConsoleBoot & Memory

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…