在与GDT相关的一章中, 我们看到使用段机制, 物理内存地址要用一个段选择子和一个偏移计算.
在本章, 我们将实现分页. 分页将线性地址从段映射到物理地址.
分页机制允许我们的内核:
在分页系统中, 每个进程可以执行在它的的4Gb内存中, 绝不会影响其他进程或内核的内存. 它简化了多任务调度.
从线性地址到物理地址的映射需经过多步:
CR3
寄存器知道页目录表的起始地址.这两个类型的表项(表和目录)看起来是一样的. 我们的操作系统只会使用标灰的区域.
P
: 指示这个页或者表是否在物理内存中R/W
: 指示这个页或者表能否写(值等于1)U/S
: 等于1时允许访问非首选任务A
: 指示这个页或页表有没有被访问D
: (只对页表有意义)指示页有没有被写PS
(只对页目录表有意义)指示页大小注解: 页目录和页表中的物理地址用20位表示, 这是因为这些地址是4KB对齐的, 所以后12位等于0.
为了开启分页, 只需设置 CR0
的第31位为1即可.
asm(" mov %%cr0, %%eax; \
or %1, %%eax; \
mov %%eax, %%cr0" \
:: "i"(0x80000000));
但是在之前, 我们需要至少一个也来初始化我们的页目录.