`
love19820823
  • 浏览: 944465 次
文章分类
社区版块
存档分类
最新评论

《 深入理解Linux内核》——第二章 内存寻址:读书笔记

 
阅读更多

内存寻址主要任务:将逻辑地址转换为物理地址。
逻辑地址---通过分段单元--》线性地址----通过分页单元---》物理地址
注意三个方面:分段、分页、TLB。(都是基于保护模式)
Intel微处理器两种不同方式进行地址转换:实模式(real mode){用于开机加载时,兼容早期模型}、保护模式(protected model)。
分段和分页在某种程度上是有点多余。区别:分段可以给每一个进程分配不同的线性地址空间;分页可以把一个线性地址空间映射到不同的物理空间。
一、分段
段选择符(存放于段寄存器中)、段描述符。
1)段选择符 (和段寄存器)
段选择符Segment Selector(或者说:段标识符)16位:15-3,索引号;2,TI;1-0,RPL。
RPL(Request Privilege Level),TI(Table Indicator)
有6个段寄存器:cs,ss,ds,es,fs,gs。
其中cs 代码段寄存器,指向包含程序指令的段(一个进程中)
重要:两位字段CPL(Current Privilege Level),为0表示最高优先级,为3表示最低优先
级。Linux只用0级 和 3级,分别称为 内核态、用户态。
ss 栈段寄存器,指向包含当前程序栈的段(一个进程中)
ds 数据段寄存器,指向包含静态数据或任意的数据段(一个进程中)
其他三个寄存器做一般用途,可以指向任意的数据段。
2)段描述符
8个字节的Segment Descriptor。放在GDT(Global Descriptor Table)或LDT(Local Descriptor Table)中。
Linux中的段描述符类型:
代码段描述符、数据段描述符、任务状态段描述符(TSSD Task State Segment Descriptor)、局部描述符表描述符(LDTD Local Descriptor Table Descriptor)。
其中TSSD和LDTD只能出现在GDT中。其他两个可以出现在LDT或GDT中。

通常只定义一个GDT,每个进程除了存放在GDT中的段之外还需要创建附加的段,可以有自己的LDT。GDT在主存中的地址和大小存放在gdtr控制寄存器中,当前正被使用的LDT地址和大小放在ldtr控制寄存器中。

二、分页
1) 常规分页:
32位被分为3个域,Directory(高10位),Table(中间10位),Offset(最低12位)。
从80386起,Intel微处理器分页单元处理4Kb的页。
cr3寄存器:存放正在使用的页目录的物理地址。Directory和Cr3相加指向页目录表项、Talbe再相加指向 页表 表项,Offset再相加 指向 页 中的物理地址。

注意:0x2003ffff,Directory是0x080,因为高10位位 0010 0000 00,转为16进制,最高两位补0,为:0000 1000 0000, 0x080
2)扩展分页
允许页框大小是 4MB,(之前是4Kb)
Directory:高10位
Offset:低22位

PAE(physical Address Extend)。具体不详细列。
3)Linux中的分页
页全局目录(Page Global Directory)
页上级目录(Page Upper Directory)
页中间目录(Page Middle Directory)
页表(Page Table)
偏移(Offset)
进程页表:从0x0000 0000 到 0xbfff ffff,用户态、内核态都可以寻址
0xc000 0000 到 0xffff ffff,(3G~ 4G-1),只有内核态进程才能寻址。
0xc000 0000 (3G)这个值PAGE_OFFSET的值。进程在线性地址空间的偏移量。也是内核生存空间的开始之处。
Linux在初始化阶段一般是将896MB的RAM窗口 映射到 内核线性地址空间。(所以程序对RAM分4096Mb)

三、TLB

TLB(Translation Lookaside Buffer)用于加快线性地址转换。
L1_CACHE_BYTES在P4前的为32,P4上的为128。
Lazy TLB模式:只用于多核,多个CPU使用相同的页表,必须对这些CPU上的一个TLB表项刷新,在某些情况下,正在运行内核线程的那些CPU上的刷新可以延迟(只要不访问,下次切换就转到别的进程了)。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics