- [OS64位][016]源码阅读:代码清单3-25~3-27
- [C语言]模拟内存物理页,申请连续64个物理页,对应位图置1
- [OS64位][014]源码阅读:代码清单3-18 ~ 3-22
- [OS64位][015]源码阅读:代码清单3-23 ~ 3-24
- [OS64位][005]源码阅读:代码清单3-6 软盘读取 Fu
- [OS64位][009]源码阅读:代码清单3-9 根据FAT表项
- [OS64位][006]源码阅读:代码清单3-7 目标文件搜索
- [OS64位][017]源码阅读:代码清单3-28~3-37 保
- [OS64位][010]源码阅读:代码清单3-10 从FAT12
- [OS64位][007]源码阅读:代码清单3-8 INT 10H
学习笔记
使用教材(配书源码以及使用方法)
《一个64位操作系统的设计与实现》
http://www.ituring.com.cn/book/2450
https://www.jianshu.com/p/28f9713a9171
源码文件
- 第3章\程序\程序3-4\
loader.asm
1、进入保护模式前需要准备的系统数据结构
代码清单3-25 Line 29~40 :开启保护模式需要的系统数据结构 GDT 表
[SECTION gdt]
LABEL_GDT: dd 0,0
LABEL_DESC_CODE32: dd 0x0000FFFF,0x00CF9A00
LABEL_DESC_DATA32: dd 0x0000FFFF,0x00CF9200
GdtLen equ $ - LABEL_GDT
GdtPtr dw GdtLen - 1
dd LABEL_GDT
SelectorCode32 equ LABEL_DESC_CODE32 - LABEL_GDT
SelectorData32 equ LABEL_DESC_DATA32 - LABEL_GDT
代码段和数据段的段基地址都设置在
0x 0000 0000
地址处
段限长为0x ffff ffff
,即段可以索引 0~4 GB内存地址空间
CODE32
代码段TYPE=1010
可读、可执行DPL=00
DATA32
数据段TYPE=0010
读、写DPL=00
-
GdtPtr
dw 后面是表界限、dd后面是表基地址(在开启分页之前,线性地址就是物理地址) -
GDT单个表项占用八个字节
GDT
-
段选择子
SelectorCode32
这里具体数值就是0x08
SelectorData32
这里具体数值就是0x10
- GDT表段描述符数值解读见参考资料
代码清单3-26 Line 712~721 : 处理中断和异常需要 IDT 表
- 开辟一段内存空间留给IDT表用
;======= tmp IDT
IDT:
times 0x50 dq 0
IDT_END:
IDT_POINTER:
dw IDT_END - IDT - 1
dd IDT
-
dq
=double quad
8个字节
2、模式切换,从实模式到保护模式
代码清单3-27 Line 479~494 :模式切换
- 在set the SVGA mode(VESA VBE)执行后继续执行
;======= init IDT GDT goto protect mode
cli ;======close interrupt
db 0x66
lgdt [GdtPtr]
; db 0x66
; lidt [IDT_POINTER]
mov eax, cr0
or eax, 1
mov cr0, eax
jmp dword SelectorCode32:GO_TO_TMP_Protect
-
mov cr0, eax
执行后,就已经进入到保护模式 -
jmp dword SelectorCode32:GO_TO_TMP_Protect
,jmp 代码段选择子:偏移 = jmp 0x08:xxxx,目的是改变处理器的执行流水线,进而使处理器加载执行保护模式的代码段
参考资料
- 段选择子 和 段描述符
[019][x86汇编语言]段描述符、段选择子格式(检测点11.1)
https://www.jianshu.com/p/0ec493a0287c
- 设置PE位,进入保护模式
cr0
https://wiki.osdev.org/CPU_Registers_x86-64#CR0
网友评论