操作系统开发系列—12.b.从Loader跳入保护模式

现在,内核已经被我们加载进内存了,该是跳入保护模式的时候了。

首先是GDT以及对应的选择子,我们只定义三个描述符,分别是一个0~4GB的可执行段、一个0~4GB的可读写段和一个指向显存开始地址的段:

; GDT
;                            段基址     段界限, 属性
LABEL_GDT:	    Descriptor 0,            0, 0              ; 空描述符
LABEL_DESC_FLAT_C:  Descriptor 0,      0fffffh, DA_CR|DA_32|DA_LIMIT_4K ;0-4G
LABEL_DESC_FLAT_RW: Descriptor 0,      0fffffh, DA_DRW|DA_32|DA_LIMIT_4K;0-4G
LABEL_DESC_VIDEO:   Descriptor 0B8000h, 0ffffh, DA_DRW|DA_DPL3 ; 显存首地址

GdtLen		equ	$ - LABEL_GDT
GdtPtr		dw	GdtLen - 1				; 段界限
		dd	BaseOfLoaderPhyAddr + LABEL_GDT		; 基地址

; GDT 选择子
SelectorFlatC		equ	LABEL_DESC_FLAT_C	- LABEL_GDT
SelectorFlatRW		equ	LABEL_DESC_FLAT_RW	- LABEL_GDT
SelectorVideo		equ	LABEL_DESC_VIDEO	- LABEL_GDT + SA_RPL3

在之前学习保护模式时,大部分描述符的段基址都是运行时计算后填入相应位置的,因为那时我们的程序是由BIOS或者DOS加载的,我们不知道段地址,于是也就不知道程序运行时在内存中的位置。

如今,Loader是由我们自己加载的,段地址已经被确定为BaseOfLoader,所以在Loader中出现的标号(变量)的物理地址可以用下面的公式来表示:

标号(变量)的物理地址=BaseOfLoader*10h+标号(变量)的偏移

我们把它以及相应的声明放在load.inc中。

BaseOfLoader	    equ	 09000h	; LOADER.BIN 被加载到的位置 ----  段地址
OffsetOfLoader	    equ	  0100h	; LOADER.BIN 被加载到的位置 ---- 偏移地址

BaseOfLoaderPhyAddr equ	BaseOfLoader*10h ; LOADER.BIN 被加载到的位置 ---- 物理地址

BaseOfKernelFile    equ	 08000h	; KERNEL.BIN 被加载到的位置 ----  段地址
OffsetOfKernelFile  equ	     0h	; KERNEL.BIN 被加载到的位置 ---- 偏移地址

我们定义了一个宏BaseOfLoaderPhyAddr用以代替BaseOfLoader*10h,它在loader.asm中被用到一次,用来计算GDT的基址。

运行结果如下:

 

一个码农的日常 

源码

转载于:https://www.cnblogs.com/joey-hua/p/5401060.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值