FAT12格式的引导程序
在上一篇文章中详细介绍了FAT12格式的引导扇区数据结构,详情请浏览:
地址是:http://blog.sina.com.cn/s/blog_3edcf6b80100cr08.html
现在我们来编写一个简单的符合FAT12格式的引导程序,用它来领略一下程序的力量,并以此来敲开操作系统神秘的大门。
其实,只要是在0磁头0柱面1扇区中的指令能加载到7c00h处运行的程序,并且在扇区最后两字节分别是55和AA,就可以称为有效的引导扇区,能成功的引导系统,那么为什么还要大费周章的编写符合FAT12格式的引导程序呢?这样做的好处有以下几点:
1、兼容性佳:FAT12格式是Mirosoft公司开发的标准格式,基本上所有的操作系统都支持FAT12。
2、调试简单:在编写引导程序或操作系统的时候,总是要不断的添加、更新、删除文件以测试程序,使用FAT12格式的时候,只需要将磁盘接上Windows或Linux就可以操作不同的文件。
3、使用方便:为了快速测试程序和不损耗硬件,一般情况下是使用虚拟机加载IMG软盘镜像来达到测试的目的,这时候使用WinImage等软件来操作或编辑标准的FAT12格式的IMG软盘镜像就非常的方便了。
现在来看看这个简单的引导源程序,使用的NASM语法:
;--------------------------------------------------------------------------------
;名称:boot.asm
;用途:符合FAT12格式的引导程序
;作者:土土龙()
;--------------------------------------------------------------------------------
org 07c00h
jmp short start
nop
BS_OEMName: db 'MSWIN4.1'
BPB_BytsPerSec: dw 512
BPB_SecPerClus: db 1
BPB_RsvdSecCnt: dw 1
BPB_NumFATs: db 2
BPB_RootEntCnt: dw 0e0h
BPB_TotSec16: dw 0b40h
BPB_Media: db 0F0h
BPB_FATSz16: dw 9
BPB_SecPerTrk: dw 12h
BPB_NumHeads: dw 2
BPB_HiddSec: dd 0
BPB_TotSec32: dd 0
BS_DrvNum: db 0
BS_Reserved1: db 0
BS_BootSig: db 29h
BS_VolID: dd 0
BS_VolLab: db ' '
BS_FileSysType: db 'FAT12 '
start:
mov ax,cs
mov ds,ax
mov es,ax
mov ax,BS_OEMName
mov bp,ax
mov cx,8
mov ax,01301h
mov bx,0ch
mov dl,0
int 10h
jmp $
times 510-($-$$) db 0
dw 0aa55h
;--------------------------------------------------------------------------------
;程序结束
;--------------------------------------------------------------------------------
程序非常的简单,首先是使用org 07c00h使程序加载到07c00h处,因为BIOS在搜索引导扇区的时候,会把有效的启动扇区(512B)加载到07c00h处,然后再跳转到这里继续引导操作系统。接着是一个短跳转指令,指向引导代码部分start,这里也可以使用jmp start的普通跳转指令(3字节长),然后把下面的空操作nop删除,作用都是为了操持FAT12数据结构的起始偏移位置为3,标准的Windows或MS-DOS格式的磁盘上的指令都是短跳转,这里为了兼容性所以使用了相同的指令。
接下来的部分一直到start为止,就是FAT12的数据结构,这些字段的取值和用途请参阅“FAT12格式的引导扇区数据结构”(地址是:http://blog.sina.com.cn/s/blog_3edcf6b80100cr08.html),所有字段的取值都是默认值。
代码的开始将ds数据寄存器和es附加数据寄存器的值设置为cs代码寄存器的值相同,即为07c00h,然后调用int10h中断打印OEM字符串。
显示字符串后的代码是jmp $,它的作用是跳转到自己的行中,$表示汇编后的当前行地址,也就是死循环。因为这里只是一个引导程序的简单的例子,所以编写到这里就可以结束了,表现为BIOS引导系统后显示字符串系统就死掉了。
代码times 510-($-$$) db 0的作用是将代码结束后一直到510的空间中填充为0,times是表示重复的关键字(NASM伪代码),$表示汇编后的当前行地址,$$表示汇编后的此节的首地址(即07c00h)。
最后的0aa55是引导结束标志,用低字节在前高字节在后的方式存储,BIOS将根据此标志来验证引导扇区的有效性。
将源文件保存为boot.asm(或其它名称),可以这样将它汇编为纯二进制代码:
nasm boot.asm -o boot.bin
注意:汇编的参数-o是字母o,而不是数字0。
汇编后可以得到512字节长的boot.bin纯二进制代码文件,将这个文件拷贝到软盘的0磁头0柱面1扇区中就可以用它来引导系统了,直接拷贝当然是不可行的,因为无法直接将文件拷贝到磁盘的引导扇区中,下面我们来详细叙述一下如何将这个引导代码文件写入到软盘的引导扇区中。
首先可以使用WinImage或Vitual PC 2007来生成一个软盘的IMG镜像文件,Vitual PC 2007生成的镜像文件后缀名为vfd,将它改成img即可。
1、用Vitual PC 2007生成软盘镜像文件的详细步骤:
首先启动“Microsoft Vitual PC 2007”。
然后点击“文件”下的“虚拟磁盘向导”。
出现“欢迎使用虚拟磁盘向导”时,单击“下一步”。
选择“创建一个新磁盘”,然后单击“下一步”。
注意,这里要选择“虚拟软盘映像”,然后单击“下一步”。
在名称和位置上输入需要保存的目录和文件名称,如“D:\nasm\boot.vfd”,请不要在这里直接将文件的后缀名改为img,而且也改不了。选择“1.44 MB(高密码)”后单击“下一步”。
最后出现“完成虚拟磁盘向导”时,单击“完成”,就可以生成软盘镜像文件了。
然后,我们需要将Vitual PC 2007生成的软盘镜像文件的后缀名改为img。依次单击“开始”、“所有程序”、“附件”、“命令提示符”,就可以DOS方式的命令行界面了。
以刚才的保存镜像文件时输入的“D:\nasm\boot.vfd”为例,输入“D:”命令以切换到D盘,然后输入“CD \nasm”以进入到nasm目录,最后输入“ren boot.vfd boot.img”就可以成功将boot.vfd改成boot.img了。输入“dir boot.img”看看,是不是有一个名称为“boot.img”且长度为1,474,560字节的文件?在“我的电脑”中的相应文件位置也是可以将后缀名修改的,提前是必须显示相应的后缀名,具体步骤请参阅其它内容。
2、用WinImage生成软盘镜像文件的详细步骤:
首先启动WinImage。
打开“文件”菜单,单击菜单中的“新建”命令。
在“格式化选择”中选择“1.44 MB”,然后单击“确定”。
然后打开“文件”菜单,单击菜单中的“保存”命令。
选择镜像文件保存的路径,输入文件名,如boot,保存类型请选择“映像文件 (*.ima)”。IMA和类型和IMG是相同的,无须更改后缀名。
经过以上的两种方式我们生成了一个软盘镜像文件,现在需要将引导代码写入到镜像文件中了。这里也有两种写入的方式,分别详细的叙述操作的步骤。
1、用WinImage来写入到引导区的详细步骤:
启动WinImage后,打开“文件”菜单,单击菜单中的“打开”命令。
选择之前保存的磁盘镜像文件“boot.img”或者“boot.ima”。
打开“映像”菜单,单击菜单中的“引导扇区属性”命令。
在弹出的“引导扇区属性”对话框中,单击“打开”按钮。
浏览并选择经过汇编后生成的引导程序,如:“boot.bin”,然后单击“打开”按钮以选择引导文件并关闭对话框。注意此处所选择的文件长度应该是512字节,文件类型是BIN启动文件。
返回到“引导扇区属性”对话框时,看看“OEM 字串”的信息应该是引导程序中的“BS_OEMName”字段,在这里也就是“MSWIN4.1”,然后单击“确定”按钮以确认写入引导扇区并关闭对话框。
返回到WinImage主界面中,打开“文件”菜单,单击菜单中的“保存”命令,最后退出WinImage,即可以把引导文件写入到软盘镜像的引导扇区中了。
2、用FloppyWriter来写入到引导区详细步骤:
FloppyWriter.exe是《自己动手写操作系统》这本书的随书光盘里的一个小工具,专门用于将引导文件写入到磁盘的引导扇区中,非常的好用。
打开FloppyWriter工具。单击“Write File to Image”按钮以写入磁盘镜像文件。
浏览并选择经过汇编后生成的引导程序,如:“boot.bin”,然后单击“打开”按钮以选择引导文件并关闭对话框。注意此处所选择的文件长度应该是512字节,文件类型是Binary files(*.bin)启动文件。
选择之前保存的磁盘镜像文件“boot.img”或者“boot.ima”,如果无法浏览,则在文件类型中选择“All(*.*)”即可,然后单击“打开”按钮以选择磁盘镜像文件并关闭对话框。
最后,成功写入到磁盘镜像文件会出现以下对话框,单击“确定”按钮关闭它以完成写入引导代码的操作。
好了,引导程序也成功的写入到引导扇区了,此时应该进入历史性的一刻了。
我们先建立一个虚拟机来测试我们之前编写的引导程序。
打开Microsoft Vitual PC 2007。如果此时还没有建立任何的虚拟机,会立即弹出“新建虚拟机向导”的欢迎窗口。
当然,如果已经存在虚拟机,也可以打开“文件”菜单,单击菜单中的“新建虚拟机向导”来打开上面的欢迎窗口。
选择“新建一台虚拟机”,单击“下一步”按钮。
在名称和位置下面的文本框中输入此虚拟机的名称,还可以单击“浏览”按钮以选择此虚拟机文件的存储位置,在这里输入“MeOS”为例,然后单击“下一步”按钮。
在操作系统类型中选择“其他”,单击“下一步”按钮。
新建默认的虚拟的内存大小为128MB,如果觉得不够就可以选择“更改分配内存大小”来设置此虚拟机的内存。在这里设置虚拟机的内存为256MB,然后单击“下一步”按钮。
在虚拟硬盘选项中,选择“新建虚拟硬盘”,单击“下一步”按钮。
在虚拟硬盘位置窗口中,在名称和位置下面的文本框中输入储存虚拟机硬盘目录和文件名称,在虚拟硬盘大小中输入数值,一般默认即可,单击“下一步”按钮。
最后,单击“完成”按钮就可以成功完成新建虚拟机的操作了。
这样,系统中就有一台可以运行的虚拟机了。选择它(这里是MeOS),然后单击“启动”按钮来运行它。
这就是虚拟机的启动界面,跟真实机器的启动相同吧。此时请打开“软驱”菜单,单击“载入虚拟软盘映像”命令以加载我们编写并制作的引导磁盘。
浏览并选择之前制作的磁盘镜像文件“boot.img”或者“boot.ima”,单击“打开”按钮以加载引导磁盘镜像文件。
虚拟系统将继续启动,如果系统启动失败后才加载引导磁盘镜像,将它复位就可以了。
激动人心的一刻开始了。看看虚拟系统的屏幕上显示的是什么?红色的“MSWIN4.1”!这就是我们自己的操作系统,虽然现在什么也做不了,但只要持之以恒,总有一刻可以让它旗帜飘扬!
到此,我们完成了自己的引导代码编写,并成功的让它运行了起来。其实操作系统也没有想像中的神秘,到底它也只是一段代码而已。在之后的文章中,将继续介绍加载系统核心、保护模式、任务切换、图形编程、中断处理等精彩纷呈的内容。
我的电脑我做主,我使用自己的操作系统!
附录1:如果需要使用3.5寸1.44MB高密软盘来测试引导系统,可以使用HDCOPY将制作好的磁盘镜像文件写入到磁盘中,用这张磁盘即可引导系统。同时,如果将这段简单的引导代码写入到硬盘的引导扇区中,也是可以启动系统的。
附录2:文章中所用到的软件下载
nasm:
WinImage: http://www.winimage.com/download.htm
Microsoft Vitual PC 2007:
FloppyWriter:
HD-COPY:
以上的下载地址或许年久失效,请于各大搜索引擎中查询,或来信()向我索取。