从零写OS(六):内存管理,知道自己有多少地可种

内核跑起来之后,第一个绕不开的问题就是内存。 你不知道这台机器有多少内存,哪些地址段可以用,哪些是硬件保留的。如果随便往一个地址写数据,轻则数据损坏,重则触发异常直接重启。 这一章解决一件事:让内核知道内存的全貌,然后有序地分配和回收物理页。 先问 BIOS:你有多少内存? 我们用 E820(BIOS INT 0x15 AX=E820h,一种标准接口,用来查询物理内存的分布和类型)来探测内存。 这事必须在实模式下做——切换到长模式之后就再也访问不到 BIOS 服务了。所以探测代码放在 boot.asm 里,在进入长模式之前完成。 每次调用 INT 0x15,BIOS 填一条 24 字节的记录: base (8字节) — 这段内存的起始物理地址 length (8字节) — 这段内存的长度(字节) type (4字节) — 类型:1=可用,2=保留,其它=别动 ACPI (4字节) — 扩展属性,一般忽略 循环调用直到 EBX 变成 0,表示枚举完毕。所有记录写入固定地址 0x8000,第一个 4 字节存条目数量。 mov di, MMAP_ADDR + 4 ; 从 0x8004 开始存条目 xor ebx, ebx xor bp, bp ; bp 记条目数量 .e820_loop: mov eax, 0xE820 mov ecx, 24 mov edx, 0x534D4150 ; "SMAP" 魔数,BIOS 验证用 int 0x15 jc .e820_done ; CF=1 表示出错或结束 inc bp add di, 24 test ebx, ebx jz .e820_done ; ebx=0 表示最后一条 jmp .e820_loop .e820_done: mov dword [MMAP_ADDR], ebp ; 把条目数量写到 0x8000 QEMU 上跑出来的内存地图一般长这样: ...

May 6, 2026 · 3 min · 大飞
京ICP备14031575号-3