IA-32/Linux按字节编址;在保护模式下,IA-32采用段页式虚拟存储管理方式,存储地址采用逻辑地址、线性地址和物理地址来进行描述。
逻辑地址由48位组成,包含16位段选择符(高13位为段表项的index)和32位段内偏移量(有效地址=基址寄存器+变址寄存器×比例因子+偏移量),通过段描述符取到段表中的对应段表项的段基址,加上有效地址得到线性地址(位数由虚拟地址空间大小决定)。
PS:逻辑地址和线性地址是虚拟地址的两种不同表示形式,描述的都是4GB虚拟地址空间中的一个存储地址。
最后通过分页方式转换为物理地址(位数由存储器总线的地址线条数决定)
 
逻辑地址向线性地址的转换:
6个16位段寄存器,用于存放段选择符
CS(代码段):程序代码所在段
SS(栈段):栈区所在段
DS(数据段):全局静态数据区所在段
其他3个辅助段寄存器ES、GS和FS可指向任意数据段
TI=0,选择全局描述符表(GDT);TI=1,选择局部描述符表(LDT)
每个段寄存器都有一个RPL字段(Request Privilege Level),说明的是进程对段访问的请求权限。
RPL是当前程序段的特权等级,Linux只用了0级和3级:RPL=00,为第0级,位于最高级的内核态;RPL=11,为第3级,位于最低级的用户态。当前CPL=0的进程要访问一个数据段,它把段选择符中的RPL设为3,这样它对该段仍然只有特权为3的访问权限。
CS寄存器中的RPL字段表示CPU的当前特权级(Current Privilege Level,CPL)
高13位索引用来确定当前使用的段描述符在描述表(段表)中的位置,即段表项的index
段描述符实际就是段表项,分两类:
  • 普通段:用户/内核的代码段和数据段描述符
  • 系统控制段描述符,又分两种:
  1. 特殊系统控制段描述符,包括:局部描述符表(LDT)描述符和任务状态段(TSS,每一个进程的状态描述信息)描述符
  2. 控制转移类描述符,包括:调用门描述符、任务门描述符、中断门描述符和陷阱门描述符(门:中断服务程序的首地址)
每项段描述符共64位,包括:
B31~B0: 32位基地址; 
L19~L0:20位限界,表示段中最大页号
G:粒度。G=1以页(4KB)为单位;G=0以字节为单位。因为界限为20位,故当G=0时最大的段为1MB;当G=1时,最大段为4KB×2^20 =4GB
D:D=1表示地址和数据(段内偏移量)为32位宽,D=0表示16位宽
AVL:由操作系统定义使用,Linux未使用
P:P=1表示存在于主存,P=0表示不存在。Linux总把P置1,不会以段为单位淘汰
DPL:访问段时对当前特权级CPL的最低等级要求。即,只有CPL为00时才可访问DPL为00的段,任何进程都可访问DPL为11的段
S:S=0系统控制描述符,S=1普通的代码段或数据段描述符
TYPE:段的访问权限或系统控制描述符类型
A:A=1已被访问过,A=0未被访问过。(通常A包含在TYPE字段中,相当于脏位)
 
描述表实际就是段表,有三种类型:
  • 全局描述符表GDT:只有一个,用来存放系统内每个任务共用的描述符,例如,内核代码段、内核数据段、用户代码段、用户数据段以及TSS(任务状态段)等都属于GDT中描述的段
  • 局部描述符表LDT:存放某任务(即用户进程)专用的描述符
  • 中断描述符表IDT:包含256个中断门、陷阱门和任务门描述符
为支持分段机制,CPU中有多个用户不可访问的内部寄存器,操作系统通过特权指令可对寄存器TR、LDTR、GDTR和IDTR进行读写
每次段寄存器装入新选择符时(例如更换进程的时候CS换新段选择符),新描述符装入描述符cache,在逻辑地址到线性地址转换时,MMU直接用描述符cache中的信息,不必访问主存段表
TR(任务寄存器)存放TSS描述符的段选择符;LDTR(LDT寄存器)存放LDT描述符的段选择符 
PS:复习的时候注意段选择符和段描述符的区别。TR和LDTR放的是TSS描述符和LDT描述符的段选择符。TSS描述符和LDT描述符在GDT中。
GDT和IDT首地址、限界放在GDTR和IDTR中
 
举例:Linux中的全局描述符表(GDT)
如TSS和LDT的段选择符分别为0x88和0x80:
TR放了0x80,RPL=0,说明TR所指段TSS处于第0环;TI=0,其描述符在GDT中;索引值为0x0010,是第16项
LDTR放了0x88,RPL=0,说明LDTR所指段LDT处于第0环;TI=0,其描述符在GDT中;索引值为0x0011,是第17项
 
图中,其实只有第一次需要去GDT表中找段描述符,后来就去Cache中找了。
 
Linux为了移植到RISC处理器,简化了分段机制,在初始化时将所有段描述符的基址设为0来简化,每个段都被初始化在0~4GB的线性地址空间中。线性地址就是有效地址。
P必定为1
GDT的第12-15表项分别是内核代码段、内核数据段、用户代码段、用户数据段。每个段描述符8B。
因此执行内核代码的时候,CS里总是0x60,DS里总是0x68,以及最后三位000
执行用户程序的时候,CS里总是0x73,DS里总是0x7b,以及最后三位011
 
线性地址向物理地址的转换:
控制寄存器保存机器的各种控制和状态信息,它们将影响系统所有任务的运行,操作系统进行任务控制或存储管理时使用这些控制和状态信息。
  • CR0:控制寄存器
① PE:1为保护模式。一旦在保护模式,不能再将PE清0,只能重启系统以回到实模式。
② PG:1为启用分页;0为禁止分页,此时线性地址被直接作为物理地址使用。
若要启用分页机制,则PE和PG都要置1。
③ 任务切换位TS:任务切换时将其置1,切换完毕则清0,可用CLTS指令将其清0。
④ 对齐屏蔽位AM。AM=0则禁止对齐检查;AM=1且EFLSGS的AC=1则进行对其检查
⑤ cache功能控制位NW(Not Write-through)和CD(Cache Disable):只有当NW和CD均为0时,cache才能工作。
  • CR2:页故障(page fault)线性地址寄存器
存放引起页故障的线性地址。只有在CR0中的PG=1时,CR2才有效。 
  • CR3:页目录基址寄存器
保存页目录表(第一级页表)的起始地址。只有当CR0中的PG=1时,CR3才有效。
IA-32采用两级页表方式:
4GB=1K个子空间×1K个页面/子空间×4KB/页
32位线性地址:1K个页目录项,通过10位页目录索引找到;每个页表1K页表项,通过10位页表索引找到;每页4KB,通过12位页内偏移量找到。
P:1表示页表或页在主存中;P=0表示页表或页不在主存,即缺页,此时需将页故障线性地址保存到CR2。
R/W:0表示页表或页只能读不能写;1表示可读可写。
U/S:0表示用户进程不能访问;1表示允许访问。
PWT:控制页表或页的cache写策略是全写(Write Through)还是回写(Write Back)。
PCD:控制页表或页能否被缓存到cache中。
A:1表示指定页表或页被访问过,初始化时OS将其清0。利用该标志,OS可清楚了解哪些页表或页正在使用,一般选择长期未用的页或近来最少使用的页调出主存。由MMU在进行地址转换时将该位置1。
D:脏位dirty bit。第一级页表页目录项中的脏位无意义,只在第二级页表页表项中有意义。初始化时OS将其清0,由MMU在进行写操作的地址转换时将该位置1。
高20位是页表或页在主存中的首地址对应的页框号,即首地址的高20位。每个页表的起始位置都按4KB对齐。
举例:IA-32/Linux中,执行“movl 8(%ebp), %eax”时,源操作数的逻辑地址向线性地址转换的过程如下:
(1)若CPL>DPL则越级,否则计算有效地址EA=R[ebp]+0×0+8
(2)取出段寄存器DS对应的描述符cache中的段基址(Linux中段基址为0)
(3)线性地址LA=段基址+EA=EA,若LA>段限则越界(Linux肯定不会,段限是全1)
(4)将LA转换为主存地址A
-    若访问TLB命中则地址转换得到A;否则处理TLB缺失(硬件/OS)
-    若缺页或越权(R/W不符)则调出OS内核;否则地址转换得到A 
-    根据A先到Cache中找,若命中则取出A在Cache中的副本 
-    若Cache不命中,则再到主存取A所在主存块送对应Cache行
 
Intel Core i7的线性地址转换:
 
页表变为了4级页表,每级虚页号9位。
进程切换时,从mm结构的pgd获得进程对应第一级页表的首地址放入CR3。
虚拟地址VA变为了48位。其中虚页号36位,页内偏移量12位。物理地址可以远大于虚拟地址。
页表项PTE从32位4B变为了64位8B。因此项数从1024变为了512。
显存不需要地址转换。

操作系统-存储管理(5)IA-32/Linux的地址转换的更多相关文章

  1. 用crash tool观察ARM64 Linux地址转换

    初学者学习Linux系统地址转换时,如果只是学习理论,又或者研读代码,那可能感觉比较枯燥.此时如果可以利用某些工具实际观察一下地址转换的过程,那可能会给枯燥的内核学习带来些微的乐趣.crash too ...

  2. Tomcat Can't load AMD 64-bit .dll on a IA 32

    Java.lang.UnsatisfiedLinkError: C:\apache\apache-tomcat-7.0.14\bin\tcnative-1.dll: Can't load AMD 64 ...

  3. 操作系统-存储管理(3)高速缓存Cache

    存储器的组织形式: 数据总是在相邻两层之间复制传送,最小传送单位是定长块,互为副本(不删除) ️指令和数据有时间局部性和空间局部性.   高速缓冲存储器Cache 介于CPU和主存储器间的高速小容量存 ...

  4. Linux 网络编程详解一(IP套接字结构体、网络字节序,地址转换函数)

    IPv4套接字地址结构 struct sockaddr_in { uint8_t sinlen;(4个字节) sa_family_t sin_family;(4个字节) in_port_t sin_p ...

  5. 01-Coredump核心转存&&Linux程序地址分析【转】

    转自:http://www.itwendao.com/article/detail/404132.html 目录(?)[-] 一Core Dump核心转存 二Linux程序地址分析 一Core Dum ...

  6. TCP/IP中32位IP地址与字符串转化

    转载:http://www.cnitblog.com/wujian-IT/archive/2007/10/11/34739.aspx 在网络上面我们用的IP都是数字加点(192.168.0.1)构成的 ...

  7. ARM中MMU地址转换理解

    首先,我们要分清ARM CPU上的三个地址:虚拟地址(VA,Virtual Address).变换后的虚拟地址(MVA,Modified Virtual Address).物理地址(PA,Physic ...

  8. OpenRisc-31-关于在设计具有DMA功能的ipcore时的虚实地址转换问题的分析与解决

    引言 之前,我们在讨论基于ORPSoC的ipcore设计时提到过DMA的问题,当时我们实现DMA的功能时,访问的是local memory,并没有使用主存(即外部的SDRAM),使用的是本地的一块存储 ...

  9. UNIX网络编程——socket概述和字节序、地址转换函数

    一.什么是socket socket可以看成是用户进程与内核网络协议栈的编程接口.socket不仅可以用于本机的进程间通信,还可以用于网络上不同主机的进程间通信. socket API是一层抽象的网络 ...

随机推荐

  1. 理解k8s资源限制系列(二):cpu time

    本文介绍几种在K8S中限制资源使用的几种方法. 资源类型 在K8S中可以对两类资源进行限制:cpu和内存. CPU的单位有: 正实数,代表分配几颗CPU,可以是小数点,比如0.5代表0.5颗CPU,意 ...

  2. Salt组件(一)

    一.管理对象属性(Grains) Grains里面记录着每台Minion的一些常用属性,比如CPU.内存.磁盘.网信息等,我们可以通过grains.items查看某台Minion的所有Grains信息 ...

  3. Java数据结构和算法(2)之稀疏数组

    1.定义 稀疏数组可以看做是普通二位数组的压缩,但是这里说的普通数组是值无效数据量远大于有效数据量的数组,关于稀疏数组的运用有五子棋盘,地图等.. *当一个数组中大部分元素为0,或者为同一个值的数组时 ...

  4. MacOS下Lucene学习

    学于黑马和传智播客联合做的教学项目 感谢 黑马官网 传智播客官网 微信搜索"艺术行者",关注并回复关键词"lucene"获取视频和教程资料! b站在线视频 全文 ...

  5. Python break语句

    Python break语句:当运行到 break 语句时,终止包含 break 的循环语句. 注:无论判断条件是否达到 False 或 序列是否遍历完都会停止执行循环语句和该 break 下的所有语 ...

  6. nonlocal 访问变量

    def counter(start = 0): def incr(): nonlocal start #分别保存每一个变量的临时值.类似yield start += 1 return start re ...

  7. 线程_ThreadLocal

    import threading # 创建ThreadLocal对象 house = threading.local() def process_paper(): user = house.user ...

  8. EF Code First数据库模型及属性约束

    1.今日完成任务 数据库实体的创建 实体属性约束的添加 实体之间关系的添加 2.核心代码 EF模型 属性约束及实体之间的关系 使用FlutAPI对模型进行修正 3.遇到的问题及解决方案 最主要的是联合 ...

  9. RocketMQ文章

    实战:RocketMQ削峰,这一篇就够了    https://juejin.im/post/5ea159e4f265da47f0794da5

  10. 无版号的ios手游下架 TF签名才是正确选择?

    2020年8月1日开始,无版号的ios手游就要全部下架appstore了,在这样关键的时刻,TF签名成了ios手游的最后一根救命稻草.因为被下架或者根本无法通过appstore的上架审核,ios手游的 ...