操作系统,看起来是一个十分高大上的话题。其实,我们自己也可以尝试着捣鼓一个,这其实不是想象的那么困难,只是自己不知道怎么做而已。
相比你已经知道了从计算机上电之后,操作系统加载直至出现鼠标,登录,显示出桌面这个过程。如果不知道,那也没关系,笔者为你简单介绍一下这个过程。
上电之后,计算机主板的BIOS会进行一系列的检查(包括检查内存、硬盘等等),假设一切检查正常通过,那么,接下来BIOS会在内存中设定一些程序(一些简单的驱动程序),然后,BIOS读取启动设备的引导扇区,加载引导程序,执行。然后,引导程序负责了后面加载操作系统的内核(或者是一个loader,再由loader加载内核)。之后,内核开始运行。。。后面暂不涉及。我们现在关注第一个程序——引导扇区部分。
引导扇区,简单来说(在这里)就是启动驱动器的第一个扇区(512字节大小)并且其最后两个字节分别是 0x55,0xAA,这样,BIOS就会认为它是一个引导扇区并尝试加载运行。那么,我们只要将我们的程序写入到第一个扇区,并以 0x55,0xAA两个字节结尾,那么就可以用来启动我们的计算机了。
不过,这里还有一个问题,就是我们的引导扇区会被加载到哪里。在BIOS加载引导扇区的时候,会将其加载到内存的0x7c00处,然后开始执行该处代码。那么,我们在写代码的时候,也应该假设我们的程序会被加载到0x7c00方可得出正确的结果。
好了,我们开始写一个引导扇区吧。
首先准备一些工具:nasm(汇编语言编译器),bochs(模拟器,可以理解为虚拟机。笔者使用的是2.1版本),以及floppywriter(笔者自己写的一个将引导扇区写入软盘镜像的程序)
以上文件可以在http://pan.baidu.com/s/1qWLjhqW下载(本文所对应的一个压缩文件为01a.zip,其中包含文中所有代码)。
好了。我们先编写代码吧。
org 0x7c00
jmp entry
db 0x90
entry:
mov ax,0 ;设置段寄存器
mov ss,ax
mov ds,ax
mov es,ax
mov sp,0x7c00 ;设置栈顶指针
mov si,msg ;要打印的字符串所在地址
putloop:
mov al,[si] ;取出一个字符
add si,1 ;字符串指针后移
cmp al,0 ;取出的字符是否为'\0'
je halt ;如果是,则挂起系统
;不是则打印字符
mov ah,0x0e ;黑底白字
mov bx,15
int 0x10 ;调用已有的中断程序打印字符
jmp putloop ;继续打印
halt:
hlt
jmp halt
msg:
db "hello os world!"
db 0
times 510-($-$$) db 0
db 0x55,0xaa以上代码就是一个十分简单的引导扇区。代码。可能你已经迫不及待想运行看看效果了。好吧,先试试吧,把上面的代码另存为boot.asm,然后在命令行下跳到其所在目录,输入命令
nasm boot.asm -o boot.bin如果没有任何以外的话,你能够看到生成的boot.bin文件,大小为512字节,0x55,0xAA结尾,刚好符合引导扇区标准。然后将其写入软盘镜像。
floppywriter boot.bin helloos.img其中floppywriter是笔者写的一个程序,能将boot.bin写入到helloos.img这个软盘镜像的第一个扇区。好了,准备就绪。我们来运行一下。在本文的附件(01a.zip)中有一个这样的文件:
在你装好bochs后便会被自动关联,双击启动模拟器,接下来就是见证奇迹的时刻,我们的引导扇区在模拟器中成功引导。
好了。今天就到此为止吧,也许你对上面的代码一知半解,也许你还不知道bochs怎么配置,也许你还不知道bochsrc.bxrc那个文件是什么,那你就打开看看吧,探索一下吧,或许你有新的收获。笔者也会在接下来的文章中一一揭秘。敬请期待。
欲知后事如何,请看下回分解。(汇编代码到底是什么意思?floppywriter是怎么写的?我不想用模拟器,我想用它启动真实电脑,我想用U盘启动。。。)敬请期待。
谢谢,如有疑惑,可在评论中说明,如有疏漏,还请不吝赐教。
本文介绍了创建操作系统的第一步——引导扇区。当计算机上电,BIOS加载并通过检查后,会读取启动设备的引导扇区,执行引导程序。引导扇区是启动驱动器的第一个512字节扇区,以0x55,0xAA结尾。BIOS将其加载到内存0x7c00处执行。为了实现自定义引导扇区,你需要汇编语言编译器nasm、模拟器bochs和工具floppywriter。代码示例和详细步骤帮助你开始这段旅程。"
43196153,4944571,C#与VB.NET中AddHandler和RemoveHandler的使用示例,"['C#编程', 'VB.NET编程', '事件处理', '控件编程']
8039





