注:本文档为《从0学x86操作系统》课程配套的学习文档,提供相应的辅助学习资料和答疑勘误。 有关该课程的信息,请点击这里访问:https://study.163.com/provider/1017884735/index.htm 在阅读本文档时,如有疑问和建议,欢迎在下方留言或者直接联系我。

本课时简要介绍保护模式,以及通过编写代码实现从实模式到保护模式的切换。课程中不会细讲保护模式方方面面的细节,而只是大体地介绍,从而让你对保护模式有比较初步地了解。

x86 CPU的两种工作模式

实模式

x86在上电启动后自动进入实模式,即16位工作模式,这种模式是最早期的8086芯片所使用的工作模式。早期的芯片设计得较简单、工作模式也较简单,所以有诸多限制:

  1. 最大只能访问1MB的内存:采用段值:偏移的方式访问,内核寄存器最大为16位宽。如段寄存器CS, DS, ES, FS, GS, SS均为16位宽,AX, BX, CX DX, SI, DI, SP等也均为16位宽
  2. 所有的操作数最大为16位宽,出栈入栈也以16位为单位
  3. 没有任何保护机制,意味着应用程序可以读写内存中的任意位置
  4. 没有特权级支持,意味着应用程序可以随意执行任何指令,例如停机指令、关中断指令
  5. 没有分页机制和虚拟内存的支持

有接触过单片机开发的同学,可以将其与单片机进行类比。可以将这种模式理解为一种比较原始、粗暴、简单的工作模式。
虽然其有这些限制,但是这种模式下可以使用BIOS提供的服务,方便我们显示字符、读取磁盘等。

保护模式

在后续的芯片设计中,intel为处理器增加了一些新的功能,可以实现某些保护功能,即保护模式。具体的特点如下:

  • 寄存器位宽扩展至32位,例如AX扩展至32位的EAX,最大可访问4GB内存
  • 所有操作数最大为32位宽,出入栈也为32位
  • 提供4种特权级。操作系统可以运行在最高特权级,可执行任意指令;应用程序可运行于最低特权级,避免其执行某些特权指令,例如停机指令、关中断指令
  • 支持虚拟内存,可以开启分页机制,以隔离不同的应用程序

    切换至保护模式

    要切换至保护模式,需要遵循以下流程。

  • 禁用中断

  • 打开A20 地址线
  • 加载GDT表
  • 设置CR0的保护模式使能位
  • 远跳转,清空流水线

    开启A20地址线

    开启的方法参考了:https://wiki.osdev.org/A20#Fast_A20_Gate。我们采用以下的简单的方法:

    in al, 0x92 or al, 2 out 0x92, al

开启保护位

此项需要设置CR0寄存器的PE位为1。CR0无法直接读写,必须先读取到某个中间寄存器,修改值后,再将值回写到CR0中。
image.png

参考资料