前言:为啥进行分段:(节省内存,方便管理)
example:设定有100 空间, 进行访问
1),如果一级访问,建立index 0~99 不进行分级,需要1~100 存储空间来存放index(1~100)
2),如果二级访问,第一级0~9, 第二级0~9,假如访问35(第一级访问3,第二级访问5,就可以访问到35 存储空间),因此需要 index 20个就可以了。
基础概念:
硬件中的分页分常规分页和扩展分页
常规分页,32位的线性地址被分为3个域: 10 bit 10bit 12 bit (0000000010 0000000010 111111111111)
Directory(目录) 最高10位
Table(页表) 中间10位
Offset(偏移量) 最低12位
扩展分页,32位的线性地址被分为2个域:
Directory 最高10位
Offset 其余22位
扩展分页和正常分页的页目录项基本相同,除了:
Page Size (CR4中标志位)标志必须被设置
20位物理地址字段只有最高10位是有意义的。这是因为每一个物理地址都是在以4MB为边界的地方开始的,故这个地址的最低22位为0
Linux中的分页
2.6.11开始采用了四级分页模型:
页全局目录(Page Global Directory)
页上级目录(Page UpperDirectory)
页中间目录(Page Middle Directory)
页表(Page Table)
PTRS_PER_PTE,PTRS_PER_PMD,PTRS_PER_PUD以及PTRS_PER_PGD
用于计算页表,页中间目录,页上级目录和页全局目录表中表项的个数。当PAE(CR4 寄存器标志位)被禁止时,它们产生的值分别为1024,1,1和1024。当PAE被激活时,产生的值分别为512,512,1和4。
注意:PAE关闭时,PGD就是PDT,此时不用PUD,PMD。虽然它们两个在线性地址中,但长度为0,2^0=1,也就是说,它们都是有一个数组元素的数组。当PAE启动时,PGD指示四个PDP
如果用一级分页,设定访问空间使4GB, 一个页4KB,一个entry 占4B,因此需要4GB/4KB = 1M条 entry , 每一个entry 是4B, 因此需要1M* 4B = 4MB ,因此需要4MB空间 来存储entry。
如果用两级分页,2^10*2^10*4KB=4GB ,因此需要entry 1M 条,因为采用了二级分页, 页中放entry (4KB页)/4B = 1024. 因此每个页1024 entry,因此需要两个页就可以了,两个页实际占用空间大小是4K+4K = 8KB。
linux 对页管理的数据结构(简单的数据类型,long ,这样设计的原因,防止使用出错) :
typedefstruct{ unsignedlong pte; } pte_t;
typedef struct{ unsignedlong pmd; } pmd_t;
typedef struct{ unsignedlongpgd[2]; } pgd_t;
typedef struct{ unsignedlongpgprot; } pgprot_t
1.linux 对分段的处理,没有进行分段处理。
DEFINE_PER_CPU_PAGE_ALIGNED(structgdt_page,gdt_page) = { .gdt= {
..............
[GDT_ENTRY_DEFAULT_USER_CS]=GDT_ENTRY_INIT(0xc0fa, 0,0xfffff),130 [GDT_ENTRY_DEFAULT_USER_DS]=GDT_ENTRY_INIT(0xc0f2, 0,0xfffff),
2.段描述符
段描述符:每个段由8位的段描述符表示,存放在GDT和LDT中,GDT和LDT在主存中的位置和大小存放在gdtr和ldtr寄存器中。
其中寄存器cr3用于存放当前进程正在使用的页目录基地址。dir用于指明目录项,table用于指明表项,offset用于指明页内偏移。8086处理器分页原理如下
页目录项和页表项有同样的结构;
它们都有4B共32b,具体布局如下
其中每个位的作用如下:
P--位0是存在(Present)标志,用于指明表项对地址转换是否有效。P=1表示有效;P=0表示无效。在页转换过程中,如果说涉及的页目录或页表的表项无效,则会导致一个异常。如果P=0,那么除表示表项无效外,其余位可供程序自由使用,如图4-18b所示。例如,操作系统可以使用这些位来保存已存储在磁盘上的页面的序号。
R/W--位1是读/写(Read/Write)标志。如果等于1,表示页面可以被读、写或执行。如果为0,表示页面只读或可执行。当处理器运行在超级用户特权级(级别0、1或2)时,则R/W位不起作用。页目录项中的R/W位对其所映射的所有页面起作用。
U/S--位2是用户/超级用户(User/Supervisor)标志。如果为1,那么运行在任何特权级上的程序都可以访问该页面。如果为0,那么页面只能被运行在超级用户特权级(0、1或2)上的程序访问。页目录项中的U/S位对其所映射的所有页面起作用。
A--位5是已访问(Accessed)标志。当处理器访问页表项映射的页面时,页表表项的这个标志就会被置为1。当处理器访问页目录表项映射的任何页面时,页目录表项的这个标志就会被置为1。处理器只负责设置该标志,操作系统可通过定期地复位该标志来统计页面的使用情况。
D--位6是页面已被修改(Dirty)标志。当处理器对一个页面执行写操作时,就会设置对应页表表项的D标志。处理器并不会修改页目录项中的D标志。
AVL--该字段保留专供程序使用。处理器不会修改这几位,以后的升级处理器也不会。
PAGE SIZE(CR4控制寄存器有该标志位)只用于页目录项,如果为1表示启用大页,2M或者4M
从pentium开始,8086处理器引入了扩展分页模式,它允许页框大小是4M而非4K,它用于把大段连续的物理地址转换成相应的物理地址。在这种情况下,内核不使用中间页表进行地址转换,进而节省内存并保留TLB项。扩展分页机理如下:
扩展分页的页目录项和普通分页基本相同,除了:
1)page size位必须被设置
2)20位物理地址字段只有高10位是有意义的
通过设置cr4处理器寄存器的PSE标志能使得拓展分页和常规分页共存。
3. 位系统中的分页
首先,32位下的分页机制不再适用。因为如果仍然是4K页,我们用48位线性地址来进行寻址,那么剩下48-12=36位,如果我们用其中的48位建立二级分页机制,那么每个进程的页目录项和页表项将含有2^18,太大了。
X86_64下,页大小是4K,寻址位数是48,分页级别是4,地址划分:9+9+9+9+12
4 TLB
TLB相当于页表的cache,每个cpu都有自己的TLB,与cache不同,TLB中的对应项不用同步,但是cpu的cr3寄存器发生修改的时候,表明当前运行进程发生了变化,此时要使得TLB所有项目无效。
5 控制寄存器CR0与CR3
控制寄存器(CR0~CR3)用于控制和确定处理器的操作模式以及当前执行任务的特性,CR0中含有控制处理器操作模式和状态的系统控制标志;CR1保留不用;CR2含有导致页错误的线性地址;CR3中含有页目录表物理内存基地址,因此该寄存器也被称为页目录基地址寄存器PDBR(Page-Directory
Base address Register)。
CR0中的保护控制位:
1)PE:CR0的位0是启用保护(Protection Enable)标志。当设置该位时即开启了保护模式;当复位时即进入实地址模式。这个标志仅开启段级保护,而并没有启用分页机制。若要启用分页机制,那么PE和PG标志都要置位。
2)PG:CR0的位31是分页(Paging)标志。当设置该位时即开启了分页机制;当复位时则禁止分页机制,此时所有线性地址等同于物理地址。在开启这个标志之前必须已经或者同时开启PE标志。即若要启用分页机制,那么PE和PG标志都要置位。
3)WP:对于Intel 80486或以上的CPU,CR0的位16是写保护(Write Proctect)标志。当设置该标志时,处理器会禁止超级用户程序(例如特权级0的程序)向用户级只读页面执行写操作;当该位复位时则反之。该标志有利于UNIX类操作系统在创建进程时实现写时复制(Copy on Write)技术。
当改变PE和PG位时,必须小心。只有当执行程序至少有部分代码和数据在线性地址空间和物理地址空间中具有相同地址时,我们才能改变PG位的设置。此时这部分具有相同地址的代码在分页和未分页世界之间起着桥梁的作用。无论是否开启分页机制,这部分代码都具有相同的地址。另外,在开启分页(PG=1)之前必须先刷新页高速缓冲TLB。
在修改该了PE位之后程序必须立刻使用一条跳转指令,以刷新处理器执行管道中已经获取的不同模式下的任何指令。在设置PE位之前,程序必须初始化几个系统段和控制寄存器。在系统刚上电时,处理器被复位成PE=0和PG=0(即实模式状态),以允许引导代码在启用分段和分页机制之前能够初始化这些寄存器和数据结构。
CR2和CR3
CR2和CR3用于分页机制。CR3含有存放页目录表页面的物理地址(注意,是物理地址!!!),因此CR3也被称为PDBR。因为页目录表页面是页对齐的,所以该寄存器只有高20位是有效的。而低12位保留供更高级处理器使用,因此在往CR3中加载一个新值时低12位必须设置为0。
使用MOV指令加载CR3时具有让页高速缓冲无效的副作用。为了减少地址转换所要求的总线周期数量,最近访问的页目录和页表会被存放在处理器的页高速缓冲器件中,该缓冲器件被称为转换查找缓冲区(Translation Lookaside Buffer,TLB)。只有当TLB中不包含要求的页表项时才会使用额外的总线周期从内存中读取页表项。
即使CR0中的PG位处于复位状态(PG=0),我们也能先加载CR3。以允许对分页机制进行初始化。当切换任务时,CR3的内容也会随之改变。但是如果新任务的CR3值与原任务的一样,处理器就无需刷新页高速缓冲。这样共享页表的任务可以执行得更快。
CR2用于出现页异常时报告出错信息。在报告页异常时,处理器会把引起异常的线性地址存放在CR2中。因此操作系统中的页异常处理程序可以通过检查CR2的内容来确定线性地址空间中哪一个页面引发了异常。