主引导程序
主引导程序是一段存储于主引导区(
MBR)中的有效代码
主引导程序是可以修改的,所以不是固件,它
是操作系统的一部分
主引导程序是
启动操作系统的桥梁,
由汇编语言编写
主引导程序
运行于实模式(地址都是实际的物理地址)
主引导程序代码量
不能超过512字节(一般意义上的一个扇区的大小,
且包含结束标记0x55aa)
引导程序(英语:boot loader)位于电脑或其他计算机应用上,是指引导操作系统的程序。引导程序引导方式及程序视应用机型种类而不同。例如在普通的个人电脑上,引导程序通常分为两部分:第一阶段引导程序位于主引导记录(MBR),用以引导位于某个分区上的第二阶段引导程序,如NTLDR、BOOTMGR和GNU GRUB等。
摘自维基百科
主引导程序的开发
编程实现主引导程序
要求使用汇编语言编写
可独立运行于x86架构上(无操作系统)
运行后在屏幕上打印“Hello,DTOS!”
思路:
将关键寄存器的值设为0(mov ax, 0)
定义需要打印的数据(db "Hello,D.T.OS!")
打印预定义好的字符数据(int 0x10)
汇编提示
mov ax, 0 ; 将0赋值给ax寄存器
mov byte [0xb800:0x01], 0x07 ; 将0x07处的一个字节赋值给内存0xb800<<4+0x01处(=0xb8001,注:0xb8000-0xbFFFF是留给显卡的32KB的地址)
int 0x10 ; 触发0x10中断,对屏幕进行操作
hlt ; 使CPU进入暂停状态
$ ; 当前指令行地址
$$ ; 当前汇编段起始地址,可以使用$$-$方式获得当前代码已经占用的字节数
; ; 汇编的单行注释符号为‘;’
not_use macro
多行注释 ; 我没有验证过
endm
中断调用和函数调用的相识之处
MBR
将汇编代码编译成二进制机器码(nasm boot.asm -o boot.bin)
创建虚拟盘(bximage a.img -q -fd -size=1.44)
将二进制代码写入虚拟盘起始位置(dd if=boot.bin of=a.img bs=512 count=1 conv=notrunc)
在虚拟机中将虚拟盘作为启动盘执行(vmware)
代码
1 org 0x7c00 ; 从0x7c00处存储下面的代码 2 3 start: ; 汇编程序入口,相当于main();这里是用CS寄存器的值初始化SS、DS、ES寄存器以及设置存储msg标记的SI寄存器 4 mov ax, cs ; CS代码段寄存器(通常和IP寄存器配合使用),AX通用寄存器 5 mov ss, ax ; SS数据段寄存器 6 mov ds, ax ; DS堆栈段寄存器 7 mov es, ax ; ES附加段寄存器 8 9 mov si, msg ; SI源变址寄存器,此处用于记录msg标记的数据,此标记记录了MBR的地址(一般配合DS使用) 10 print: 11 mov al, [si] ; 把SI寄存器中的值作为内存地址去寻找对应的数据放入al寄存器([si]相当于C语言的*si),要打印的字符存储于AL寄存器,字符颜色存储于BL寄存器 12 add si, 1 ; 指向下一个字符位置,相当于C语言打印字符时的递增 13 cmp al, 0x00 ; 比较指令,不保存结果,但是会影响标志位,这里的意义是判断字符串结束符 14 je last ; 如果ZF标志位为0就跳转到last,意思是如果到了字符串结束符就停止打印(进入CPU暂停死循环) 15 mov ah, 0x0e ; 配置0x10中断所需数据,对ah寄存器写入0x0e(显示字符并右移光标,到最后时自动换行) 16 mov bx, 0x0f ; BX=BH+BL,BH设置页码,BL设置前景色;这里没发现存在的意义,注释掉未发现影响 17 int 0x10 ; 触发显示中断,打印字符 18 jmp print ; 循环打印直至结束 19 20 last: 21 hlt ; 暂停指令,时钟信号会停止,CPU收到复位或中断信号后又会恢复 22 jmp last 23 24 msg: 25 db 0x0a, 0x0a ; 设置两个换行 26 db "Hello, DTOS!" ; 设置打印字符串 27 db 0x0a, 0x0a 28 db 0x07, 0x07 ; 设置两个响铃 29 times 510-($-$$) db 0x00 ; 用0填充多余的空间 30 db 0x55, 0xaa ; 主引导区结束必须是0x55aa
将代码保存成boot.asm文本文件
以下操作在linux系统上,你或许需要安装相关软件(例如:nasm、bximage,其中dd是系统自带的命令)
使用
nasm boot.asm -o boo.bin命令编译代码
使用
bximage a.img -q -fd -size=1.44生成1.44MB的软盘
使用
dd if=boot.bin of=a.img bs=512 count=1 conv=notrunc将数据写入软盘(bs=大小、count=次数、conv=连续写入不能有空)
设置虚拟机为软盘启动,并将a.img作为启动镜像
(下图是采用bochs虚拟机在linux上运行,下一篇介绍bochs相关的内容;你也可以使用vmware,不懂请自行度娘)
最后5行就是我们输出的内容
(注意Hello,DTOS!前后都有两个换行)
这个MBR没有关机功能,你需要硬件级别的关机