Linux学习 内存寻址 (1)

Intel 80x86微处理器 芯片级的内存寻址
Linux 如何利用寻址硬件

一、 内存地址

地址英文说明
逻辑地址logical address由一个段(segment)和偏移量(offset)组成
线性地址linear address是一个32位无符号整数,可以用来表示高达4GB的地址
物理地址physical address用于芯片级内存单元寻址
分段单元
分页单元
逻辑地址
线性地址
物理地址

二、硬件的分段单元

段寄存器

逻辑地址由段标识符和指定段内相对地址的偏移量

段标识符是一个16bit的域,称为段选择符(segment selector),偏移量是一个32bit的域
为了快速方便地找到段选择符,处理器提供段寄存器(segmentation register),目的是存放段选择符。

段寄存器用途
cs代码段寄存器,指向存放程序指令的段 含有一个两位的域,用于指明CPU的当前特权级。Linux 0 内核态 3 用户态
ss栈段寄存器,指向存放当前程序栈的段
ds数据段寄存器,指向存放静态数据或者外部数据的段
es,fs,gs一般用途,可以用来访问任何段

段描述符

每个段由一个8字节的段描述符(segment descriptor)来表示,它描述了段的特征。段描述符被放在全局描述符表(Global Descriptor Table,GDT)或局部描述表(Local Descriptor Table, LDT)

系统通常只定义一个GDT,而每个进程可以有自己的LDT.GDT在主存中的地址被放在处理器的gdtr寄存器中,当前正被使用的LDT的地址被放在处理器的ldtr寄存器中。

段描述符:不可编程寄存器

段选择符

段选择符说明
13位的索引指定了放在GDT或LDT中的相应段描述符的入口
TI(描述符表指示符)TI = 0,在GDT中;TI=1,在LDT中
两位RPL(请求特权级)域描述了当相应的段选择符装入到cs寄存器中时,CPU的当前特权级

段单元

一个逻辑地址是怎样转换成相应的线性地址的。
1.检查段选择符的TI域,用于决定段描述符保存在哪一个描述符表中。

TI说明
0(描述符在GDT中)段单元从gdtr寄存器中得到GDT的线性基地址
1(描述符在LDT中)段单元从ldtr寄存器中得到LDT的线性基地址

2.从段选择符的索引域计算段描述符的地址,索引域的值乘以8,这个结果被放在gdtr或ldtr寄存器中
3.将逻辑地址的偏移量与段描述符基地址域的值相加,就得到了线性地址

只有当段寄存器的内容被改变时才需要执行前两个操作

Linux中的段

段可以给每一个进程分配不同的线性地址空间,而页可以把同样的线性地址空间映射到不同的物理空间。
Linux喜欢使用分页方式:
1.当所有的进程使用同样的段寄存器值时,内存管理变成更简单,也就是说它们能共享同样的线性地址
2.Linux目标:可以把它移植到绝大多数流行的处理器平台上。

由于所有的进程使用同样的逻辑地址空间,因此需要定义的段的总数就可以被限制得很少,于是把所有的段描述符存放在全局描述符*(GDT)中就成了可能。

内核代码段内核数据段用户代码段用户数据段
Base0x000000000x000000000x000000000x00000000
Limit0xfffff0xfffff0xfffff
G(粒度标志)1(段大小,单位以页计)111
S(系统标志)1(正常的代码段或数据段)111
Type0xa(可读可执行的代码段)0x2(可读写数据段)0xa0x2
DPL0(内核态)03(用户态)3
D/B(32位地址标志)1(偏移量为32bit)111
段选择符__KERNEL_CS__KERNEL_DS__USER_CS__USER_DS

对于每一个进程,GDT包含两个不同的段描述符,一个用于TSS段,一个用于LDT段。当进程被创建时,其TSS和LDT描述符被加入到GDT中。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值