关闭

Linux下的地址映射

标签: Linux内存管理
83人阅读 评论(0) 收藏 举报
刚刚开始写博客,怕自己忘记,同时有些专业错误也请大家指正。
在这里我讲一些,在Linux下的地址映射,首先说一下实模式下的地址映射,实模式简单的说就是没有操作系统的模式,在实模式下,不区分用户态与内核态,因为此时还没有操作系统,主要是指在8086之前的计算机,8086的数据总线是16位,地址总线是20位,因此它有效的寻址空间是2^20,即1M,在8086里面有4个寄存器,CS,代码段寄存器,DS,数据段寄存器,SS(ES),堆栈段寄存器,我们的物理地址=段基址+逻辑地址/偏移地址,这里的段基址值指,在段寄存器里面的值,但是我们需要知道的是,在8086里面规定每个内存段的起始地址为16的倍数,也就是说段基址的低4位一定为0,因此,在8086的设计中,寄存器并没有保存它低4位的值,因此在计算的时候,我们需要将段基址左移4位,之后即可得到真实的物理地址。

由于实模式这样的设计并不安全,因为我们并不知道,内存的访问权限,内存的大小,很有可能一不小心就越界,因此在80386之后,采用了保护模式下的地址映射,在保护模式下,新增了寄存器,GDTG,全局段描述符表,LDTR,局部段描述符表,在GDTR里面存放了GDT的地址,而GDT相当于一个存放内存信息的数组,在GDT里面存放的数组信息包括内存的起始地址,内存段的大小,以及内存的访问权限等信息,而之前8086里面已经存在的寄存器也没有消失,只是它不再存放段基址,它存放GDT的索引,即下标,在80386中,段寄存器的低两位为RPL,表示内存的权限,00为最高全校,也即内核态,01表示用户态,最低权限,次低位为TL,表示在这里用的是什么段描述符,0 为GDTR,1为LDTR,因此段寄存器还剩下13位,这里的13位可以表示对的数字为8192,但是在系统内部已经有12个数字已用,因此,8180个数字表示GDT和LDT的数组下标,GTD结构如下:

这里的G如果为0;表示是按照字节,也即1M*1=1M;为1表示是按照页面,4K*1M=4G,也即总共的内存大小为4G,32位操作系统分配给每一个进程的虚拟地址空间为4G,其中前3G为用户空间,高的3-4G为内核空间,我们的段页式管理,计算物理内幕内存的时候,在分段管理模式下,GTD[ds<<3].base address+逻辑地址=线性地址,为什么要将寄存器的值左移三位呢,因为前面已经提到了,寄存器的低三位保存了一些信息,只有高13位才保存我们GTD的下标值,因此需要左移,在得到线性地址的情况下,如果没有开启内存分页,则这里的线性地址就是物理地址,如果开启了分页机制,我们还需要进行多级页表映射才能得到物理地址。

通过CR0寄存器的PG为可以查看是否开启了分页机制,CR2寄存器为我们提供发生缺页异常时的虚拟地址,CR3保存当前页目录的其实地址,CR4可以通过PAE查看是否开启了物理地址扩展。在进行多级页表映射时是这样做的,在CR3寄存器中存放的是当前进程的其实地址,它的高10位为PG,次高10位为页表,低12位为物理页面的偏移量,通过页目录查询页表,通过页表查询物理内存。

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:162次
    • 积分:20
    • 等级:
    • 排名:千里之外
    • 原创:2篇
    • 转载:0篇
    • 译文:0篇
    • 评论:0条
    文章存档