构建自己的操作系统[1]-引导程序

来源:互联网 发布:吕斌拳击 知乎 编辑:程序博客网 时间:2024/05/16 06:25
 
    这几天一直在看Linux 0.11的内核,也在看国内一些小操作系统的代码,LearnOS,Pretty,Iris。。。。想集合它们的一些优点,先做出一个简单的内核。

    学习操作系统是我一直想法,以前都只是停留在比较肤浅的层面上,学了一些比较大的理论知识,对于底层一点的东西还是一无所知。下个学期有<操作系统>这门课,知道课上也不会有什么太细致的讲解的,大纲安排的实验也不会太深入。不过终于可以有一点时间来进行我自己的实验了:-)

    今天正式开始动手实践,写了一个实验性质的引导程序。
    以下引自<谢煜波的实验报告>
[quote]
首先,我要先说明一下计算机在你按下电源按钮后,计算机都做了什么
当你按下电源键的时候,同这个键相联的电线就会送出一个电信号给主板,主板将此电信号传给供电系统,供电系统开始工作,为整个系统供电,并送出一个电信号给BIOS,通知BIOS供电系统已经准备完毕。随后BIOS启动一个程序,进行主机自检,主机自检主要工作是确保系统的每一个部分都得到了电源支持,内存储器,主板上的其它芯片,键盘,鼠标,磁盘控制器及一些I/O端口正常可用,此后,自检程序将控制权还给BIOS。
 
接下来,BIOS开始启动操作系统。
BIOS将访问启动盘的第一个扇区(0磁道,1扇区,一共是512字节),BIOS将这第一扇区中的内容调入内存的0x7c00地址处,并开始执行它。这是启动系统的第一关,从此之后,系统就将控制权将给操作系统了,留下的事情就由你的程序来完成。
 
现在我们的任务就是写这样一个程序,系统将它称之为引导程序,用它来引导或说启动我们的计算机。它有如下两个特点:
1。大小只能是512字节,不能多一字节,也不能少一字节。因为BIOS只能读512字节的数据到内存中,多的部份BIOS不会理采
2。它必须以"55 AA"结尾,即最后两字节(511,512)必须是它们。这是引导区程序结束的标志,没有它BIOS不会将它作为引导程序看待。(我以前的程序没有执行,就是因为没有在这里写"55 AA")
把这一程序放在磁盘的0磁道,1扇区里,这样,此磁盘就可以用来引导系统,而且是用的你自己做的引导程序!
 
在开始制作引导程序之前,先介绍一下怎样在Windows环境下进行这样的开发。
 
首先,需要一个实验环境,你当然可以就用真实的计算机,如果你有多台计算机的话,且不觉得麻烦的话。
这里我们使用虚拟机来进行实验,它与使用真实的计算机是一样的,不信待会儿你可以自己实验一下。
我用的是 MS Virtual PC,使用非常简单,这里就不多说了,它可以用一个1.44M大小的img文件,作为模拟软盘,因此,我们就只需把我们的引导程序写到一个img文件中,就如同写在了一张磁盘上面,就可以用它来引导系统。
启动虚拟机后,在Floopy菜单下,选Floopy Disk Image项,然后选到我们生成的那个img文件后,就可以了。
 
下面说说img文件的创建生成方法
要把引导程序写到这个1.44M的文件里面,我使用的是WinHex工具,它非常方便,可以直接通过拷贝完成二进制文件的写入,而且还可以创建指定大小的文件。
1.44M的img文件可以用WinHex来创建,点击新建按钮就行,大小输入1474560,单位字节。
到时后,把我们写的程序用WinHex打开,将其内容复制到生成的img文件下就行。
[/quote]
    讲启动过程讲得很细致,让我学到了不少知识。他的实验环境是在Windows下的,下面我说说Linux下实验环境的搭建。
   
    1   下载并安装一个虚拟机,我用的是VirtualBox
     2 VirtualBox的详细使用请参考它带的文档。在我们的img制作好了以后可以用虚拟机的Floppy进行启动引导
    3   下载Nasm汇编编译与链接器
   
    实验环境搭建好后就可以进行第一次实验了,一个最简单的引导程序。
    代码如下:

[BITS 16]                       ; 生成16位的程序
[ORG 0x7C00]                ; 从偏移位置为0x7c00处开始执行

xor ax
, ax
mov ds
, ax
mov es
, ax
call ShowMessage
jmp $                            
; $ 代表此语句的地址,表示在此语句此进行无限循环

ShowMessage:
    mov ax
, BootMsg
    mov bp
, ax                ; ES:BP=字串地址
    mov cx, 28                ; CX=字数
    mov ax, 0x1301         ; 设置显示模式
    mov bx, 0x000c        ; BH=页数,BL=颜色属性
    mov dl, 0                  ; 起始位置
    int 0x10
    ret

BootMsg: db 
"Hello, world! I'am l0y0l ^^!"       ; 定义提示信息,l0y0l是我的操作系统的名字:-)
times 510 - ( $ - $$ ) db 0                                ; 填充 0 以满足文件大小,凑够510字节
                    ; $ 表示当前语句的地址,$$ 表示程序的起始地址
db 0x55, 0xaa                ; 引导程序结束标志


    1  假设这个引导程序叫做"BootTester.asm",使用命令nasm BootTester.asm -o BootTest生成二进制文件
    2  使用命令dd if=BootTest of=BootTest.img 制作img文件
    3  用虚拟机的软盘引导功能进行引导
 

    代码中用到那个int 0x10中断请参看一些汇编语言程序设计的书,比如<IBM PC汇编语言程序设计>。
原创粉丝点击