注:本文档为《从0学x86操作系统》课程配套的学习文档,提供相应的辅助学习资料和答疑勘误。 有关该课程的信息,请点击这里访问:https://study.163.com/provider/1017884735/index.htm 在阅读本文档时,如有疑问和建议,欢迎在下方留言或者直接联系我。
本课时简要介绍保护模式,以及通过编写代码实现从实模式到保护模式的切换。课程中不会细讲保护模式方方面面的细节,而只是大体地介绍,从而让你对保护模式有比较初步地了解。
x86 CPU的两种工作模式
实模式
x86在上电启动后自动进入实模式,即16位工作模式,这种模式是最早期的8086芯片所使用的工作模式。早期的芯片设计得较简单、工作模式也较简单,所以有诸多限制:
- 最大只能访问1MB的内存:采用段值:偏移的方式访问,内核寄存器最大为16位宽。如段寄存器CS, DS, ES, FS, GS, SS均为16位宽,AX, BX, CX DX, SI, DI, SP等也均为16位宽
- 所有的操作数最大为16位宽,出栈入栈也以16位为单位
- 没有任何保护机制,意味着应用程序可以读写内存中的任意位置
- 没有特权级支持,意味着应用程序可以随意执行任何指令,例如停机指令、关中断指令
- 没有分页机制和虚拟内存的支持
有接触过单片机开发的同学,可以将其与单片机进行类比。可以将这种模式理解为一种比较原始、粗暴、简单的工作模式。
虽然其有这些限制,但是这种模式下可以使用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中。