x86 Real-Mode Memory Map
What lives at 0xB8000 and the rest of the lower 1 MB on real PC hardware (simplified):
0x00000000 ──────────────────────────────────────────────────────────
INTERRUPT VECTOR TABLE (IVT)
- Size: 1 KB (1024 bytes)
- Range: 0x00000000 → 0x000003FF
- Contains 256 interrupt pointers
(each pointer = 4 bytes: segment:offset)
- BIOS + hardware rely on these entries
- You must NEVER overwrite this area
0x00000400 ──────────────────────────────────────────────────────────
BIOS DATA AREA (BDA)
- Size: 256 bytes
- Range: 0x00000400 → 0x000004FF
- Stores system state set by BIOS:
* Keyboard status
* COM/LPT port data
* Display mode info
* Equipment list
* Memory size under 640 KB
- Also critical. Do NOT touch.
0x00000500 ──────────────────────────────────────────────────────────
LOW REAL-MODE USABLE RAM (SCRATCH SPACE)
- Size: ~30 KB
- Range: 0x00000500 → 0x00007BFF
- This is the first memory that’s safe for you to use
- Bootloaders often:
* Put temporary stacks here
* Read sectors here
* Store disk buffers
- Still under the 1 MB real-mode boundary
0x00007C00 ──────────────────────────────────────────────────────────
BOOTLOADER (BIOS loads here)
- Size: exactly 512 bytes (one sector)
- Range: 0x00007C00 → 0x00007DFF
- This is where your `boot.asm` executed
- The BIOS always:
* Reads LBA sector 0
* Loads into 0x7C00
* Sets CS:IP to 0000:7C00
- A sacred location in IBM PC architecture
0x00007E00 ──────────────────────────────────────────────────────────
REMAINING LOW RAM UNTIL VIDEO MEMORY
- Size: ~480 KB
- Range: 0x00007E00 → 0x0009FFFF
- Often used by early loaders:
* Move kernel here temporarily
* Prepare GDT/IDT
* Setup buffers
* Enable A20 line
- This memory is still safe but messy
0x000A0000 ──────────────────────────────────────────────────────────
VGA GRAPHICS MEMORY (FRAMEBUFFER)
- Size: 64 KB
- Range: 0x000A0000 → 0x000AFFFF
- Used for pixel graphics modes:
* Mode 13h (320×200)
* VESA modes (varies)
- CPU writes pixel values directly here
0x000B8000 ──────────────────────────────────────────────────────────
VGA TEXT MODE BUFFER
- Size: 4 KB (depending on mode)
- Range: 0x000B8000 → ~0x000B8FA0
- Layout (80×25 mode):
* 2000 characters
* Each: 1 byte char + 1 byte attribute = 2 bytes
- Your ‘K’ printed earlier is ultimately reflected here
- CPU writes characters here directly
0x000C0000 ──────────────────────────────────────────────────────────
BIOS ROM + EXPANSION ROMs
- Size: 256 KB
- Range: 0x000C0000 → 0x000FFFFF
- Contains:
* System BIOS firmware
* Video BIOS
* Option ROMs (network PXE boot, RAID controllers)
- Memory is READ-ONLY, mapped to actual ROM hardware
- Firmware lives here permanently
0x00100000 ──────────────────────────────────────────────────────────
1 MB MARK — HIGH MEMORY — KERNEL LAND
- Size: "Everything above 1 MB" (depends on RAM)
- Range: 0x00100000 → end of RAM
- Clean, uncontested, flat RAM
- Perfect for protected-mode kernels:
* No BIOS data
* No video memory
* No ROM shadowing
- This is where you will load and execute your kernel
- Common OS convention:
Kernel physical start = **0x00100000**Why The Map Looks Like This (History + Hardware Reasons)
Everything below 1 MB is a disaster of 1980s design, preserved eternally for compatibility:
- The first 1 KB (IVT) must exist so interrupts work.
- The next 256 bytes (BDA) hold BIOS system info before any OS loads.
- From 0x500 → 0x7BFF is old-school RW RAM available to boot sectors.
- The bootloader is forced to be at exactly 0x7C00 due to 1981 IBM PC BIOS design.
- The space from 0xA0000 to 0xBFFFF is reserved by VGA hardware.
- The top 256 KB (0xC0000–0xFFFFF) is ROM where the BIOS literally lives.
The region above 1 MB is clean only because:
After the A20 line is enabled and the CPU enters protected mode, memory above 1 MB is flat, linear, and not polluted by BIOS history.
This is why every modern kernel starts at 1 MB.