深入理解linux内核-阅读笔记-第二章

第二章 内存寻址

内存地址

内存地址分为三种,分别是逻辑地址、线性地址和物理地址。

逻辑地址是指机器指令中,比如汇编中有代码段,栈段之类的段名,以及一个偏移量,用来确定某个变量或者方法所在的地址。

线性地址是指运行的时候,某个变量在内存中的虚拟地址,比如我们定义一个int a,输出&a,就是输出变量a的线性地址。

物理地址是指某个线性地址在物理内存上的实际地址。

逻辑地址转为线性地址是通过一个叫MMU的硬件转换,通过分段单元的硬件电路转换,而线性地址转物理地址是通过分页单元进行转换。

CPU访问内存条的时候,需要通过一个叫内存仲裁器的硬件电路,用于限制多CPU对某个内存条的串行读写。即使是单CPU,也需要内存仲裁器,因为存在DMA控制器。DMA是某个用来读取内存的硬件(等待补充)

段选择符和段寄存器

前面说过逻辑地址包含一个段名和一个偏移量,这个段名叫段选择符,16位大小,13位用来记录段位移,1位用于标记在GDT还是在LDT中,2位用来标记当前CPU的level。

CPU的level是指CS中有两bit,用来记录4种不同CPU当前的level,linux中使用0代表内核态,3代表用户态。

段寄存器有6个,分别是cs,ss,ds,es,fs,gs。其中cs是代码段寄存器,用来记录当前代码段的段选择符,ss为栈段,ds为数据段,其他作为一般用途。

段描述符

段描述符共64bit,描述段的属性,用来描述段首地址,长度,权限等属性。

段描述符可能存在全局描述符表(GDT)或者局部描述符表(LDT)中。

全局描述符表只有一个,其在主存的位置,存在gdtr寄存器中。

局部描述符表为进程特有,ldtr寄存器会记录当前使用的LDT地址和大小。

快速访问段描述符

CPU提供了额外的寄存器,当段选择符被装入到段寄存器时,就会通过GDT或者LDT查找内存上对应的段描述符,然后填充到这额外的寄存器中,减少了查主存的开销,加速了逻辑地址到线性地址的转换。

段描述符地址计算方式为,GDT或者LDT中的地址,加上段描述符的13位*8。

段描述符在GDT中还是LDT中,由段选择符的第14位决定。

分段单元

(待更新)

Q&A

转载于:https://www.cnblogs.com/scaugsh/p/11094798.html