在保护模式下,IA32采用段页式虚拟内存管理,即先分段再分页。地址的类型有以下三种:

  • 逻辑地址(48bit)
  • 线性地址(32bit)
  • 物理地址

由逻辑地址转化为线性地址由分段过程完成,由线性地址转化为物理地址由分页过程完成。

逻辑地址向线性地址的转化

48bit的逻辑地址可分为16位的段选择符和32位的段内偏移量(也即有效地址EA,汇编指令中给出的地址),比如对于这样一条采用基址+比例变址+偏移量寻址的汇编指令:movw 8(%ebp, %ebx, 4), %ax,其给出的就是32位的段内偏移量=8+[%ebp]+[%ebx]*4

首先总的看一下从逻辑地址到线性地址的转换过程:

由段寄存器中存储的段选择符找到段表(段描述符表)中的段表项(段描述符),该段表项给出了该段的段基址,再加上指令中的有效地址EA就得到了最终的线性地址

回顾一下IA32的寄存器组织:

6个16位的段寄存器存储了一个段选择符

  • TI=0,使用全局描述符表GDT
  • TI=1,使用局部描述符表LDT
  • 高13位的索引指向段描述符表(段表)中的一个段描述符(段表项)

代码段寄存器CS的最低两位RPL就指明了当前执行代码的特权级,IA32采用环保护的方式:0表示内核,3表示用户

段描述符和段描述符表的分类:


段描述符的结构:

  • B31~B0为基地址
  • L19~L0为限界
  • G(granularity)为粒度,G=1表示段以页为基本单位,此时最大段长4GB;G=0表示以字节为基本单位,此时最大段长1MB
  • D=1表示32位宽数据,D=0表示16位宽数据
  • P=1表示段是否已经在主存中,Linux总是把P置1,因为它从不把一个段置换到磁盘,而是以页为单位交换的
  • DPL表示访问该段的最低特权级要求
  • S=0表示系统控制描述符,S=1表示普通代码段或数据段描述符
  • A=1表示该段已经被访问过,A=0表示未被访问过

逻辑地址向线性地址的转换:

  1. 首先根据段选择符中的TI位确定使用GDT(0)还是LDT(1)
  2. 然后使用段选择符中的13位的索引,找到段描述符,GDT的基址由GDTR获得,LDT的基址由LDTR获得
  3. 从段描述符中取出32位的基址B31~B0,与逻辑地址中的EA相加,得到32位的线性地址

考虑到对RISC机器的支持(RISC对分段的支持有限),Linux对IA32的分段机制做了简化,它将所有段描述符的基地址全部设为0,每个段的段内地址空间大小都是4GB,所以,所有逻辑地址中的段内偏移量(EA)就是其线性地址。相当于仅启用了分页机制,而对分段机制进行了简化(所以前面一堆白学)

线性地址向物理地址的转化

这个过程就比较简单了,首先根据控制寄存器CR3找到当前进程的页目录表基址,然后根据线性地址的最高10位作为页目录索引页目录表中找到对应的页目录项,该页目录项指向了一个页表基址,然后根据线性地址的中间10位作为页表索引页表中找到页表项,该页表项指向了一个物理页框,将该物理页框拼接上线性地址最低12位的页内偏移就得到了最终的物理地址

页目录项和页表项的结构:

  • P=1表示该页表或页在内存中;否则发生了缺页故障,需要将页故障线性地址记录在CR2中,由OS处理页故障
  • R/W=0表示该页只读,否则表示读写
  • U/S=0表示用户进程不可访问该页,可以保护操作系统的页不会被用户进程破坏
  • PWT指明该页的cache写策略,write throuhg OR write back
  • PCD表示cache允许位,控制该页能否被缓存到cache中
  • A=1表示该页被访问过,供页面替换算法参考
  • D脏位,表示该页是否被修改过
  • 高20位就是页表或页在主存中首地址对应的页框号

所以,一条取数指令的大致流程如下:

进程切换时,OS是如何找到当前进程的页目录表基址并将其装入CR3中的呢?一个很自然的想法就是将页目录表基址保存到task_struct中:

