概述
在计算机加电之后,bios检查硬件,并且把第一个扇区中的bootloader代码加载到0000: 07c00h处,开始执行bootloader代码.bootloader主要做两件事情:
- 从实模式进入保护模式
- 从硬盘(或者其他)中读取OS kernel到内存的固定位置处,然后跳转到OS中执行.
这里先讨论如何从实模式进入保护模式
参考链接:
- 学堂在线 - 清华大学OS课程
先让代码跑起来
- 先下在freedos,并将其中的a.img复制到代码在的工作目录,改名为freedos.img.下载链接:freedos
- 用bximg生成软盘映像,pm.img
- 修改bochsrc,添加下面三行
floppya: 1_44=freedos.img, status=inserted
floppyb: 1_44=pm.img, status=inserted
boot: a
# 相当于有两个软盘,软盘a作为bootloader,引导操作系统启动,软盘b里面放置我们自己
# 的对操作系统的操作(相当于操作系统内核)
- 启动Bochs,待FreeDos其中之后,使用
format b:
命令格式化B:盘 - 把代码编译成.com文件,
nasm pmtest1.asm -o pmtest1.com
- 把pmtest1.com复制到虚拟软盘pm.img上:一种拷贝方法,值得学习
sudo mkdir /mnt/floppy
sudo mount -o loop pm.img /mnt/floppy
sudo cp pmtest1.com /mnt/floppy
sudo umount /mnt/floppy
- 现在我们的.com文件已经拷贝到软盘pm.img中了,在freedos中使用
B:\pmtest1.com
即可执行
GDT(Global Descriptor Table)
参考:GDT,LDT,GDTR,LDTR 详解,包你理解透彻
GDT就是一个装有段描述符的大数组.在GDT中每一个段描述符占用8字节,段描述符最主要的包含两个信息:
- 段的起始地址(段基址)
- 段的大小(段界限)
代码段和数据段描述符如下所示:
GDT表的基地址存放在GDTR寄存器中.GDTR是一个48位寄存器,其低16位保存GDT表的长度,高32位保存表的基址.所以GDT表的最大长度是1M,因为每一个描述符是8字节,所以一共可以存放213个段描述符,但是注意:第一个描述符为空,