分享

再论 real mode

 凤凰苑凶真 2016-12-13

real mode(实模式)有几个显著特征,但是最主要的特征是:实地址模式(real address),processor 的 linear address 就是 physical address,它的第 1 物理特征就是:CR0.PE = 0 ,因此,识别 processor 是否处于 real mode 的唯一途径就是判断 CR0.PE 标志位。

real mode 实际上被称为 8086 模式。它的其它特征,如:16 位的寻址空间,0 级的 processor 权限等等,这些都是次要,造成这些 real mode 特征是原因是:real mode 下 processor 一直处于初始态。

1. processor 的初始态

初始化 processor 的两个途径是:接收到 RESET# 信号和 INIT# 信号,RESET# 信号由外部的电源逻辑产生。在 system logic 上电后,RESET# 只产生一次。而 INIT# 可以在上电后,执行多次

下面是 processor 一些关键的初始状态值:

processor 物理资源
状态值(hex)
描述
CR0
0000_0000_6000_0010
CR0.PE = 0, CR0.ET = 1, CR0.CD = 1,处于 real mode
RFlags
0000_0000_0000_0002
所有标志都为 0, Bit1 是固定为 1
CS
Selector = F000, Base = 0000_0000_FFFF_0000, Limit = FFFF
CS.Base = FFFF0000h, Limit = 64K,此时 DPL = 0 处于最高权限
G = 0, D/B = 0, L = 0, P = 1, DPL = 0, S = 1, Type = 1010
RIP
0000_0000_0000_FFF0
RIP 指令指针指向 0000FFF0h 处
DS, ES, FS, GS, SS
Selector = 0, Base = 0, Limit = FFFF
所有 segment registers 都处于 base = 0, Limit = 64K
G = 0, D/B = 0, P = 1, DPL = 0, S = 1, Type = 0010
GDTR, IDTR
Base = 0, Limit = FFFF
GDTR.base 和 IDTR.base 都处于 0, Limit = 64K
LDTR, TR
Selector = 0, Base = 0, Limit = FFFF
LDTR.base 和 TR.base 都处于 0, Limit = 64K
G = 0, P = 1, DPL = 0, Type = 0010/0011

上面就是决定 processor 处于 real mode 的关键初始化状态值。由于 CR0.PE = 0,表明 processor 处于 real mode

其中 CS segment registers 和 DS/ES/FS/GS/SS segment registers 以及 RIP 寄存器决定了 processor 的执行环境

CS.base = 0000_0000_FFFF_0000 以及 RIP = 0000_0000_0000_FFF0 从物理上决定了 processor 的 first fetch Instruction 位于内存:FFFF_FFF0h(CS.base + RIP)中

在 FFFFFFF0 内存里的第 1 条指令典型地是 far jmp 远跳转指令,如下所示:

FFFFFFF0: EA 5B E0 00 F0        jmp far ptr F000:E05B

FFFFFFF0 地址会被映射到 F000:FFF0 这个地址上,执行完这条 far jmp 后,CS.base 会被刷新为 0xF0000 (CS.selector << 4,也就是 0xF000 << 4),eip 是 0000E058,processor 将转到 000FE058 继续执行。此时,processor 处于真正的 real mode 状态。实际上 processor 的第 1 条指令最大的目的是刷新 cs 寄存器,开辟混沌。

可以看到:

由于所有的 segment registers 的 Limit 都是 64K,因此决定了 real mode 下寻址能力为 64K

这是为什么 real mode 只能访问 16 位地址空间的根本原因,当然是有办法在 real mode 下更改每个 segment 的 limit 值,使用 real mode 下访问超越 64K 空间。

另一方面由于 IDTR.base = 0,它决定 real mode 下 IVT(interrupt vector table)中断向量表位置在内存地址 0 上

由于这些 processor 执行环境(Limit 和 attribute)在整个 real mode 执行过程中都没改变,导致 real mode 下一直都处于 processor 初始执行环境下。

2. real mode 下的 processor 资源

