操作系统实模式和保护模式

实模式和保护模式的中的地址

  1. 在实模式下,“段基址+段内偏移地址”经过段部件的处理,直接输出的就是物理地址,CPU可以直接用此地址访问内存。
  2. 而在保护模式下,“段基址+段内偏移地址”称为线性地址。段基址通过选择子获取,它本质是个索引,类似于数组下标,通过这个索引便能在GDT中找到相应的段描述符,在该描述符中记录了该段的起始、大小等信息,这样便得到了段基址。
  3. 若没有开启地址分页功能,线性地址就被当作物理地址来用,可直接访问内存。若开启了分页功能,此线性地址又多了一个名字,就是虚拟地址虚拟地址线性地址在分页机制下都是一回事)。虚拟地址要经过CPU页部件转换成具体的物理地址,这样CPU才能将其送上地址总线去访问内存。
  4. 无论在实模式或是保护模式下,段内偏移地址又称为有效地址,也称为逻辑地址,这是程序员可见的地址。
address.png

实模式

实模式下用户程序可以直至访问任意内存,存在风险

保护模式

  1. 与实模式相比, 保护模式中,段寄存器保存的再也不是段基址,而是选择子。该选择子其实就是一个数,用来索引全局描述符表(GDT)中的段描述符全局描述符表就像数组,选择子就像下标一样。

    全局描述符表中,每一个表项是段描述符,大小为64位。全局描述符表保存在内存中,由GDTR寄存器指向它。

  2. 段描述符保存在内存中,CPU访问效率不高,为提高段信息获取效率,将段信息用段描述符缓冲寄存器来缓存

寄存器扩展

除段寄存器外,从16位寄存器,扩展为32位

寻址扩展

address find.png

段描述符

segment.png
  1. 段界限

    段界限的单位,由G指定,G = 0表示为1字节,G = 1 表示 4K

    段界限是一个偏移量,从0算起,所以实际的段界限界值 = (描述符中段界限 + 1)* (1 : 4K) - 1

    根据段的扩展方向(栈向下扩展),当段内偏移超出界限范围时,被认为时非法访问。

  2. 段基址

    3处段基址组合成一个32位的段基址

  3. S

    CPU将一个段描述符分为两类,系统段的描述符和数据段的描述符,由S位决定是否是系统段

    系统段:硬件运行需要用到的东西

    数据段:软件用到的东西(包括,代码、数据、栈等)

    S = 0 表示系统段, 1 表示数据段

  4. type

    与S字段共同确定段描述符的确切类型

type.png
  1. DPL(Descriptor Privilege Level)

    描述符特权级,代表所指内存段的特权级,能表示4中特权,0、1、2、3,数字越小权限越大。用户程序通常处于3特权级

  2. P(Present)

    若段存在于内存中,P = 1,否则为0。

  3. AVL(Available)

    表示操作系统可随意使用

  4. L

    用来设置是否是64位代码段

  5. D/B

    指示有效地址(段内偏移)和操作数的大小,用来兼容80286的保护模式(286保护模式下,操作数是16位)

    对于代码段,此位是D位,D = 0表示指令中的有效地址和操作数是16位,D = 1 表示32位

    对于栈段,此位是B位,B = 0表示栈的起始地址是16位寄存器的最大范围0xffff。 B = 1栈的起始地址是32位寄存器的最大寻址范围,0xffffffff。

  6. G (Granularity)

    指定段界限的单位大小。

    G = 0表示为1字节,G = 1 表示 4K

全局描述符表GDT、局部描述符表LDT和选择子

GDT (Global Descriptor Table)

全局描述符表中,每一个表项是段描述符,大小为64字节。全局描述符表保存在内存中,由GDTR寄存器指向它。

GDT.png

使用lgdt 指令初始化gtdr。

选择子

在保护模式中,段寄存器CS、DS、ES、FS、GS、SS不在存放段基址,而是存放一个选择子,通过选择子在GDT中找到对应的段描述符,获取段相关信息。

GDT Selector.png

选择子结构:

  1. RPL

    请求特权级,可以表示0、1、2、3四种特权级

  2. TI(Table Indicator)

    用来指示选择子实在GDT中,还是LDT中索引描述符。

    TI = 0表示GDT

    TI = 1表示LDT

  3. 描述符索引值

    索引值表示在GDT或LDT中的索引

LDT (Local Descriptor Table)

厂商为在硬件一级原生支持多任务而创造的表,一个任务对应一个LDT,保存任务的私有内存段。 每个任务都有自己的LDT,随着任务的切换,也要切换相应的LDT。

现代操作系统很少有用到LDT的。

打开A20地址线

在实模式下,通过段基址 * 16 + 段内偏移地址寻址,实模式下寄存器都是16位,所以最大寻址地址为:0xffff:ffff0xffff0 + 0xffff = 0x10ffef,由于8086/8088的地址线是20位(A0 ~ A19),最大寻址空间为1MB,即0x00000~0xfffff

由于没有A20地址线,当段基址 * 16 + 段内偏移地址超过最大寻址空间时,相当于丢掉进位,回到低地址范围。为兼容与8086/8088,在实模式下,后续的CPU都关闭A20地址线,实现地址回绕。

要进入保护模式去访问更大的内存空间,需打开A20地址线

打开A20地址线,只需要将端口0x92的第一个位置置1:

in al, 0x92
or al, 00000010b
out 0x92, al

保护模式开关

通过将控制寄存器CR0的第0位,即PE(Protection Enable)位置1,开启保护模式

mov eax, cr0
or eax, 0x00000001
mov cr0, eax

你可能感兴趣的:(操作系统实模式和保护模式)