X86 CPU mode switching

MODE SWITCHING

    在一次硬件或软件复位后,为了能够使CPU处在保护模式下,必须在实模式下执行一次模式交换.一旦处在保护模式下,为了能够执行在实模式下写的软件,软件一般不需要返回到实模式.而是在虚拟8086模式下更方便的执行该软件.

Switching to Protected Mode

    在实模式交换到保护模式之前,一个最小组的系统数据结构表格和代码模组必须被装载到Memory,一旦这些表格被建立,软

件初始化代码就能够交换到实模式。保护模式通过执行指令MOV CRO 来置起CR0寄存器中的PE 标志位而进入,在保护模式下刚开始执行指令时,CPL为0。
    Intel64与IA-32 CPU在交换到保护模式有些许的差别。为了保证兼容性,建议采用以下步骤:
    1.关闭中断。CLI关闭可屏蔽硬件中断。NMI能够被外部电路关闭。软件必须保证不产生中断和异常在模式交换操作过程中。
    2.执行LGDT指令来装载GDTR(GDT的基地址)。
    3.在控制寄存器CR0执行MOV CR0 指令来置PE flag(PG可置可不置)。
    4.紧随 MOV CR0 指令,执行一次远跳转或是远调用指令.
    5.紧随 MOV CR0 指令的跳转和调用指令改变CPU执行和系列化的流程.
    6.如果分页功能使能,MOV CR0 和JMP,CALL指令必须来自a page is identity mapped(线性地址在JMP或CALL前和物理地址
       在paging和保护模式使能后是一样的)。JMP或CALL的目标指令不必被标记为mapped。
    7.如果一个局部描述符表(LDT)将要被使用,执行LLDT指令为LDT装载在LDTR寄存器的segment selector.
    8.执行LTR指令来装载一个segment selector到task 寄存器用来初始化保护模式 task或一个被用来存储在一次任务交换的TSS信          息的可写区域的memory。
    9.在进入保护模式后,The segment register继续保持它们在实模式下的内容。在第4步中的JMP或CALL指令复位CS register通          过执行下面的操作来更新剩下segment register的内容。
    - 重载segment register DS,SS,ES,FS,和GS。如果ES,,FS,GS register 不会被使用,装载它们给一个null selector。
    - 执行一次JMP或CALL指令to a new task,这个过程自动reset 所有的segment register的值和到一个新的code segment的分          支。
    10.执行LIDT指令来装载IDTR register,给值为保护模式下IDT的address和limit.
    11.执行STI指令来使能可屏蔽硬件中断和执行必要的硬件操作来使能NMI中断。
    
     随机的失败会发生如果其他的指令存在于step3和4以上。失败很容易看见在某些情况下,比如在system management mode        下参考memory的instructions在第3步和第4步插入。

Switching back to real-address mode 

     CPU 从保护模式返回到实模式,如果软件清零CR0寄存器中的PE bit通过MOV CR0 指令。返回实模式的步骤如下:

    1.关闭中断。CLI关闭可屏蔽硬件中断。NMI能被外部电路关闭。
    2.如果paging功能打开,执行下面的操作:
     -传递编程控制到被识别映射到物理地址的线性地址(就是说线性地址等于物理地址)。
     -保证GDT和IDT在identity mapped page 上。
     -清零CR0寄存器中的PG bit。
     -CR3 regiater置零来刷新TLB。
     3.传递编程控制到一被限定为64K字节的可读segment。这个操作装载实模式下要求的segment limit到 CS regiser。
     4.将包含下列值的描述符的selector装载到segment register SS,DS,ES,FS,and GS,在实模式下这些值是合适的:
     - Limit = 64KByte(0FFFFH)
     - Byte 粒度的(G = 0)
     - Expand up (E =0)
     - Writable (W =
1) 
     - Present(P = 1)
     - Base = any vaule
段寄存器必须被装载为非空的segment selector否则,段寄存器在实模式下将不可用.注意如果段寄存器不重载的话,指令会使用
在保护模式下装载的descriptor 属性继续.
     5.执行一LIDT指令来指向一个实模式下的中断向量表,这个是在1M-Byte实模式寻址范围内.
     6.清零CR0 register中的PE flag来交换到实模式.
     7.执行一远跳转指令跳到实模式编程.这个操作刷新了指令列,并且装载了合适的Base-address值在CS register中.
     8.执行STI指令来使能可屏蔽硬件中断,以及执行必要的硬件操作来使能NMI.


NOTE

     所有的在step1`9执行的代码必须在A single page且线性地址在该page必须被识别映射到物理地址。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值