real mode 下的物理资源和 protected mode 以及 long mode 下的物理资源是一样的,real mode 下可访问的 16 位资源,如:16 位的 PC(PC 计数器),16 位的 GPRs,16 位的 segment registers 以及 16 位的寻址空间等等,追根究底是由于:real mode 下的能力受到限制。

在 real mode 下,processor 提供的 protected 机制被 disable,processor 所使用的 logic address 转换为 linear address 后无须转换就变成了 physical address。这与在 proected mode 下关闭 paging 功能 是一样的效果。由于 protected 被 disalbe,real mode 所能使用的 processor 资源为:

  • 16 位 segment limit:由于 real mode 下没有改变初始的 segment limit 值,因此,所有的 segment 访问被限制在 64K 内
  • 16 位的 default 操作数:CS.D = 0,导致 real mode 下缺省的 operand size 是 16 位,但是并不是不能访问 32 位的数据,这需要进行 operand size override(改写操作数大小)
  • 16 位的 default 地址值: 同样 CS.D = 0 导致 real mode 缺省的 address size 是 16 位,但是这也并不代表不能使用 32 位的地址值, 这需要进行 address size override(改写地址大小)。但是,这里又有些矛盾,segment limit 被限制为 16 位值,实际上改写为 32 位地址值,只是使用了 32 位地址范围的前 64K 空间。虽然这样,通过进行 address size override 操作,最大的好处是可以使用了 32 位的寻址模式,这比 16 位的寻址模式提供了很多寻址模式
  • 16 位的 default stack 大小:DS.D/B = 0,导致 real mode 下使用的 stack 大小为 16 位的。
  • 真实地址模式,而无须进行 physical 的转换。这样导致 processor 提供的 proected 机制无法使用,protected 机制下的数据结构无法使用,包括:GDT/LDT, TSS 块,而 IDT 变相为 IVT,IDTR 寄存器在 real mode 下 IDTR.base = 0 ,IVT 被放在地址 0 处
  • 16 位的 ip 值:RIP 寄存器在 real mode 只能使用前 64K 值
  • 20 位的指令 fetch 操作:虽然 ip 是 16 位的,但是 real mode 下的 fetch 机制却允许使用 20 位地址。这个 20 位的 fetch 地址值的形成是:CS.base = CS.selector << 4 ,CS 的 base 值由 CS.selector 左移 4 位(即乘以 16)而来,这样就形成了 20 位的 fetch 地址
  • 20 位的地址 1M 寻址能力:同样,对于 DS 来说情况一样,它支持 20 位地址的寻址

这些限制可以通过切换到 protected 模式进行更改。

3. real mode 的 processor 权限

real mode 下 CS.DPL 或者说 CS.CPL 为 0,并且这个 CPL 无法改变,因此 processor 始终处于最高的 0 级权限。这代表 real mode 下用户的代码可以做任何操作。

4. 操作系统的引导

从 processor 第 1 条 far jmp 指令开始,直到读取磁盘的 0 扇区(MBR 记录)止,所执行的都是属于 BIOS 的代码,BIOS 所支持的硬盘可以有 4 个主分区,因此 pc 中最多可以安装 4 个操作系统。MBR 可由操作系统引导管理软件配置安装或者由操作系统的安装程序配置安装。如下示意图:

first fetch instruction  --->  BIOS  -->  MBR --->  OS 1 boot  ---> OS 1(例如:windows/linux)
                                           |
                                           |
                                           +----->  OS 2 boot  ---> OS 2(例如:windows/linux)
                                           |
                                           |
                                           +----->  OS 3 boot  ---> OS 3(例如:windows/linux)
                                           |
                                           |
                                           +----->  OS 4 boot  ---> OS 4(例如:windows/linux)

硬盘的主分区表包含在 MBR(Master Boot Record)内,MBR 负责查找活动可引导的主分区进行加载,将控制权交给加载进内存的主分区 boot 代码。每个操作系统可以实现自己的 boot 程序,

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多