内核装载
0x7c00
固件程序 BIOS 会将硬盘中启动区的 512 字节的数据,原封不动复制到内存中的 0x7c00 这个位置,并跳转到这个位置进行执行
只要硬盘中的 0 盘 0 道 1 扇区的 512 个字节的最后两个字节分别是 0x55 和 0xaa,那么 BIOS 就会认为它是个启动区。
0x07c0
段基址向右移动四位,成为0x7c00, 即最开始存储内核程序的位置
写入到ds寄存器中,作为数据段基址
设置段寄存器值
0x90000
es附加段寄存器值,后序还需要复制给cs代码段寄存器、ds数据段寄存器、ss栈段寄存器
需要将存储在0x7c00中的内核程序移动个位置到0x90000
0xFF00
sp栈基址寄存器存储的值,此时实际栈顶位置为ss:sp也就是0x9FF00
加载内核代码
0x90200
加载setup程序部分,将硬盘的第 2 个扇区开始,把数据加载到内存 0x90200 处,共加载 4 个扇区
0x90200 + gdt
这里的gdt表示在setup.s中的偏移量,即全局描述符表是跟随着setup.s在最开始一起加载的,gdt就是用来获取各个段的段基址,然后和需要访问的内存的偏移地址计算出来得到物理地址
gdt中存储着代码段、数据段地址、LDT局部描述符地址
gdt的值存储在gdtr寄存器中
0x90200 + idt
同上,该内存地址中存储的是中断描述符表,地址值存储在idtr寄存器中
0x10000
加载system程序部分,从硬盘第 6 个扇区开始往后的 240 个扇区,加载到内存 0x10000
系统一些基本信息
内存地址 长度(字节) 名称 0x90000 2 光标位置 0x90002 2 扩展内存数 0x90004 2 显示页面 0x90006 1 显示模式 0x90007 1 字符列数 0x90008 2 未知 0x9000A 1 显示内存 0x9000B 1 显示状态 0x9000C 2 显卡特性参数 0x9000E 1 屏幕行数 0x9000F 1 屏幕列数 0x90080 16 硬盘1参数表 0x90090 16 硬盘2参数表 0x901FC 2 根设备号最后一次复制
0x10000 - 0x90000
移动到 0x00000 - 0x80000
因为最开始的bootsect不需要了
进入保护模式后新的地址
重新设置gdt、idt从内存0开始而不是从0x90200
开始
-
0
: 页目录表,存储在cr3寄存器,表示0地址处就是页目录表 -
0x1000
: 页表0 -
0x2000
: 页表1 -
0x3000
: 页表2 -
0x4000
: 页表3