Linux 下地址映射过程总结

CPU上电强制进入实模式
实模式下 访问地址 DS<<4 + ip = 物理地址
主要的段寄存器有
DS:数据段
SS:堆栈段
CS:代码段
ES:扩展段
GS:全局段
IP:偏移量

实模式下访问内存是极其不安全的,我们访问内存时,不仅要知道内存段的起始地址,还需要知道内存段大小和访问权限。但是这些信息没有办法都存在16位的段寄存器中,从80386开始,有了保护模式,又增加了几个寄存器,为了解决信息没有办法都存在16位的段寄存器中的问题,GDTR和LDTR。
GDTR 指向了 GDT 全局描述附表
LDTR 指向了 LDT 局部描述符表
GDT是一个数组 全局的段描述表
如图这里写图片描述
这时段寄存器不在用于存放地址的去掉后4位(因为之前内存段的起始地址总是4k整数倍,因此后四位都为0),而用于存放段描述表的索引。

比如想要访问数据段的地址,DS存放的是数据段在GDT中对应的下标。
这里写图片描述

其中8192个描述符中12项被系统预留下来了 因此8192 - 12 = 8180 个描述符
内核代码(12个预留项):
这里写图片描述

因此保护模式下 内存分段的地址映射
GDT[DS>>3].BaseAddr + IP(逻辑地址,加前要与Length比较) = 线性地址
若没有开启分页机制 线性地址 == 物理地址
若开启分页机制 线性地址 == 虚拟地址
需要多级的页表映射 虚拟地址才能转化到====》 物理地址

那么接下来通过bochs对简单程序的调试来熟悉Linux32位系统的二级映射过程
程序源码:

#include <stdio.h>

int main()
{
int data = 10;
pritnf("&data = 0x%x\n",&data);
whlie(data);
printf("progrma done...\n");
return 0;
}

可见,程序运行期间,会在while函数体内不断循环
在不改变代码的前提下,通过二级映射,访问data的物理内存,修改为0
即可结束程序
这里写图片描述
sreg指令可以看到段寄存器的信息
data是局部变量,因此ss寄存器的内容是映射的关键

LDTR内容:0x0068
二进制形式展开 0000 0000 0110 1(序号13) 0(GDT) 00(内核态)
说明LDT在GDT 13位存着
找到GDT的第13号元素内容
这里写图片描述
得到:0xe2d00068 0x000082fa
需要注意是小端模式,对应段描述符表项的定义 得到地址0x00fae2d0 (LDT的起始地址)
SS内容 :0x0017
二进制形式展开 0000 0000 0001 0 (序号2) 1(LDT) 11(用户态)
说明详细信息在LDT[2]
这里写图片描述
得到:0x00003fff 0x10c0f300(data栈内存的详细信息)
对应段描述符表项的定义,0x10000000栈内存起始地址
加上程序打印出的虚拟地址0x10000000+0x3fffef4 得到线性地址

此时分段映射结束


通过creg指令查看CR0的最高PG位 查看有没有开启分页式管理

ps.
CR0 最高PG位 0表示没有开启分页机制 1表示开启
CR2 发生缺页异常的虚拟地址
CR3 页目录的虚拟地址
CR4 PAE位物理地址扩展 0未开启 1开启

这里写图片描述
CR0 8=》1000 最高位为1 开启内存分页

将我们线性地址0x 13fffef4 拆分为10 10 12
这里写图片描述

0001001111 1111111111 111011110100‬ 二进制数
79 1023 3828 对应数值

这里写图片描述

得到页目录地址0x00fea027
前20位有效=》0x00fea000
(为什么说前20位有效呢,PT起始地址为4K的整数倍,因此32位地址的低12位都为零,可以不用存储,用来存取其他内容,如访问权限等等,特别指出 pt的最后一位是present位,0代表对应的物理页面在交互分区中,1代表对应的物理页面不在交互分区中,这又牵扯到了swap分区了,后几期会专门写一篇理解)

这里写图片描述

得到页表地址0x00f94067

前20位有效=》0x00f94000
这里写图片描述
得到data映射到物理内存的地址
值为a == 10

这里写图片描述
通过setpmem语句 将data对应的物理地址设置为4字节的0
从而data = 0;
continue程序
对应while判断为false
退出程序
这里写图片描述

到这该死的地址映射过程就算完成了。。。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值