JIURL文档-Linux的虚拟内存与分页机制(x86-64位)(二)

作者:JIURL
日期:2015年11月01日

还是分页机制

进程的页目录和页表在虚拟地址空间中的位置


   上一篇中,我们把分页相关结构,分别叫做PML4,PDPT,PD,PT。这是Intel对x86-64中这些结构的称呼。Linux需要支持多种不同类型的CPU架构,所以对分页相关结构,做了一层抽象。对于需要4级地址转换的分页相关结构,分别叫做PGD,PUD,PMD,PTE。对于x86-64CPU来说,PGD=PML4,PUD=PDPT,PMD=PD,PTE=PT(注意PTE是PTE表的意思)。两者指的是同样的东西,仅仅是叫法不同(番茄和西红柿,番茄炒西红柿算不算黑暗料理?)。

   当执行一条访问内存的指令时,如果寄存器中的分页标志位已经被设置,CPU就自动完成虚拟地址到物理地址的转换,来完成该指令。CPU在转换地址过程中,并不需要PGD,PUD,PMD,PTE的虚拟地址。但是分页标志位被设置之后,CPU会把所有指令中的地址当做虚拟地址转换成物理地址。所以所有程序(包括操作系统)中使用的都是虚拟地址。一个进程的一套PGD,PUD,PMD,PTE结构是由系统维护的,比如一个进程申请或者释放内存,系统就需要设置对应的一些页表项。系统需要访问PGD,PUD,PMD,PTE结构,但是系统只能使用虚拟地址,所以系统必须把一个进程的PGD,PUD,PMD,PTE结构映射到地址空间中(32位的Linux情况有不同。目前64位用于映射物理内存的地址空间足够大,估计未来也不需要做进一步处理)。

    Linux会把物理内存从物理地址0x0000000000000000开始,一一映射到 0xffff880000000000 -0xffffc7ffffffffff这块地址空间中。这块地址空间的大小为64TB。物理内存小于64TB的话,将全部被映射到这块地址空间中。也就是说,通过这个区域的虚拟地址,将可以访问整个物理内存(相信将来也不会有使用大于64TB物理内存的PC,那得交多少电费?吓死本宝宝了。)。

    Linux中,可以通过每个进程的进程结构(task_struct)找到该进程的PGD表的物理地址,顺着PGD表就可以找到该进程的所有分页相关结构的物理地址。task_struct.mm->pgd中的值,就是该进程PGD表的物理地址。切换地址空间时,将会把要切换过来的进程的task_struct.mm->pgd值,放入CR3中(具体细节参考Linux源码中的switch_mm函数)。
task_struct 结构是linux的进程结构,在/include/linux/sched.h中定义。
task_struct 结构中有成员变量 struct mm_struct *mm, *active_mm;
mm_struct 结构在 /include/linux/mm_types.h中定义。
mm_struct 结构中有成员变量 pgd_t * pgd;

   我们来访问一个进程的所有分页相关结构。整个物理内存被全部一一映射到了0xffff880000000000 -0xffffc7ffffffffff 这块地址空间中,所以 0xffff880000000000 +物理地址,就是该物理地址的一个虚拟地址(一个物理页可能被映射到多个进程地址空间的多个虚拟地址)。通过这个虚拟地址,就可以访问该物理页中的内容。通过每个进程的mm->pgd,可以得到该进程PGD表的物理地址,该物理地址+0xffff880000000000,就得到了该进程PGD表的虚拟地址,就可以访问每一个PGD表项。找到该进程每一个PUD表的物理地址,同样方法可以得到该进程每一个PUD表的虚拟地址。通过所有PUD表的内容,使用同样方法可以得到该进程所有PMD表的虚拟地址。通过所有PMD表的内容,使用同样方法可以得到该进程所有PTE表的虚拟地址。通过所有PTE表的内容,使用同样方法可以得到该进程所有物理页的虚拟地址(意味着一个内核模块可以方便的访问任何进程的地址空间中的内容)。0xffff880000000000- 0xffffc7ffffffffff的64TB地址空间位于高128TB的系统地址空间内,需要系统级的权限才能访问。

    Linux系统也是通过上面的方法来访问一个进程的分页结构的。kmap_atomic函数的源码实现,可以部分验证这一点。(调试环境为,eclipse+qemu源码级内核调试)

static inline void *kmap_atomic(struct page *page)
{
   pagefault_disable();
    returnpage_address(page);
}

#define page_address(page) lowmem_page_address(page)

static __always_inline void *lowmem_page_address(const struct page*page)
{
    return__va(PFN_PHYS(page_to_pfn(page)));
}

#define__va(x)          ((void*)((unsigned long)(x)+PAGE_OFFSET))

#definePAGE_OFFSET       ((unsignedlong)__PAGE_OFFSET)
#define__PAGE_OFFSET          _AC(0xffff880000000000, UL)

有效页目录项和有效页表项

   PGD表项,PUD表项,PMD表项,PTE表现的最低位,第0位,指明了一页是否映射了物理内存。最低位为1,表示该页映射了物理内存。PGD表项,PUD表项,PMD表项,PTE表现,8个字节,64位,有着差不多的结构。结构细节可以参考Intel软件开发手册。

PGD,PUD,PMD,PTE 实例解析

   我写了一个简单的内核模块,可以得到指定进程的pgd值,可以输出指定地址处4KB的内容。

下面的内容,是通过我写的这个内核模块,在我的计算机上运行得到的结果。

实例进程1
init进程(pid为1)的 task_struct.mm->pgd 值为 0x369de000。
即 init进程的PGD表的虚拟地址为0xffff880000000000+0x369de000=0xffff8800369de000。

1. PGD表
0xffff8800369de000 处,4KB内容:
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 0000000036a070670000000036a00067
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000001fd4067 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 000000021608b067 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 00000002147b6067 0000000000000000 0000000000000000000000021e7ef067 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 0000000001e950670000000001c19067

可以看到,
第254项 0000000036a07067负责254*512GB=0x7F0000000000开始处,512GB地址空间的映射
第255项 0000000036a00067
第272项 0000000001fd4067
第402项 000000021608b067
第465项 00000002147b6067
第468项 000000021e7ef067
第510项 0000000001e95067
第511项 0000000001c19067
共8个PGD表项的值最低位为1。PGD表项的低12位是标志位,这8个PGD表项的最低12位的值都为0x067。将低12位清0,即可得到一个PUD表的物理地址。
其余504个PGD表项的值全部为0。一个PGD表现负责512GB地址范围的映射。
一个PGD表项为0,就意味着该PGD表项对应的512GB地址空间,没有映射任何一页物理内存。
一个PGD表项最低位为1,就意味着该PGD表项对应的512GB地址空间中,至少有一部分映射了物理内存。

2. 其中一个PUD表
接着看PGD表项0000000036a07067,对应的PUD表。

0xffff880036a07000 处,4KB内容:
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
...(全都是全0项,省略)
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 0000000036a2f0670000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
...(全都是全0项,省略)
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000

第347项 0000000036a2f067负责347*1GB+0x7F0000000000=0x7F56C0000000开始处,1GB地址空间的映射
本PUD表中只有一个PUD表项的值最低位为1。其余全部PUD表项的值为0。
可以看到本进程 0x7F0000000000处开始的512GB地址空间中,只有0x7F56C0000000处开始的1GB地址空间中,至少有一部分映射了物理内存。绝大部分地址空间,没有映射任何一页物理内存。

3. 其中一个PMD表
接着看PUD表项0000000036a2f067,对应的PMD表。

0xffff880036a2f000 处,4KB内容:
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
...(全都是全0项,省略)
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 000000000000000000000002125f6067
00000002125fa067 00000002125fc067 0000000212602067 00000000d9e8b06700000000d9e8a067 0000000000000000 00000000d9e8906700000000d9e88067
0000000000000000 00000000d9e87067 00000000d9e98067 00000000d9e9706700000000d9e96067 00000000d9e95067 00000000df02406700000000df023067
0000000036aa5067 0000000036aa3067 0000000000000000 00000000d9e8c0670000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000

第471项 00000002125f6067负责471*2MB+0x7F56C0000000=0x7F56FAE00000开始处,2MB地址空间的映射
第472项 00000002125fa067
...
第489项 0000000036aa3067
第491项 00000000d9e8c067
共18项值最低位为1,其余项值为0。

4. 其中一个PTE表
接着看PMD表项00000002125f6067,对应的PTE表。

0xffff8802125f6000 处,4KB内容:

0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
...(全都是全0项,省略)
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 000000021ef34025000000021ef31025
000000021eb43025 000000021ecb6025 000000021ef29025 000000021ecb2025000000021eca2025 000000021ed7a025 000000021ed2b025000000021e75a025
000000021ebd7025 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
...(全都是全0项,省略)
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000

