三种内存地址

三种地址

今天我们来学习一下 Linux 下的内存寻址,通常我们在谈内存地址的时候,我们在谈什么呢?所以首先我们得明确三种地址(以80x86微处理器为例):

  • 逻辑地址(logical address):机器语言指令中用来指定一个操作数或者一条指令的地址,每一个逻辑地址由一个段和偏移量组成,偏移量指明了从段开始的地方到实际地址之间的距离
  • 线性地址(linear address 也叫做虚拟地址 virtual address):是一个 32 位无符号整数,可以用来表达 4GB 的地址,通常用十六进制数表示
  • 物理地址(physical address):用于内存芯片内的内存单元寻址,它们从微处理器的地址引脚发送到内存总线上的电信号对应。

以上内容来自 《Understanding The Linux Kernel》

内存管理单元(Memory Management Unit, MMU)通过分段单元的把一个逻辑地址转换成线性地址,通过分页单元把线性地址转换成物理地址。

从 80286 开始,Intel 处理器以两种不同的方式执行地址转换,分别为实模式(real mode)和保护模式(protected mode)。下面我们就展开描述,在保护模式下,硬件的分段机制和分页机制

分段机制

段选择符和段寄存器

逻辑地址有两部分组成:一个段标识符和一个偏移量。短标识符是一个 16 位的字段,成为段选择符;偏移量是一个 32 位长的字段。
为了快速找到段选择符,处理器提供了段寄存器用来存放段选择符,分别为 cs,ss,ds,es,fs,gs。
其中有三个有专门的用途:

  • cs:代码段寄存器,指向包含程序指令的段
  • ss:栈段寄存器,指向包含当前程序栈的段
  • ds:数据段寄存器,指向包含静态数据或者全局数据段
    其中,cs 含有一个两位的字段,用来指明当前的 CPU 特权等级(CPL),0 代表最高等级、3 代表最低等级。 Linux 只用到了 0 和 3,分别称为 内核态 和 用户态
段描述符

每个段由一个 8 字节的段描述符表示,描述了段的基本信息。段描述符放在全局描述符表(GDT)或者局部描述符表(LDT)中。
通常只会定义一个 GDT,每个进程除了放在 GDT 中的段以外,如还需要创建附加的段,就可以有自己的 LDT。GDT 在主存中的地址和大小存放在 gdtr 控制寄存器中,LDT 的地址和大小则存放在 ldtr 中。
段描述符包涵以下关键字段:

  • Base:包含段的首字节的线性地址
  • Type:描述了段的类型特征和它的存取权限
  • DPL:限制对这个段的存取权限,表示访问这个段的要求的最小 CPU 特权等级
  • P:Segment-Present 标志,表明当前段是否在内存中。Linux 总是把这个标志设为 1,从来不会把整个段交换到磁盘上去
分段单元

介绍完上述的概念,那么逻辑地址是如何转换到线性地址的呢?我们通过下面的步骤来简单说明:

  • 先检查段选择符的 TI 字段,以决定段描述符保存在 GDT 中还是在 LDT 中。如果在 GDT 中,分段单元从 gdtr 中得到 GDT 的线性基地址,如果在 LDT 中,分段单元从 ldtr 中得到 LDT 的线性基地址
  • 从段选择符的 index 字段计算段描述符的地址,计算方法为 index * 8 (一个段描述符为 8 字节),将这个结果与 gdtr 或者 ldtr 中的基地址相加
  • 把逻辑地址中的偏移量与段描述符中的 Base 值相加,就得到了线性地址
快速访问分段机制

如果每次都执行上述的过程,可能会比较耗时,因为 GDT 是存储在主存中的,每次都访问主存,可能会比较慢,所以为了提高逻辑地址到线性地址的转换速度,80x86 处理器提供了一组6个不可编程寄存器。每一个不可编程寄存器含有 8 个字节的段描述符,具体的值由相对应的段寄存器中的段描述符确定。每当一个段选择符被装入段寄存器,相对应的段描述符就由主存装入到对应的不可编程寄存器,这样就可以不需要上面三个过程中的前两个,就可以得到线性地址了。

分页机制

页、页框和页表

分页单元把线性地址转换成物理地址,其中的关键任务是把所请求的访问类型与线性地址的访问权限做对比。

  • 页:为了更高效和更经济的管理内存,线性地址被分为以固定长度为单位的组,成为页。页内部连续的线性地址空间被映射到连续的物理地址中。这样,内核可以指定一个页的物理地址和对应的存取权限,而不用指定全部线性地址的存取权限。这里说页,同时指一组线性地址以及这组地址包含的数据
  • 页框:分页单元把所有的 RAM 分成固定长度的页框,每一个页框包含一个页。页框是主存的一部分,因此也是一个存储区域。页和页框相比,前者只是一个数据块,可以存放在页框或者磁盘中。
  • 页表:把线性地址映射到物理地址的数据结构成为页表,页表存放在主存中,并在启用分页单元之前必须由内核对页表进行适当的初始化
常规的分页

从 80386 开始,Intel 处理器的页大小为 4KB。
32 位的线性地址被分为 3 个域:

  • Directory(目录):最高 10 位
  • Table(页表):中间 10 位
  • Offset(偏移量):最低 12 位
    线性地址的转换分两步完成,每一步都基于一种转换表,第一种转换表成为页目录表,第二种转换表成为页表。

为什么需要两级呢?目的在于减少每个进程页表所需的 RAM 的数量。如果使用简单的一级页表,将需要高达 2^20 个表项来表示每个进程的页表,即时一个进程并不使用所有的地址,二级模式通过职位进程实际使用的那些虚拟内存区请求页表来减少内存容量。每个活动的进程必须有一个页目录,但是却没有必要马上为所有进程的所有页表都分配 RAM,只有在实际需要一个页表时候才给该页表分配 RAM。

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

  • Present 标志:为 1 则表示页在主存中;如果为 0 则表示不在内存中,如果执行一个地址转换的时候,所需的页表项或者页目录项中的该标志为 0,那么分页单元就把该线性地址存在在控制寄存器 cr2 中,并产生 14 号异常:缺页异常。
  • 包含页框物理地址最高 20 位的字段
  • Dirty:当对页框进行写操作时就设置这个标志
  • Read/Write 标志:含有页或者页表的存取权限
  • User/Supervisor:含有访问页或者页表所需的特权等级

了解了以上结构之后,我们看看如何从线性地址转换到物理地址的:

  • 线性地址中的 Directory 字段决定页目录中的目录项,目录项指向适当的页表
  • 线性地址中的 Table 字段又决定页表的页表项,页表项含有页所在页框的物理地址
  • 线性地址中的 Offset 地段决定了页框内的相对位置,由于 offset 为 12 为,所以一页含有 4096 字节的数据

以上描述的为 80x86 微处理器硬件分页机制,不同架构的 64 位处理器分页机制,大体的思路就是将二级模式拓展为三级(ia64)或者四级(x86_64),以达到对更大范围寻址空间的支持。具体到 Linux 中如何使用操作系统的分段分页机制以及进程的地址空间管理,后续再谈

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容