Chinaunix首页 | 论坛 | 博客
  • 博客访问: 258889
  • 博文数量: 52
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 277
  • 用 户 组: 普通用户
  • 注册时间: 2016-06-09 10:57
文章分类

全部博文(52)

文章存档

2016年(52)

我的朋友

分类: LINUX

2016-09-04 21:26:30

        在说Linux的内存管理之前,先说一下X86的内存管理方式。

        16位的CPU内部拥有20位地址总线,它的寻址范围是2的20次方,也就是1M的内存空间,数据总线却有16位,16位CPU用于存放地址的寄存器(IP,SP ......)只有16位,因此能有访问65535个存储空间,也就是64K。为了能够访问1M的存储空间,CPU采用了内存分段的管理模式,并在CPU内部加入了段寄存器,16位CPU把1M的空间分为若干个逻辑段,每个逻辑段的起始地址(段地址)必须是16的倍数,即最后4个二进制位必须全为0,逻辑段的最大容量为64K。
        逻辑地址= 段基地址+段内偏移量  由逻辑地址得到物理地址的公式为:PA=段寄存器的值 x 16(得到基址) + 逻辑地址(乘以16是因为16位的寄存器存的是20位的地址,由上知最后4位为0,所以存的时候不存,即只存高16位,也就相当于左移4位,所以计算时需要右移4位,也就是乘以16

        下面来说一下逻辑地址,线性地址,物理地址,和虚拟地址的区别:

        线性地址:是逻辑地址到物理转换的中间层,连续的,不分段的0~4G的地址空间(有时也称为虚拟地址)。

        物理地址:也就是实际地址,就是地址总线所访问的地址。

        逻辑地址:(也叫相对地址)按Intel说的定义是由一个段标识符加上一个指定段内的相对地址偏移量(也可以理解成代码中去地址符号后得到的地址)。例如变量A的地址为0x80000000,则A的逻辑地址为【A的段代码标识符:0x80000000】

        不同的逻辑地址可以映射到相同的线性地址上(因为段的基址不同),不同的线性地址也可以映射到相同的物理地址上(因为所使用的页目录和页表不同),多是多对一的关系。

        CPU为32位时,分为实模式和保护模式,实模式时和16的CPU 是一样的,而保护模式采用的分段机制和分页机制。

        从逻辑地址到线性地址的转换过程为:首先从段选择符寄存器中找到相应的段描述符的索引,然后从段描述符中读出相应的段的基址和偏移量。
                        段的基址(放在段的基址寄存器中)+偏移量= 线性地址

        从线性地址到物理地址的转换过程为:(若没有启动分页机制则线性地址就是物理地址)从CR3寄存器(进程运行时操作系统自动把页目录地址存到CR3寄存器中)取出页目录地址
                        CR3中取出的页目录地址 + 线性地址的最高10位[31 :22] = 页表地址 
                        页表地址 + 线性地址的中间10位[21 : 12] = 物理页的起始地址
                        物理页的起始地址 + 最后12的偏移地址 = 物理地址
图形如下:
                    

     采用的是二级管理模式:即页目录表中项不是页的地址,而是页表的地址,还有采用三级管理模式,四级管理模式的,此时的线性地址就不是32位了,而是64位。分页的大小有64K的,有4k的,也有极小页1k的,当以4K分页时,4GB=4k x 220次方,也就是有220次方个页,至于为什么可以覆盖4G的线性地址空间的计算过程为:页目录中有210次方个页表(线性地址的最高10位),而一个页表中有210次方个也(中间10位),一个页中又有212次方个偏移地址,所以连乘后刚好为4G

        
        物理的地址的分页的大小和页的分页大小是一样的,段的长度不是固定的,页的长度是固定的。

        最后说一下Linux的内存管理:Linux的内存管理可以说是完全的分页管理机制,页可以说是有限的采用了分页管理机制,因为所有的段的基址都是0,由此得出每个段的逻辑地址空间范围都是0~4G,因此逻辑地址与线性地址保持一致(即逻辑地址偏移量的字段的值总是与线性地址是一样的),在Linux中提到的逻辑地址(相对地址)和线性地址(虚拟地址)可以认为是一样的,看来Linux巧妙的把分段机制给避过去了,完全采用分也地址,说有限的采用时所有段的机制都是0.

        Linux的页式地址管理图如下:
            


        Linux把虚拟地址空分为两部分,用户地址空间和内核地址空间,从0~0xbfffffff为用户地址空间,3G到4G为内核地址空间,




阅读(1258) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~