IA32-Linux地址转换过程相关推荐

  1. WinDbg演示IA-32 CPU下的Windows 分页机制下的地址转换过程

    今天在学习<软件调试>的时候,练习虚拟地址转物理地址的时候遇到了一个问题.用windbg本地调试内核功能时,!dd无法使用 用windbg命令dd的时候出现了以下错误: kd> !d ...

  2. 【翻译】【linux设备驱动】linux地址类型

    [翻译][linux设备驱动]linux地址类型 Linux中使用的地址类型列表: 用户虚拟地址(User virtual addresses) 用户空间程序可见的普通地址.用户虚拟地址的长度为32位 ...

  3. NAT(NAPT)地址转换过程

    整理自NAT地址转换过程 注:本文实质讲的是NAPT(Network Address Port Translation),即网络端口地址转换.NAPT与动态地址NAT不同,它将内部连接映射到外部网络中 ...

  4. 地址随机化 linux,GOT覆盖和Linux地址随机化

    8种机械键盘轴体对比 本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选? 原理由于GOT表是可写的,把其中的函数地址覆盖为我们shellcode地址,在程序进行调用这个函数时就会执行shellc ...

  5. Python在Linux地址已在使用,python在linux下的使用

    1.查看python(解释器)的版本(什么版本的解释器支持哪一版版的语言标准) 一般在linux上已经预装了python,只要在Bash Shell中输入python,即可看到如下版本信息: 按Ctr ...

  6. c语言段页式存储地址转换,页式存储和段页式存储的地址转换过程

    一.页式存储-地址转换 访问2次内存,第一次是页表,第二次是真正的物理内存. 二级页表,访问3次内存 两个例子的形式讲解逻辑地址到物理地址的转换: (1) 页系统页表 : 页号: 0 1 2 3 4 ...

  7. 上海linux地址,Linux

    2018年重新捡起PHP,把博客从ASP平台的ZBlog转为WordPress,2019年弄了个VM虚拟机玩了一下CentOS的Linux系统,但弄虚拟机有点麻烦,下载CentOS安装包,安装到VM, ...

  8. linux 地址重定向,Linux重定向(输入输出重定向)详解

    我们知道,Linux 中标准的输入设备默认指的是键盘,标准的输出设备默认指的是显示器.而本节所要介绍的输入.输出重定向,完全可以从字面意思去理解,也就是: 输入重定向:指的是重新指定设备来代替键盘作为 ...

  9. linux地址virbr0,命令行如何修改KVM生产的virbr0的地址

    前言 kvm默认生成的网段是192.168.122.0/24.假如内网已经有了一个网段192.168.122.0/24,这个时候就需要进行修改.而我秉着学习的态度来学习修改. 了解virbr0的配置文 ...

最新文章

  1. FPGA之道(71)提高设计的综合性能(三)提高设计的重用性与易改性
  2. OpenCV基本绘图
  3. 【数据可视化应用】绘制极坐标(附Python代码)
  4. 分布式系统之通信技术学习
  5. Spring+Hibernate+SpringMVC+MySql实现配置多个数据源!
  6. 好程序员前端分享使用JS开发简单的音乐播放器
  7. flux_Flux建筑模式简介
  8. 04. Django基础:路由配置
  9. 项亮《推荐系统实践》读书笔记1-推荐系统评价指标
  10. c语言串口通信实验报告,单片机串口通信实验报告总结
  11. java pos58打印_POS58小票打印机
  12. Oracle-11g数据库安装教程
  13. mac 虚拟打印机:
  14. LSUN数据集读取和解压,mdb格式转换为jpg格式(保姆教程)
  15. 技术分享 | Frida 实现 Hook 功能的强大能力
  16. 在使用缓冲流时,遇到Stream closed异常提醒
  17. python实现MACD策略背离点的判断
  18. 1521端口已被占用解决方案
  19. 幂函数的c语言程序,C ++中的幂函数
  20. 解决Graphviz无法显示决策树中文问题

热门文章

  1. CSS字体颜色滚动渐变动画
  2. 自动驾驶控制算法——老王Carsim_Simulink环境搭建步骤
  3. OJB Connection
  4. 《蹭课神器》Beta版使用说明
  5. PHP数据库操作类ADODB 详解
  6. java word导出带背景_Java 用Freemarker完美导出word文档(带图片)
  7. Android-Dex分包最全总结:含Facebook解决方案,移动app开发
  8. ssm+jsp计算机毕业设计CheatEngine学习系统4i3k0(程序+LW+源码+远程部署)
  9. 将tensor转换为image
  10. 二次验证码小程序与谷歌身份验证器不同点是?