门徒进阶课第2课:Hello,DTOS

    科技2022-08-13  127

    问题:主引导程序是软件还是固件呢?如果是软件,那么是由谁来开发的?如何开发?

    主引导程序: 1、它是一段存储在主引导区(MBR)中的有效代码 2、它并不固化于硬件,属于操作系统代码的一部分 3、它是启动操作系统内核的桥梁,由汇编程序编写而成 4、代码总量是不能超过 512 个字节(包含 0x55aa 在内)

    主引导程序的开发 对比一般的应用程序: 1、主引导程序的的入口地址是 0x7c00,而一般的应用程序的入口地址为 main 函数; 2、主引导程序的语言是汇编,而一般的应用程序的语言则是常见的 C/C++; 4、主引导程序因为没有操作系统的概念,因此它最后调用的是 BIOS 中断,一般的应用程序最后是 OS 系统程序的调用。

    课程实验: — 编写一个主引导程序(基于汇编语言) — 可独立运行于 x86 架构的主机(无操作系统) — 运行后在屏幕上打印“Hello,DTOS!”

    实现思路: 1、先将关键寄存器的值设置为 0(mov ax, 0); 2、定义需要打印的数据(db "Hello, DTOS!"); 3、打印预定义好的字符数据(int 0x10)。

    关于汇编的知识点:

    1、mov:赋值操作,它是将右操作数赋值给左操作数。 如 mov ax, 0 代表的意思是将 0 赋值给 ax 寄存器 2int:触发中断。 如 int 0x10 代表的是触发 0x10 中断,对屏幕来进行操作 3、hlt:停止运行,CPU进入暂停状态,不再执行任何操作。 如 hlt 代表的是使程序进入睡眠状态 4、汇编中的地址访问方式是:段地址:段内偏移地址。 如 mov byte [0xb800:0x01], 0x07;那么此处的 0xb8000:0x01 可等价于 0xb8000 + 0x01,byte 代表的是后面的数据占用一个字节 5、标签。用于表示后续指令的地址(可等同于 C 语言中的标签,作用类似于 goto 跳转语句一样) 6、$ 和 $$。 $ 表示当前指令行地址,$$ 表示当前汇编段起始地址

    我们看到在一般的应用程序中 printf 的 %c 对应于在主引导程序中是用两条 mov 指令来完成的,参数 ‘c’ 对应于主引导程序中的 mov al, ‘c’。那么在一般的应用程序到此就编写完成了,而主引导程序还加了一句 int 0x10。因为一般的应用程序是基于操作系统来编写的,后续的处理由操作系统来完成;而主引导程序则是没有操作系统的,后面的 CPU 挂起工作就交由编写者自己来完成了。

    下来我们来编写一个用于引导加载的程序,如下

    boot.asm 源码

    org 0x7c00 // 定义起始地址 start: //将关键寄存器的值设置为0 mov ax, cs mov ss, ax mov ds, ax mov es, ax mov si, msg // 将 msg 所代表的标签地址放到 si 寄存器中 print: mov al, [si] // 将 si 中所代表的内容取出来,类似于 C 中的*(头地址) add si, 1 // 将地址 + 1 cmp al, 0x00 je last // 如果上面定义的 al 和 0x00 相等,则跳转到 last mov ah, 0x0e mov bx, 0x0f int 0x10 // 触发中断 jmp print // 类似于 C 中的 while 循环 last: hlt // 跳转完成,CPU 挂起 jmp last // 循环跳转 msg: db 0x0a, 0x0a // 定义换行符 db "Hello, DTOS!" // 定义打印数据 db 0x0a, 0x0a times 510-($-$$) db 0x00 // 将 510 - 上面代码所占用的字节,因为 msg 也占用字节,所以是 510 // $ 代表本行的地址数,$$ 代表上面全部代码的地址个数 db 0x55, 0xaa

    我们在完成引导程序的编写之后,应如何来验证所编写的程序呢?这时我们便可以利用 VMWare 来创建一个空的虚拟机,基于它来验证我们所写的汇编程序。

    具体思路是:首先将汇编代码编译为二进制机器码(nasm指令),紧接着创建虚拟盘(bximage);然后将二进制 diamante 写入虚拟盘起始位置(dd),最后在虚拟机中将虚拟盘作为启动盘执行(VMware)。

    实验的原材料: nasm 指令:nasm boot.asm -o boot.bin,这是将我们编写的 boot.asm 编译为二进制 bin 文件; bximage 指令:bximage a.img -q -fd -size=1.44,其中的 -q 选项是指不用进行交互界面,直接一次运行完成; dd 指令:dd if=boot.bin of=a.img bs=512 count=1 conv=notrunc,这是将 bin 文件写入到 a.img 文件中。

    小结: 1、主引导程序的代码量不能超过 512 字节; 2、主引导程序需要使用汇编语言开发; 3、主引导程序中可以通过 BIOS 中断使用硬件功能; 4、主引导程序运行于实模式(地址都是实际的物理地址)。
    Processed: 0.016, SQL: 8