在loader中创建GDT,进入保护模式

回顾
上一节实现了从BIOS中加载MBR,MBR从磁盘2扇区读取loader加载到内存0x900处,但loader目前尚未实现任何功能。

Q&A
Q1:loader在OS中主要做什么?
答:创建一些系统数据结构,如GDT,页表等,打开进入保护模式的开关。

Q2:保护模式与实模式主要有哪些不同?
答:
(1)寻址范围:实模式下共20根地址线,寻址范围1MB;进入保护模式会打开20根地址线的限制。
(2)访问限制:保护模式下段寄存器中存储的不再是段基址,而是段选择子,选择子中包含段描述符在全局描述符表中的索引,GDTR寄存器中存储全局描述符表在内存中的地址,通过索引可获取段描述符在内存中的地址,段描述符记录段的功能,权限信息。
GDTR寄存器结构:
在这里插入图片描述
选择子结构:
在这里插入图片描述
段描述符(汇编实现这个结构真是令人头大…)
在这里插入图片描述
非系统段type,共四位:
X :可执行/不可执行,代码段为1,数据段为0
C:代码段一致性,数据段扩展方向)
R:可读/不可读
A:cpu访问后置1,初始化为0

Q3:如何进入保护模式?
答(按顺序):
1、在内存中创建GDT,并初始化段描述符(初始化了代码段,数据段,显存段)
2、将控制寄存器CR0 PE位(第0位)置1,将0x92端口置1;
3、初始化GDTR寄存器,0-3位初始化为0,后32位填写GDT在内存中的起始位置。
4、将控制寄存器CR0 PE位置1,打开保护模式

开始动手

实现功能所需知识的补充
1、汇编lgdt指令,用于修改gdtr寄存器的值
2、bochs查看控制寄存器的命令:creg;查看gdt: info gdt
3、平坦模型:初始化三个段描述符,代码段,数据段,显存段。代码段和数据段采用平坦模型,即段基址为0,段界限0xffff,寻址范围4GB。
4、远跳转清空cpu指令流水线
修改CR0控制寄存器后,机器已经进入保护模式,但应在保护模式下执行的指令已经在实模式的环境下被放上cpu指令流水线,同时段描述符缓冲寄存器也是在实模式下加载的,所以需要使用jmp跳转指令清空指令流水线,然后重新加载段描述符缓冲寄存器。

5、dd命令,其实在上一节已经用过了,loader加载在2扇区,和mbr隔了一个扇区,因此需要跳过两个扇区,因此加上seek=2参数,loader大于512字节,因此count也需要修改,索性改为4。
代码loader.S

%include "boot.inc"
section loader vstart=0x900
LOADER_STACK_TOP equ 0x900
jmp loader_start
GDT_BASE:      ;全局描述符表定义在内存0x900处
dd 0x00000000
dd 0x00000000

CODE_DESC: dd 0x0000FFFF
           dd DESC_CODE_HIGH4

DATA_DESC: dd 0x0000FFFF
           dd DESC_DATA_HIGH4
VIDEO_DESC: dd 0x80000007
            dd DESC_VIDEO_HIGH4

GDT_SIZE equ $-GDT_BASE
GDT_LIMIT equ GDT_SIZE-1
times 60 dq 0         ;目前有三个描述符,预留60个描述符的空位
;三个描述符都是0特权级
SELECTOR_CODE equ (0x0001<<3)+TI_GDT+RPL0
SELECTOR_DATA equ (0x0002<<3)+TI_GDT+RPL0
SELECTOR_VIDEO equ (0x0003<<3)+TI_GDT+RPL0

gdt_ptr  dw  GDT_LIMIT
         dd  GDT_BASE

loader_start:
mov sp, 0x900    ;0x900以下可作为栈的地址
;open A20 address line ;打开A20地址线
in al,0x92
or al,0000_0010b
out 0x92,al

;initialize GDTR register ;初始化GDTR寄存器
lgdt[gdt_ptr]

;let CR0 register PE site equ 1  ;将CR0寄存器0位置1
mov eax,cr0
or eax, 0x00000001
mov cr0, eax
 jmp  SELECTOR_CODE:p_mode_start	 ;跳转清空cpu指令流水线
;jmp $
p_mode_start:
mov ax, SELECTOR_DATA      ;初始化段描述符缓冲寄存器
   mov ds, ax
   mov es, ax
   mov ss, ax
   mov esp,LOADER_STACK_TOP
   mov ax, SELECTOR_VIDEO
   mov gs, ax
   jmp $

boot.inc是《操作系统真相还原》一书提供的配置文件,一开始自己写段描述符的各个位,调试了好久一直都表示不对,所以还是乖乖的用人家的配置文件吧,基本思路也是按照这本书上做的。
结果验证
加载GDT成功:
在这里插入图片描述
可以看见1,2,3三个代码段哈
creg查看控制寄存器CR0第0位:
在这里插入图片描述
OK了,其实还有很多细节有待考究,调试的时候还出了好多莫名其妙的错误😂 以后还会补充。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值