第446项 000000021ef34025负责446*4KB+0x7F56FAE00000=0x7F56FAFBE000开始处,4KB地址空间的映射
第447项 000000021ef31025
...
第455项 000000021e75a025
第456项 000000021ebd7025
共11项值最低位为1,其余项值为0。

至此我们已经顺着PGD,PUD,PMD,PTE 走完了4级地址转换分页结构的一条路径。

我们再来看一下PTE表项000000021ef34025对应的4KB物理页中的数据。也就是该进程0x7F56FAFBE000开始处4KB的数据的开头部分。
0xffff88021ef34000:
00010102464c457f 0000000000000000 00000001003e0003 00000000000022a00000000000000040 000000000000b2e0 0038004000000000001d001e00400009
0000000500000006 0000000000000040 0000000000000040 000000000000004000000000000001f8 00000000000001f8 00000000000000080000000400000003
...
可以看到,里面的内容,已经明显不再是分页结构表项了。

实例进程2
一个gedit进程的 task_struct.mm->pgd 值为 0x182903000。
即 gedit进程的PGD表的虚拟地址为0xffff880000000000+0x182903000=ffff880182903000。

0xffff880182903000处,4KB内容:

00000001f253c067 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 000000000000000000000001ebe23067
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000001fd4067 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 000000021608b067 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 00000002147b6067 0000000000000000 0000000000000000000000021e7ef067 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 00000000000000000000000000000000
0000000000000000 0000000000000000 0000000000000000 00000000000000000000000000000000 0000000000000000 0000000001e950670000000001c19067

第0项 00000001f253c067
第255项 00000001ebe23067
第272项 0000000001fd4067
第402项 000000021608b067
第465项 00000002147b6067
第468项 000000021e7ef067
第510项 0000000001e95067
第511项 0000000001c19067

刚才init进程的PGD有效项为:
第254项 0000000036a07067
第255项 0000000036a00067
第272项 0000000001fd4067
第402项 000000021608b067
第465项 00000002147b6067
第468项 000000021e7ef067
第510项 0000000001e95067
第511项 0000000001c19067

对比,可以发现两者的第402,465,468,510,511项,都有值,并且值完全相同。
这验证了,所有进程的系统地址空间(ffff800000000000 -ffffffffffffffff)部分中的内容是完全一样的。因为每个进程负责系统地址空间部分的PGD项完全相同。相同的某一项都指向同一物理页,则该PGD项之后对应的所有分页结构必然相同。则每个进程的系统地址空间部分所映射的物理页完全相同。
对比,可以发现两者都有255,272项,但是值不同。gedit还有第0项,而init没有第0项。
这验证了,所有进程的用户地址空间(0000000000000000 -00007fffffffffff)部分中的内容是完全不一样的。每个进程都有自己的用户地址空间。

每个进程的PGD,PUD,PMD,PTE分页结构所需内存

   每个进程自己的一套PGD,PUD,PMD,PTE分页结构,所需的内存大小,取决于该进程实际使用的物理内存大小。

   一个进程实际映射8MB物理内存的话,一个页表项可以映射4KB地址空间,8MB/4KB=2048项,需要至少2048个页表项。一个页表项大小为8个字节,2048个页表项大小为16KB。所以,一个进程实际映射8MB物理内存的话,需要至少16KB物理内存,来维护本进程的一套PGD,PUD,PMD,PTE分页结构。

   一个进程实际映射4GB物理内存的话,一个页表项可以映射4KB地址空间,4GB/4KB=1M项,需要至少1M个页表项。一个页表项大小为8个字节,1M个页表项大小为8MB。所以,一个进程实际映射4GB物理内存的话,需要至少8MB物理内存,来维护本进程的一套PGD,PUD,PMD,PTE分页结构。

参考文档
《JIURL玩玩Win2k内存篇》
《Intel Architecture Software Developer Manual》
linux-3.18.22 源码

微博: http://weibo.com/ddqqppb
邮箱:[email protected]
QQ:6291898
欢迎交流指正。
亲,可以加微博,加QQ,发邮件,给5星好评哦。

最后祝大家身体健康,万事如意。JIURL。

(完)

JIURL文档-Linux的虚拟内存与分页机制(x86-64位)(二)_第1张图片

你可能感兴趣的:(JIURL文档-Linux的虚拟内存与分页机制(x86-64位)(二))