《深入理解Linux内核》内存寻址学习心得

510阅读 0评论2014-06-15 hackernelor
分类:LINUX

1.    三种地址:逻辑地址,线性地址,物理地址。

三者的详细解释:

         逻辑地址(logical address):由段(segment(16)和偏移量(offsetdisplacement(32)组成。

         线性地址(linear address)(也称虚拟地址virtual address):是一个32位无符号整数,用来表示高达4GB的地址。

物理地址(physical address):实际地址。

 

分段目的:把逻辑地址转换为线性地址,如下图所示:

 

2.1 段标识符和段寄存器

      

段标识符(段选择符)(存放在段寄存器中)字段如下:

index

用来得到段描述符在GDTLDT中的偏移(位置)

TI

指明段描述符是在GDT(TI=0)或在LDT(TI=1)

RPL

请求特权级,

由于一个段描述符是8字节,因此它的地址=GDTLDT内的首地址+(index*8)。能够保存在GDT中的段描述符的最大数目是8191(213-1),其中13index的位数。

不同段的段描述符构成段描述符表,段描述符(8字节)存放在全局描述符表(GDT)或局部描述符表(LDT)中。GDT在主存中的地址和大小存放在gdtr控制寄存器中,当前正被使用的LDT地址和大小存放在ldtr控制寄存器中。

2.2 段描述符

 

CPL(Current Privilege Level)

当前特权级

DPL(Descriptor Privilege Level)

描述符特权级

RPL ( Require Privilege Level)

请求特权级,

Liunx中广泛采用的段描述符类型:代码段描述符、数据段描述符、任务状态段描述符、局部描述符表描述符(代表一个包含LDT的段)

 

2.3 快速访问段描述符:(是由逻辑地址得到段的一个流程)

 

1.4  Linux中的分段

用户代码段

__USER_CS

用户数据段

__USER_DS

内核代码段

__KERNEL_CS

内核数据段

__KERNEL_DS

1.5  Linux GDT

每个处理器中只有一个GDT,所以在多处理器系统中有多个GDT。一般的,每个处理器中的都是GDT的一个副本。除了以下的三种情况:

1.每个处理器都有自己的TSS段,因此其对应的GDT项不同。

2.GDT中只有少数项可能依赖于CPU正在执行的进程。

3.在某些情况下,处理器可能临时修改GDT副本中的某个项。

所有的GDT存放在cpu_gdt_table数组中,而所有的GDT的地址和它们的大小(初始化gdtr时用)存放在cpu_gdt_descr数组中。这些都在arch/i386/kernel/head.s中定义。

如下图所示,一个GDT中包含18个描述符和14个空的、未使用的、或保留的项。

 

1.6  Linux LDT

大多数用户态程序不使用LDT,这样内核就在GDT中定义了一个缺省的LDT来供大多数进程共享。缺省的LDT存放在default_ldt数组中。它含有5个项,内核只使用了两个项:用于iBCS执行文件的调用门和Solaris/x86可执行文件的调用门。调用门是一种机制:用于在调用预定义函数时改变CPU的特权级。

如果进程需要创建自己的LDT,则使用modify_ldt()系统调用。用户创建的LDT需要自己的段,此时GDT中的LDT表项相应的就要被修改。

2.    分页

目的:把线性地址转换为物理地址。其中的一个关键任务:比较所请求的访问类型与线性地址的访问权限。如果内存访问无效,则产生一个缺页异常。

:以固定长度为单位的线性地址。页内部的线性地址被映射到连续的物理地址中。(代表一组数据)

页框RAM被分成固定长度的页框,每一个页框包含一个页。(即主存中的物理地址

页表:把线性地址映射到物理地址的数据结构,它存放在主存中,并在启用分页单元之前由内核进行初始化。

所有的80x86都支持分页,它通过设置cr0寄存器的PG标志启用(PG=0)

3.1 常规分页

 

32位的线性地址被分为3个域(4KB的页)

重要的概率

组成

页目录

页目录项

页表

页表项

线性地址到物理地址的转换如下图所示:

 

3.2 扩展分页

 

3.3 物理地址扩展(PAE)分页

看书p56-57

3.4 硬件保护方案

段有三种存取权限(读、写、执行),页只有两种存取权限(读、写)

PAE(Physical Address Extension)

物理地址扩展

PSE(Page Size Extension)

页大小扩展

PGE(Page Global Enable)

页全局启用

3.5 硬件高速缓存

原因:CPURAM之间速度不匹配。

原理:基于局部性原理,用小而快的内存来存放最近最常使用的代码。以脉冲突发模式(burst mode)在慢速DRAM和快速片上SRAM之间传送行(一种新单位)

映射关系:直接映射、全相关、N-路相关。

硬件高速缓存单元的组成:一个硬件高速缓存内存、一个高速缓存控制器。Cache hitcache miss。通写(write-through)、回写(write-back)

 

多处理器高速缓存,需要保持高速缓存间的内容同步。就有一种高速缓存侦听(cache snooping)活动来实现同步。

 

Linux中对所有的页框都启用高速缓存,对于写操作总是采用回写策略。

3.    Linux中的分页

4.1 分页概述

Linux2.6.11开始采用四级分页模型:(为了适用于32位和64位系统)

l  PGD(Page Global Directory)

l  PUD(Page Upper Directory)

l  PMD(Page Middle Directory)

l  PT(Page Table)

PGD中包含若干PUD的地址,PUD中包含若干PMD的地址,PMD中又包含若干PT的地址。每一个页表项指向一个页框。线性地址被分为五个部分,如下图所示:(图中没有指明每一部分的大小,因为每一部分的大小与具体的计算机体系结构相关。)

 

没有启用物理地址扩展的32位系统,两级页表就可以了。Linux通过使PUDPMD对应的位全为0,使得每个PUDPMD都只有一个项。此时PGDPUDPMDPT中表项的个数分别是:1024111024

启用物理地址扩展的32位系统使用了三级页表。Linux中的PGD对应于80x86的页目录指针表(PDPT)PUD对应位全为0PMD对应于80x86的页目录,PT对应于80x86的页表。此时PGDPUDPMDPT中表项的个数分别是:41512512

Linux的进程处理依赖于分页:

1.       给每一个进程分配一块不同的物理地址空间,可以有效地防止寻址错误。

2.       区别页和页框之不同。这就允许存放在某个页框中的一个页,然后保存到磁盘上,以后重新装入这同一页时又可以被装在不同的页框中。这是虚拟内存机制的基本要素

当发生进程切换时,linuxcr3控制寄存器的内容保存在前一个执行进程的描述符中,然后把下一个要执行进程的描述符的值装入cr3寄存器中,因此,当新进程重新开始在CPU上执行时,分页单元指向一组正确的页表。

 

上一篇:没有了
下一篇:没有了