[系列]OS学习-自己写操作系统(3)- 实模式到保护模式的跳转
2017-04-06 19:24
731 查看
这一章比较难,断断续续看了3天,才搞懂“实模式到保护模式的跳转”
自己的一点心得:
1.保护模式非常复杂,涉及方方面面的规则,不要想一次性、完全弄懂,每次只学该学的就好。
2.CR0(0号控制寄存器)的最后1位如果是0,CPU在实模式下运转;如果是1,在保护模式下运转。
3.一定要自己写一遍GDT、段选择符、以及实模式->保护模式跳转,不然是不可能明白的。
首先来谈谈保护模式下最基础的、最重要的——寻址方式,写寻址方式的文章很多很多,就不在赘述
(我前前后后看了10篇文章,好多教材,还是没懂,最后写了跳转代码、编译进镜像,跟着bochs虚拟机一点点调试才最后明白的)
jmp 保护模式的段选择符:目标语句在目标段的偏移量 这条语句代表:跳跃到保护模式下的目标语句。
大致的动作是这样:
CPU拿出段选择符->取段选择符前13位为段描述符在GDT中的索引-->根据GDTR基址寄存器找到GDT表位置-->取得需要的段描述符-->从中拿出32位的真正段基址-->加上一开始给出的偏移量(最一开始jmp语句中给出)-->偏移量+段基地址=获得物理地址(目前没有开启分页机制,不然要再分页一次,才能得到物理地址)
对实模式—>保护模式的跳转进行了更加详尽的注释。
其余的部分请大家看于渊老师的《Orange's》一书。
然后是一致/非一致代码段的call/jmp限制(保护模式下不能随意jmp执行的),做了一个思维导图:
如果我们在甲段;想访问乙段(一致段),那么只要乙>=我们,就可以访问:
接下来谈一谈描述符属性:也是很复杂的事情。
找到了一篇很好的文章:段描述符和段选择符解析,通过这文章,暂时明白了段描述符的意义。
新知识:
1.段界限值(20bit=1M),在G=0(不允许分页情况下),代表段最大长1M个字节,即段最大为1MB
在G=1(允许分页下),代表段最大长1M个页(1个页4kb),即段最大4GB
2.系统段描述符一般都在中断/异常描述符表中
自己的一点心得:
1.保护模式非常复杂,涉及方方面面的规则,不要想一次性、完全弄懂,每次只学该学的就好。
2.CR0(0号控制寄存器)的最后1位如果是0,CPU在实模式下运转;如果是1,在保护模式下运转。
3.一定要自己写一遍GDT、段选择符、以及实模式->保护模式跳转,不然是不可能明白的。
首先来谈谈保护模式下最基础的、最重要的——寻址方式,写寻址方式的文章很多很多,就不在赘述
(我前前后后看了10篇文章,好多教材,还是没懂,最后写了跳转代码、编译进镜像,跟着bochs虚拟机一点点调试才最后明白的)
jmp 保护模式的段选择符:目标语句在目标段的偏移量 这条语句代表:跳跃到保护模式下的目标语句。
大致的动作是这样:
CPU拿出段选择符->取段选择符前13位为段描述符在GDT中的索引-->根据GDTR基址寄存器找到GDT表位置-->取得需要的段描述符-->从中拿出32位的真正段基址-->加上一开始给出的偏移量(最一开始jmp语句中给出)-->偏移量+段基地址=获得物理地址(目前没有开启分页机制,不然要再分页一次,才能得到物理地址)
;使用NASM,如有疑问/bug,欢迎指出! %include "pm.inc" org 0700h jmp LABEL_BEGIN [section .GDT] ;GDT ; 段基址, 界限, 属性 LABEL_GDT: Descriptor 0, 0, 0 LABEL_DESC_CODE32: Descriptor 0, SegCode32Len-1, DA_C+DA_32;这里的寻址方式似乎又出现了问题 LABEL_DESC_VIDEO: Descriptor 0B8000h, 0ffffh, DA_DRW ;GDT结束 GdtLen equ $ - LABEL_GDT ;GDT长度定义 GdtPtr dw GdtLen-1 ;GDT界限 dd 0 ;GDT基址 ;GDT选择子 SelectorCode32 equ LABEL_DESC_CODE32 - LABEL_GDT SelectorVideo equ LABEL_DESC_VIDEO - LABEL_GDT ; ;end of [section .GDT] [section .16] ;16位代码段 [BITS 16] ;原始指令,表示运行在16位处理器上 LABEL_BEGIN: ;将所有段寄存器和SP填好,这只是为了程序的完整性 ;实际上除CS外的段寄存器,都并不会被用到 MOV AX,CS MOV DS,AX MOV SS,AX MOV ES,AX MOV SP,100H ;填写GDT中的descriptor XOR EAX,EAX MOV AX,CS SHL EAX,4 ADD EAX,LABEL_SEG_CODE32 ;将32位代码段的 起始物理地址的 前16位,写入段描述符的第3/4个字节内 MOV WORD [LABEL_DESC_CODE32+2],EAX;LABEL_DESC_CODE32代表着地址 SHR EAX,16 MOV BYTE [LABEL_SEG_CODE32+4],AL MOV BYTE [LABEL_SEG_CODE32+7],AH ;将32位代码段的 起始物理地址的 前16位,写入段描述符的第5/8个字节内 ;GDT中所有段描述符填写完成 ;填写GDT寄存器的基地址 XOR EAX,EAX MOV AX,CS SHL EAX,4 ADD EAX,LABEL_GDT ;LABEL_BEGIN也是地址 MOV WORD [GdtPtr+2],EAX ;GdtPtr也是地址 ;GdtPtr填写完成,低字节为段界限,高2字节为GDT的起始物理地址(32位) ;装入gdtr寄存器 LGDT [GdtPtr] ;也是地址 ;装入完成 ;关中断 CLI ;中断关闭完成 ;开启A20地址线 IN AL,92H OR AL,00000010B OUT 92H,AL ;开启成功,内存不再回卷 ;置位,即将打开保护模式 MOV EAX,CR0 OR AX,1 MOV CR0,EAX ;置位完成 ;跳转 下面这句话编译后生成的是:jmp 0x0008H:00000000 偏移量是32位,而0x0008H不是基地址,而是段选择符的地址 JMP DWORD SelectorCode32:0;此时SelectorCode32究竟是“SelectorCode32 equ LABEL_DESC_CODE32 - LABEL_GDT”这句话的偏移地址还是“LABEL_DESC_CODE32 - LABEL_GDT” ;上面这句话已经是在保护模式下了,cpu接到这条指令后,将会自动在selectorcode32选择符中提取索引 ;找到段描述符,提取段基地址,加上偏移量后进行寻址 ;不加 dword时,如果后面偏移量不是0,可能会发生截断(0x95357454H->0x7454H) ;end of [section .16] [SECTION 32] ;32位代码段 [BITS 32] LABEL_SEG_CODE32: MOV AX,SelectorVideo MOV GS,AX ;将video选择子的地址放入gs中 ;显示字 MOV EDI, (80*11+79)*2 ;11行,79列 MOV AH,0CH ;黑低红字 MOV AL,'P' MOV [GS:EDI],AX ;覆写显存 ;显示完成 JMP $ SegCode32Len equ $-LABEL_SEG_CODE32 ;end of []
对实模式—>保护模式的跳转进行了更加详尽的注释。
其余的部分请大家看于渊老师的《Orange's》一书。
然后是一致/非一致代码段的call/jmp限制(保护模式下不能随意jmp执行的),做了一个思维导图:
如果我们在甲段;想访问乙段(一致段),那么只要乙>=我们,就可以访问:
接下来谈一谈描述符属性:也是很复杂的事情。
找到了一篇很好的文章:段描述符和段选择符解析,通过这文章,暂时明白了段描述符的意义。
新知识:
1.段界限值(20bit=1M),在G=0(不允许分页情况下),代表段最大长1M个字节,即段最大为1MB
在G=1(允许分页下),代表段最大长1M个页(1个页4kb),即段最大4GB
2.系统段描述符一般都在中断/异常描述符表中
相关文章推荐
- [系列]OS学习-自己写操作系统(4)- 保护模式
- 《Orange's 一个操作系统的实现》学习笔记(二) 实模式和保护模式
- 自己动手写操作系统 实模式到保护模式 GDT表
- [系列]OS学习-自己写操作系统(5)-loader的产生
- [系列]OS学习-自己写操作系统(1)
- [系列]OS学习-自己写操作系统(2)- bochs的使用注意
- 《自己动手做操作系统》保护模式阅读报告
- 《Orange's 一个操作系统的实现》学习笔记--实践认识保护模式
- 学习笔记:一个操作系统的实现--保护模式之基础知识
- 学习x86时,自己写的一个引导,从实时模式到保护模式
- 一个操作系统的实现:关于保护模式和实模式的跳转和段描述符高速缓冲寄存器
- <自已动手写操作系统> 学习扎记让操作系统走进保护模式
- 自己动手写操作系统--搭建保护模式下的运行环境:bochs下安装freedos
- 操作系统学习笔记——保护模式——分段机制
- 《Orange's 一个操作系统的实现》学习笔记--保护模式理论初步(一)
- 《Orange's 一个操作系统的实现》学习笔记--保护模式理论初步(二)
- 操作系统学习笔记——保护模式——中断和异常(1)
- 自己动手写操作系统--搭建保护模式下的运行环境:bochs下安装freedos
- <自已动手写操作系统>学习扎记之保护模式(x86)
- 操作系统实验二:从实模式跳转到保护模式