引导程序的编写

对于一个操作系统来说,如果没有一个引导程序是无法工作的。但是,引导程序却往往不被认为是操作系统的一部分。这也是为什么我们在安装多个操作系统的时候可以使用linux来引导windows,也可以使用windows的引导程序引导linux。但是,这里的引导是有附加条件的。那就是你必须做一些改动。不过,这个不是我们要讨论的。
那么,什么是引导程序呢?引导程序到底做了那些工作?他有起到了什么作用?有一个比喻是很贴切的。那就是我们可以把引导程序想像成药引子,如果说操作系统被看成是一副中药的话。
那么引导程序做了那些工作呢?不同的引导程序实现的具体功能是不一样的。比如GRUB和NTLD的功能就千差万别。不过有一句话道出了其中的共性,那就是“一个好的引导程序相当于一个小的操作系统”。
GRUB就是一个好的引导程序,他有shell,可以访问多种文件系统(包括ext2、FAT12/16/32、iso等等)。他甚至还包含了简单的内存管理。
不过无论他多么强大,他也只是一个引导程序。我们现在就来看一下如何写我们自己的引导程序。
首先,我们来了解一下为什么需要有引导程序,而不是机器一启动就进入操作系统呢?
在计算机加电以后,计算机会做些什么呢?首先,他会按照你的BIOS里面的设置读取各个驱动器的第一个扇区。以辨认一下有没有操作系统存在。然后,将第一个找到的符合要求的扇区读入内存并执行它。这个符合要求的扇区其实就是操作系统的引导程序。接着,这个引导程序会将操作系统的内核加载到内存并运行它。最后,就是操作系统里面的各种初始化(例如硬件的初始化,图形界面的初始化等等)。这样我们就进入了操作系统里面了。

下面我们就来看一下引导程序到底是个什么样子。在这一篇中我们只是感性的认识一下引导程序的样子,并学会编译和运行它。而不去研究其运行机理。下面就是一个masm版的最最简单的引导程序:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PRO_SIZE EQU 512 ; 引导程序的大小
orIGIN EQU 00H ; 引导程序被加载到的位置
.MODEL TINY
.386

.data
.CODE
orG orIGIN
assume cs:@code ,ds:@data

Public $begin
$begin:

start:
jmp main
main:
mov al, 'a'
mov ah, 0eh
int 10h
jmp $

; 填充剩下的空间,使生成的二进制代码恰好为512字节
Free EQU (PRO_SIZE - 4) - ($ - $begin)
if Free LT 0
%out 编译以后生成的程序超过了指定的大小,请检查PRO_SIZE是不是设置错了!注意:程序必须等于512字节(即PRO_SIZE=512)!
.ERR
endif
org origin + (PRO_SIZE-2)
db 55h,0aah ; 引导扇区标志
end start
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
上面这个引导程序就干了一件事,那就是将一个字符a打印到屏幕上。如果你学过汇编,完全可以在main和Free中间加上你自己的代码。这样就可以实现一些有趣的东西了。那个我事如何编译和运行的呢?编译脚本如下:
@echo off
ren myboot.bin 复件myboot.bin
set path=d:\masm\bin;c:\windows\system32;
set include=d:\masm\include;
set lib=d:\masm\lib;

ML /c /Fo myboot.obj myboot.asm
if errorlevel 1 goto err

link /TINY myboot.obj, myboot.bin, myboot.map, , ,
if errorlevel 1 goto err

:OK
echo ---------------------------
echo Build OK!
del /Q *.map
del /Q *.cod
del /Q *.obj
del /Q 复件myboot.bin
goto end
:err
echo ---------------------------
echo Build Failed!!!!!
cmd /K
:end
@echo on
至于制作ima映像的方法,需要使用我的上一个文章的一个方法。在这儿千万不能使用winimage。至于虚拟机可以使用vmware、bochs或qemu(我没有vpc,所以没有测试。不过,应该不会有问题)。
上面就是masm版的最最简单的引导程序。下面我们再看一个nasm版的最最简单的引导程序:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
org 07c00h ; 告诉编译器程序加载到7c00处
main:
mov al, 'a'
mov ah, 0eh
int 10h
jmp $
times 510-($-$$) db 0 ; 填充剩下的空间,使生成的二进制代码恰好为512字节
dw 0xaa55 ; 引导扇区标志
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
编译脚本如下:
@echo off

nasmw boot.asm -o boot.bin
if errorlevel 1 goto err

:OK
echo ---------------------------
echo Build OK!
goto end
:err
echo ---------------------------
echo Build Failed!!!!!
cmd /K
:end
@echo on
运行方法和上面的masm版本一样。

现在,我就揭开了引导程序的神秘面纱。但是,现在我们的引导程序还是如此的简陋,以至于没有任何的实际功能。再下一篇里面我们就是来详细的解释一下引导程序的编写方法并丰富一下我们的引导程序,让他干点事情。好了,今天就到这儿。我该休息了。




本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/qimingos/archive/2006/06/27/842378.aspx

文章来自: 本站原创
Tags:
评论: 0 | 查看次数: 9177