在 Linux 源代码(版本 2.6.18)中:
movl $swapper_pg_dir-__PAGE_OFFSET,%eax
movl %eax,%cr3
movl %cr0,%eax
orl $0x80000000,%eax
movl %eax,%cr0 /* ..and set paging (PG) bit */
ljmp $__BOOT_CS,$1f /* Clear prefetch and normalize %eip */
还有load_cr3(pgdir)
andwrite_cr3(x)
宏:
#define load_cr3(pgdir) write_cr3(__pa(pgdir))
#define write_cr3(x) \
__asm__ __volatile__("movl %0,%%cr3": :"r" (x))
似乎整个cr3
控制寄存器都存储了Page Directory的地址。但是,当我参考 intel ia-32 Developer's_Manual 时,它讲述了一个不同的故事。以下是英特尔手册的内容:
name 0.............11 12.................31
cr3 flags address of page directory
PDE flags address of page table
PTE flags address of 4kb page frame
手册说 20 个最高有效位cr3
存储页面目录的地址而不是整个cr3
寄存器。这也是合理的,因为页面目录正好是 4kb,所以地址的 12 个最低有效位始终为零。
是不是有点奇怪?linux 代码只是将页面目录的地址分配给 .cr3
而不是swapper_pg_dir
. 寄存器存储的究竟是什么cr3
,地址或英特尔手册建议的格式?
以下链接是英特尔手册: http: //www.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html