80x86处理的三种内存地址:logical address逻辑地址(segment + offset) -> [segment unit分段单元] -> linear addresss线性地址(又叫virtual address虚拟地址) -> [paging unit分页单元] -> physical address物理地址
[方括号内的组建属于硬件电路]
memory arbiter内存仲裁器,介于总线和RAM之间,用于判断串行读写的RAM此时能否被访问。
逻辑地址=16位的段选择符(segment selector)+32位偏移量(offset)
段选择符存放于6个段寄存器里:
cs (code segment) 代码段寄存器,它含有一个2bit字段,指明CPL(current privilege level),0=内核态,1=用户态。
ss (stack segment) 栈段寄存器
ds (data segment) 数据段寄存器
es (extra segment) 附加段寄存器和fs, gs (按字母排序) 可存储任意数据段。
分段寻址方式:
8位的段选择符指定64位的段描述符,逻辑地址的偏移量 + 段描述符的Base字段 = 虚拟地址
运行在用户态的所有Linux进程都使用相同的一对用户代码段和用户数据段来对指令和数据寻址。
运行在内核态的所有Linux进程都使用相同的一对内核代码段和内核数据段来对指令和数据寻址。
Linux所有段都从0x00000000开始,偏移量字段的值 = 虚拟地址的值
GDT(Global Descriptor Table) 全局描述符表,每个CPU对应yi ge
LDT(Local Descriptor Table) 局部描述符表
控制寄存器
CR0:含有控制处理器操作模式和状态的系统控制标志
CR1:保留不用
CR2:含有导致页错误的线性地址
CR3:含有页目录表物理内存基地址,又被称为Page-Directory Base address Register页目录基地址寄存器
分页寻址方式:
通常的页设置为4K大小,32位的线性地址被分为2级3个域:页目录域(Directory 10bit) + 页表域(Table 10bit) + 偏移量(Offset 12bit)。
通用的64位线性地址分页级别是使用48bit寻址,分4级:Page Global Directory(9bit) + Page Upper Directory(9bit) + Page Middle Directory(9bit) + Page Table(9bit) + Offset(12bit)。
目前的Linux对于32位一样采用该通用4级模型:10 + 0 + 0 + 10 + 12。不过,页上级目录和页中间目录在指针序列中的位置被保留,以便兼容32bit和64bit。
关于高速缓存cache
虽然每个页目录项和页表项都包含两个标志:PCD(Page Cache Disable), PWT(Page Write-Through),Linux清除该标志,对所有页框都启用高速缓存,对写操作总是采用回写策略。