操作系统执行的第一步,自然是将自身装入内存。自己将自己装入内存,这听起来有点不可思议:操作系统不可能是全部由自身装入的。因为在自身被装入系统前,操作系统根本不可能运行。因此,操作系统的某一部分必然是被硬件直接装入内存的。一般来说,一个计算机系统会和操作系统约定:系统启动后会将启动设备(如硬盘)上的某个固定位置的程序装入内存。而操作系统则将它的第一部分放在约定的位置,从而可以被硬件装入内存
在 PC 体系结构中,计算机加电起动后, BIOS 自检程序将会运行。在自检结束后, BIOS 会将硬盘的第一个扇区,也就是主引导扇区,读入内存中的一个固定的地址: 0x07c0:0000 。因此硬盘上这个扇区中的程序将会自动加载运行。通常主引导扇区中的程序会负责将硬盘上活动分区的引导程序读入内存。然后由分区引导扇区来读入真正的操作系统。换句话说,放在主引导扇区中的代码将由硬件自动装入内存。
下面我们来试着编写一段主引导记录(注,这段代码修改自 Singularity 源代码,我将在完成所有工作后重写 MBR 代码)。这段程序中涉及了硬盘分区表,读者可以不用太关心,我将在下一篇文章详细介绍这个数据结构。在编译链接下面这个程序的时候,我们用到了一个工具: Link16 。这是个 16 位的链接器,可以在 singularity 的工具目录中找到。读者也可以使用任何一个 16 位链接器来完成这个工作。
编译程序
ML /nologo /c /omf /Cp /AT /Fl"MBR.lst" /Fo"MBR.obj" MBR.ASM
Link16 /nologo /tiny MBR.obj,MBR.bin
现在找个工具将这段程序写入一个已经分好区的硬盘镜像,在 bochs 中启动调试,我们就可以清楚地看到程序的执行了。