最近在学习Linux0.12内核,正在读《Linux内核完全剖析》。一开始就被ax86写的引导扇区弄晕了。于是Google了很多资料。最终实验了一晚上终于搞定。下面来看看我们怎么用Windows下的MASM来写个Boot Sector。因为我MASM汇编用的比较熟,所以就用MASM来写,当然,汇编只有语法差异,你用什么来写都没关系。
首先,先来说说计算机怎么启动的。经过一系列BIOS加电、系统自检后,会将硬盘0面0道1扇区的512字节(Boot Sector)加载到内存地址07c0:0000处,之后就是执行这个Boot Sector部分了。而我们要写的就是这部分。这部分之后会引导操作系统启动,我们暂时不管这些。
需要注意的是,系统会检查内存地址07c0:01FE处是否等于0xaa55,不等于则报错。
既然知道了系统会把前512扇区加载内存,那么我们就要在汇编里做些设置。
源码如下:
data segment org 07c00h ;将程序加载到07c0:0000处 start: mov ax,data mov es,ax ;后面的字符串寻址输出需要es:bp mov bp,offset msg1 lop:mov ah,13h ;第10h中断向量的功能代码13h---写字符串 mov al,0 ;写模式 使用0就可以 mov bh,0 ;0页,默认为0页即可 mov bl,07 ;显示属性,黑底白字 mov cx,32 ;字符32个,更科学的方法是两个标号相减,为了简化代码,直接数出来 mov dh,10 ;输出在第10行 mov dl,24 ;输出在第24列 int 10h ;10h 使用第10h中断向量,显示器输出 jmp lop ;死循环,让字符保持在屏幕上 ret msg1 db "Welcome to my Operating System !" org 07c00h+512-2 ;地址计数器跳到512字节的倒数第二字节,即07c0:01FE DW 0AA55H ;此处在512字节的最后两字节写入AA55H !! data ends end start
然后把这汇编用MASM编译即可。我用的MASMPlus,其实都一样,只不过编译器不同。MASM不支持鼠标,麻烦点。
其实编译运行后我们的字符串已经显示出来了。
但是这并不是我们的目的,我们要写Boot Sector。
我们找到编译出来的exe文件,下面用WinHex工具把exe前面的PE文件头去掉,只留下我们需要的512字节。
先找到最后的55AA(高字节在后,低字节在前,所以是55AA),
然后向上选择512字节,
然后导出新的EXE,“编辑”--“复制选块”--“至新文件”
这是裁剪后的
然后就要使用软盘引导,但是现在这年代哪来的软盘,于是我们可以用软盘镜像,直接挂到虚拟机上。
启动Linux系统,用dd命令做个空的floppy镜像。
将我们裁剪好的myboot.exe拖到虚拟机里。不用管它是什么exe文件,现在扩展名去掉都可以,失去作用了。
用dd命令将myboot.exe文件写入myflp.img软盘镜像
好的,现在软盘镜像制作完成,下面开始虚拟机引导。
将做好的myflp.img拖到Windows上。
然后新建虚拟机,操作系统全选'Other',网络连接可以不要,内存8M,硬盘3M。
然后“编辑虚拟机设置”,在软盘驱动器挂上myflp.img,勾上“打开电源时连接”,确定。
好了,开机吧。
完成了,这就是自己用MASM写的Boot Sector。以后可以加上操作系统的内容,让它真正的引导起我们自己的操作系统。这只是个开始。
我是内核新手,写博客只为记录自己的历程,欢迎各位指正,也希望有兴趣的可以一起交流。