免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 841 | 回复: 0
打印 上一主题 下一主题

linux的内存寻址 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-08-16 23:05 |只看该作者 |倒序浏览
以下内容摘自陈莉君的《linux操作系统与应用》
内存寻址
硬件发展:
  Intel公司第一个16位处理器8086,标志着Intel x86王朝的开始,也是内存寻址方式的一次飞跃。第一次引入了段的概念。它的寻址目标是1MB,地址总线扩展到了20位,可是ALU的宽度,也就是数据总线还只有16位,也就是说可以直接加以运算的指针长度是16位,于是设置了段寄存器,分别为CS、DS、SS、ES,每个段寄存器都是16位的,每条访问内存指令中的地址也是16位的,它被送到地址总线前,CPU内部自动把段寄存器左移四位然后和指令中的地址相加。
  80286引入了保护模式,在这种模式下内存段的访问受到了限制,不能直接访问,需要转换和检查。为了和过去兼容,80286提供了两种模式,一种是先进的保护模式,一种是实模式,系统启动的时候处于实模式,只能访问1MB空间,经过处理进入保护模式,可以访问16MB,但是段的大小还是64k
  80386及其以后的处理器统称为IA32(32bit Intel Architecture)
IA32寄存器:
1、通用寄存器,8个通用寄存器是8086的超集:EAX,EBX,ECX,EDX,EBP,ESP,ESI,EDI。通常保存32位数据。它们的低位部分可以作为8个16位的寄存器:即AX,BX。。。DI,而AX、BX、CX、DX又可分为8个8位寄存器:AH、BH、CH、DH和AL、BL、CL、DL
2、段寄存器:386中6个16位的段寄存器,但是16位无法存放32的段基址,段基址存放在描述符表中,而段寄存器中存的就是这个描述符表的索引,又称为段选择符。
3、指令指针寄存器和标志寄存器
EIP存放下一条将要执行的指令的偏移量,这是相对于目前正在运行的段代码段CS而言的。EIP的低16位可以单独访问,用于16位寻址。
4、386有4个32位的控制寄存器,分别是CR0,CR1,CR2,CR3,CRO的0位置1启动保护模式,为0则是实模式。第31位表示是否允许分页。CR1未定义。CR2保存最近一次缺页的线性地址。CR3是页目录基地址(物理地址)页目录总是在以4KB为单位的存储器边界上,因此低12位总为0

物理地址、虚拟地址及线性地址
  应用程序看到的地址空间称为虚拟地址空间,用“段:偏移量”表示,线性地址是指一段连续的不分段的、范围为0-4GB的地址空间。一个线性地址就是线性地址空间的绝对地址
虚拟地址------->分段机制-------->线性地址-------->分页机制------->物理地址

分段机制:
   段是虚拟地址空间的基本单位,需要描述段的数据结构,包括:段的基址、段的界限、段的保护属性(是否可读或写或执行)虚拟地址空间中偏移量为0到limit范围内的一个段,映射到线性空间就是从base到base+limit。
段描述符表
索引    基地址  界限  属性
0 baseA  limitA  attributeA
1 baseB  limitB  attributeB
2 baseC  limitC  attributeC
每个表项(段描述符)占8个字节(基地址32位,界限20位,属性12位)保护模式下可分为全局描述符表、中断描述符表及局部描述符表。保护模式下的段选择符存放的内容就是索引:
0:1 RPL(requestor privilege level)保护模式下有四个特权级,0表示内核态,最高,3最低,表示用户态,很多操作系统只用了这两个。
2bit:TI (Table Indicator) 置0表示从全局描述表选择,置1表示从局部选择
3:15bits 索引

linux中的段
   由于绝大部分硬件不支持分段,只支持分页,所以linux为了更好的移植性,把段基址设为0,段的界限设为4GB,这样虚拟地址就和线性地址相同了。IA32F规定为代码段和数据段创建不同的段。这就意味着linux必须创建4个段描述符--特权0和3的代码段和数据段
分页机制: 
    物理页和虚拟页面大小都是4KB。页表是把线性地址映射到物理地址的一种数据结构,包括:页面物理地址和页的属性(是否在内存中,是否可读或可写)因为页面大小是4KB,所以物理页面的基址的低12位为0,这12位就用来表示页面的属性,这样一个页表项就是32位,4G空间要分为1M个页面(1个4KB),这样就需要4M空间来存放页表,而且要求是连续的,这样是不能接受的,所以采用二级页表的方法,即为页表再建立一个页表,称之为页目录。
    一个线性地址为32位,高10位是页目录中的索引,对于每个进程都保存着页目录的物理基地址,切换该进程时,即把这个值赋到CR3中。用这个值加上高10位乘以4得到页表基地址,这个基地址加中线性地址中间10位,得到物理页面基地址,然后用物理页面的基址加上线性地址的后12位得到实际物理地址。
页表项结构:高20位表示物理基址,低12位表示页面属性(0位:present=1表示已经装入内存;)

页面高速缓存(cache)页表是放在内存中的,这使得CPU每次读取数据都要至少访问两次内存,从而大大降低了访问速度。为了提高速度,在IA32中设置了一个记录最近存取页的高速缓存部件,它自动保留处理器最近使用的32项页表项,这样就覆盖了128KB的范围,先查缓存是否命中  

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/22326/showart_156476.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP