深入理解linux内核--内存3

硬件中的分页

为了效率,线性地址被分为固定长度的组,成为”页“,页内连续的线性地址被映射到连续的物理地址。这样,内核可以指定一个页的物理地址和其存取权限。把线性地址映射到物理地址的数据结构被称为”页表“,页表在主存中。

386开始,页为4kb

directory:最高10位,Table(页表):中间10位;Offset:最低12位;

二级模式的目的是为了减少每个进程页表所需的RAM数量。

每个活动的进程必须分配一个页目录,不过没有必要为进程的所有页表都分配RAM。只有在进程实际需要一个页表时才分配RAM。

正在使用的页目录的物理地址存放在cr3寄存器。线性地址中的directory字段只是存在页目录中的目录项。而页目录项指向适当的页表,地址Table字段说明页表中的表项。表项中存放的是页框的物理地址。

页目录项和页表项有相同的结构,有以下字段:

Present标志,包含页框物理地址最高20位的字段,accessed,dirty,read/write...

扩展分页:

允许页框大小是4MB

物理地址扩展(PAE)分页机制:

现在处理器的寻址数目由32增加到36.RAM大小为64GB,页表项物理地址字段由20位扩展到24位。页表项大小由32位变成64位。如果页目录项中的页大小标志PS启用大尺寸页(在PAE启用时为2MB)

结果4KB页表包含512个页表项而不是1024个表项。

引入一个叫页目录指针表的页表新级别,它由4个64位表项组成。

cr3包含一个27位的页目录指针表(PDPT)基地址字段。

当把线性地址映射到4KB的页时,32位线性地址按下列方式解释:

cr3:指向一个PDPT;

31-30:指向PDPT中4个项中的一个;

29-21:指向页目录项中512个项中的一个;

20-12:指向页表中512项中的一个;

位11-0:4KB页中的偏移量;

总之,一旦CR3被设置,就可寻址高达4GBRAM。如果希望对更多的RAM寻址,就必须在CR3中方一个新值。

但是线性地址仍然是32位,也就意味着同一个线性地址映射不同的RAM区。很明显,PAE并没有扩大进程的线性地址空间,因为它只能处理物理地址。此外,只有内核能够修改进程的页表,所以用户态下运行的进程不能使用大于4GB的物理地址空间。但是,内核的使用容量高达64GBRAM,从而显著增加了系统中的进程数量。

高速缓存

linux清楚了所有页目录项和页表项中的PCD和PWT,对所有页框都启用高速缓存,对于写操作,总是回写策略。

Linux中的分页

linux的分页模型同时适用32位和64位系统。linux从2.6.11开始,采用四级分页模型。

  • 页全局目录
  • 页上级目录
  • 页中间目录
  • 页表

线性地址因此被分为5个部分。如果是32位系统没有启用物理扩展的情况下,让”页上级目录“和”页中间目录“位全为0,从而恢复2级目录。

  1. 给每个进程分配一块不同的物理地址空间,确保了寻址错误;
  2. 区别页和页框;
  3. 每个进程有它自己的页全局目录和自己的页表集。

物理内存布局

一般来说linux内核安装在物理地址0x00100000开始的地方,也就是在第2个MB开始。

进程页表

0x0000 0000-0xbfff ffff的线性地址,无论进程运行在用户态还是内核态都可以寻址。

0xc000 0000-0xffff ffff的线性地址,只有内核态的进程才能寻址。

内核页表

内核线性地址是1GB,1GB= 12MB特殊映射+896MB

linux映射一个896MB的RAM窗口到内核的线性地址空间。剩余的RAM留着不映射,并由动态重映射。而且着896MB的线性地址是映射到物理内存低位区域。而且这896MB的线性地址所建立的映射是线性的,映射的物理地址=线性地址=PAGE_OFFSET

所以至少128MB的内核线性地址留作它用,可以是非连续内存分配和固定映射地址。

定映射的线性地址类似常量映射,它和物理地址不是线性的,但是固定不变的。

 

posted @   老胡同学  阅读(121)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示