xv6 在 entry.S 中开启分页
启用分页机制需要完成下面三步
- 准备好页目录表和页表
- 将页表地址写入控制寄存器 cr3
- 将寄存器 cr0 的 PG 位置 1
../../study/os/xv6-public/entry.S
entry 阶段使用 CR4_PSE 的 4M 大页映射,这里的前提是做以下操作
- 需要 Pentium 以上的 CPU
- CR4 中的 PSE 位(第 4 位)为 1
- 页目录项的 PS 位(第 7 位)为 1
通过 qemu 验证开启分页后
(qemu) help info tlb info tlb -- show virtual to physical memory mappings (qemu) help info mem info mem -- show the active virtual memory mappings (qemu) info tlb 0000000000000000: 0000000000000000 --P-A---W 0000000080000000: 0000000000000000 --P-----W (qemu) info mem 0000000000000000-0000000000400000 0000000000400000 -rw 0000000080000000-0000000080400000 0000000000400000 -rw (qemu)
gdb 调试分页
(gdb) b main Breakpoint 2 at 0x80103060: file main.c, line 20. (gdb) c Continuing. => 0x80103060 <main>: lea 0x4(%esp),%ecx Thread 1 hit Breakpoint 2, main () at main.c:20 20 kinit1(end, P2V(4*1024*1024)); // phys page allocator (gdb) info reg cr3 cr3 0x109000 [ PDBR=265 PCID=0 ] (gdb) x/8x 0x109000 0x109000: 0x000000a3 0x00000000 0x00000000 0x00000000 0x109010: 0x00000000 0x00000000 0x00000000 0x00000000 (gdb) p *(int *)0x109000 $1 = 163 (gdb) p/x *(int *)0x109000 $2 = 0xa3 (gdb) p/t *(int *)0x109000 $3 = 10100011 (gdb)
- end 查看手册,获取
extern char end[];
细节man 3 end
- kinit1 初始化内存
- kmem.freelist 初始化链表
- 头插法
- kfree 初始化页面
(gdb) x/8x 0x803fc000 0x803fc000: 0x803fb000 0x01010101 0x01010101 0x01010101 0x803fc010: 0x01010101 0x01010101 0x01010101 0x01010101
- memset 初始化块内存
- 内联汇编设置内存值