x86 实模式内存映射如下:
- 0x00000000 - 0x000003FF - Real Mode Interrupt Vector Table
- 0x00000400 - 0x000004FF - BIOS Data Area
- 0x00000500 - 0x00007BFF - Unused
- 0x00007C00 - 0x00007DFF - Our Bootloader
- 0x00007E00 - 0x0009FFFF - Unused
- 0x000A0000 - 0x000BFFFF - Video RAM (VRAM) Memory
- 0x000B0000 - 0x000B7777 - Monochrome Video Memory
- 0x000B8000 - 0x000BFFFF - Color Video Memory
- 0x000C0000 - 0x000C7FFF - Video ROM BIOS
- 0x000C8000 - 0x000EFFFF - BIOS Shadow Area
- 0x000F0000 - 0x000FFFFF - System BIOS
在我的实模式编程中,我通常坚持从 0x00007E00 - 0x0009FFFF(不是全部).. 我使用段:偏移寻址来使用内存.. 从 1 阶段引导加载程序到内核或引导加载程序第二阶段,我使用:
; bootloader.s
BITS 16
ORG 0x7C00
CLI
JMP 0xE000 ; Can also be JMP 0x7C00:200
HLT
TIMES 510 - ($-$$) DB 0
DW 0xAA55
--
; Something.s
BITS 16
ORG 0x7E00 ; Can also be ORG 0x7C00:200
; Code goes here for your purposes.. whether it be a 2nd stage
; bootloader or your 16bit kernel..
CLI
HLT
如果您要进入保护模式,您仍然需要如上所示的存根。在Something.s中,您可以在保护模式例程中编程(GDT、A20、设置视频模式等)
为了解释 0x7C00(引导加载程序入口点)的内存位置,0x7C00 - 0x7DFF 是放置引导加载程序的位置(上面的 bootloader.s)。您将其放置在那里是因为 BIOS 在执行其例程后会跳转到该位置。引导加载程序的大小必须正好为 512 字节(注意 TIMES 指令)。从那里,您的代码可以是任何大小(只要它适合内存映射),您将能够完全在操作系统上工作。
如果您确实进入 32 位保护模式,您将能够使用任何关于 1MiB 标记的内容。