GDT和LDT详解

1.GDT

我们回顾一下实际的操作系统的内存关系:

程序/进程 → 映射 段 表 逻辑地址 → segment unit 段 基 址 + 偏 移 地 址 虚拟地址 → page unit 页 表 物理内存地址 \text{程序/进程}\overset{段表}{\xrightarrow[\text{映射}]{}} \text{逻辑地址}\overset{段基址+偏移地址}{\xrightarrow[\text{segment unit}]{}} \text{虚拟地址}\overset{页表}{\xrightarrow[\text{page unit}]{}} \text{物理内存地址} 程序/进程 映射逻辑地址 segment unit+虚拟地址 page unit物理内存地址

这里有一个重要的概念虚拟内存,这个概念是面向软件程序而言,他们希望程序是连续的地址,一段一段的,注意,在32位系统里,一个program仅有3G,(还有1G OS程序占据)

而逻辑地址 由 两个部分组成 Segment SelectorOffset(偏移地址)

其中Segment Selector 指向 Segment Descriptor,一个 Segment Descriptor 完整的描述了一个 Segment 既段的信息.

因为程序中一般将一个程序所使用的部分分为程序段,数据段,堆段和栈段等,这里面每一个段也就会有相应的Base,执行中也会Offset(即Linear Address)

Segment Descriptor

段通过段描述(Segment Descriptor)保存段的信息,每一个 Segment Descriptor 作为一个 entry 保存到 GDT(全局段表)中;总长为64位;Segment Descriptor 由如下部分构成,

img

  • Base
    长度 32 bits,Segment 在虚拟内存中的起始地址;
  • Type
    长度 4 bits,表示访问权限,读、写、执行等权限;
  • S
    长度 1 bit,系统标志位,表示该段是否是系统段,如果是,表示其中保存的是系统核心内容;
  • D Or B
    表示该段包含的是 data 还是 code;
Segment Selector

Segment Selector 又称作 Segment Identifier 既段标识,它作为标识指向段表中该段所在的位置;

Segment Selector 总长 16 bits,由三部分组成,

img

  • index指向的是段描述(Segment Descriptor)在段表(GDT)中的偏移地址(直白点说,就是定位段在段表中的位置),长度 13 位.

    假设求某个段的位置:

    a d d r s = a d d r g + i n d e x ∗ 8 addr_s = addr_g + index * 8 addrs=addrg+index8

    其中 a d d r g addr_g addrg保存在GDTR中

  • TI
    Table Indicator;长度 1 bit,表示它指向的是 GDT 还是 LDT;

  • RPL

    Request Privilege Level;长度 2 bits;指定 CPU 访问的权限级别;

    • 00 表示该段运行在内核态
    • 11 表示该段运行在用户态

这些概念似乎有点太过绕看图

操作系统内存管理 - 全局段表结构

这里就很清楚的表明 segment selector + GDTR 确定了 Segment Description的位置.而Segment Description指向的是段的实际位置…

2.LDT(linear Data Table)

线性地址,既常说的虚拟地址;线性地址由逻辑地址映射而来,物理地址由线性地址映射而来.虚拟地址处于

映射
映射
逻辑地址
线性地址
物理地址

线性地址由两部分组成 段基址(从GDT/LDT中得到) + 偏置

img

而逻辑地址(代码中内容),为Segment Selector : offset

这里我们得清楚LDT和GDT基本结构是类似的LDT内部存储的是进程相关的段的基址内容,GDT存储的是内核代码的段的基址,而下面一张图则会更好的说明LDT以及GDT的关系.

**总结:**系统会给程序自动分配程序段,代码段等,这些段以及偏移组成了逻辑地址,而逻辑地址通过GDTR/LDTR,找到位于虚拟内存的段基址,最后得到虚拟地址.

3.线性地址到物理地址

基于之前的学习我们认知到,一页物理内存大小为4K,而32位操作系统的最大寻址空间是4G(系统总线数目限制),则总共有1 M个页框.

物 理 内 存 = 页 框 号 + 偏 移 地 址 物理内存 = 页框号 +偏移地址 =+

则假设物理地址为 d d d,而页框号为 n n n,偏移地址为 r r r

d 4 K = n . . . . r \frac{d}{4K} = n .... r 4Kd=n....r

结合前面学习的多级也变原理,我们清楚,为了避免储存页框浪费过多内存,所以采用多级页表.

则由上述的线性地址

img

天然形成这样一种对应关系,总共有 1024 个 Directories(目录),每个 Directory 包含 1024 个页表,每个页表对应 4K 个偏移地址(这里这样做是有目的的,这样这好与一个物理页框的偏移地址范围相吻合);那么总共有

1024 × 1024 × 4 K = 4 G 1024\times 1024\times 4\text{K}=4\text{G} 1024×1024×4K=4G

  • 这里就会有一个疑问了注意,逻辑地址中的 Offset 是 32 位的,而基于多级页表线性地址的 offset 是 12 位的,为什么偏移由此转换呢?

    ​ 因此逻辑地址中 32 位的偏移地址是段内偏移地址,因此它的地址仍然是 32 位,而线性地址的偏移地址需要与物理页框的偏移地址对应起来(一个页为 2 12 = 4 K 2^{12} = 4K 212=4K ),所以,需要设计为 12 位,否则虚拟地址和物理地址基于页框的偏移地址对应不起来,就得不到正确的转换;

  • Directory(目录)记录着上述第一层的地址—>cr3 + directory

  • Table 记录着第二层的地址,即—>Directories entryXX + table

img

  1. 通过控制寄存器 cr3 找到 Page Directory Table 在内存中的起始地址;

  2. 通过线性地址中的 Directory 段从 Page Directory Table 中找到对应的 Directory Entry;

  3. 通过 Directory Entry 的高 20 bits 找到 Page Table 在主存中的起始地址;

  4. 通过线性地址中的 Table 段从 Page Table 中找到对应的 Page Entry;

  5. 从 Page Entry 中通过虚拟页框号找到物理页框号 P F N p PFN_p PFNp

  6. 最后,通过 P F N p × 4 K + O F F S E T = 物 理 内 存 地 址 PFN_p \times 4K + OFFSET = 物理内存地址 PFNp×4K+OFFSET=

这些内容由page unit完成

e Entry;

  1. 从 Page Entry 中通过虚拟页框号找到物理页框号 P F N p PFN_p PFNp

  2. 最后,通过 P F N p × 4 K + O F F S E T = 物 理 内 存 地 址 PFN_p \times 4K + OFFSET = 物理内存地址 PFNp×4K+OFFSET=

这些内容由page unit完成

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值