第二载、第一个操作系统程序,"Hello OS" 尝鲜

《彖》曰:屯,刚柔始交而难生。《易经》的屯挂,讲述的是万物始生,充满艰难险阻,然而顺时应运,必欣欣向荣,故屯挂也叫做始生之挂。

 任何事物,都必须经历一个艰难的开始,方有可能守得云开见月明,当然操作系统学习也不例外。
        学编程逃不过的真香定律:一个程序永远是打印一行"Hello Word",那么这章节,我们也来编写一个可独立运行于x86架构的程序(注意,这里是脱离操作系统的)。

在上一篇我们说了,BIOS会加载启动介质中的主引导程序,主引导程序是一个由汇编语言完成的软件,并且存储在启动介质的前512字节处,入口地址为0x7C00,以0x55AA结束。主引导程序的入口地址0x7C00类比到C语言中,就是main函数入口,对应关系可参考下图:
第二载、第一个操作系统程序,

 本章节要实现的就是一个简单的主引导程序,功能为运行后在屏幕上打印字符串"Hello OS"

编写这个汇编程序有如下几个点需要注意:
一、打印相关设置
       1、bx寄存器固定设置为0x0F (mov bx, 0x0F)
       2、ah寄存器固定设置为0x0E (mov ah, 0x0E)
       3、al寄存器设置要打印的字符 (mov al, '要打印的字符')
       4、使用 int 0x10指令触发0x10号中断,使得al寄存器的值在屏幕上显示

一下是类比C语言中的打印
第二载、第一个操作系统程序,

二、其他汇编贴士
       1、hlt:程序进入睡眠状态的指令
       2、标签:一段指令代码的起始地址,类似C语言的标签
       3、&:表示当前指令的地址    && :表示当前汇编段的起始地址

有了以上两点的基础知识,下边就来编写这个主引导程序,文件名为boot.asm,启动时在屏幕上打印字符串"Hello OS"

org 0x7c00 ;指定起始地址为0x7c00

start:   ;关键寄存器清零
    mov ax, cs
    mov ss, ax
    mov ds, ax
    mov es, ax

    mov si, msg  ;将msg地址放入si寄存器中

print:
    mov al, [si]   ;取si寄存器中的一个字节数据
    add si, 1
    cmp al, 0x00   ;比较al是否到达信息尾
    je last        ;al值等于0x00,则跳到last标签
    mov ah, 0x0e   ;设置打印参数
    mov bx, 0x0f
    int 0x10   ;调用中断,打印字符
    jmp print  

last:
    hlt
    jmp last

msg:
    db 0x0a, 0x0a   ;定义换行符
    db "Hello OS!"  ;定义要打印的字符串
    db 0x0a, 0x0a
    times 510 - ($-$$) db 0x00  ;times 510 - ($-$$)为0占位符,确保启动程序为512字节
    db 0x55, 0xaa

上述代码就是一段简单的主引导程序,占用512字节,对于一些汇编指令,如定义数据指令 db、跳转指令jmp、比较指令cmp等,可自行查x86汇编,这里不再详解。

主引导程序boot.asm已经写好了,前边说了,主引导程序存储在启动介质的前512字节处,下边需要解决的问题就是:
        1、使用什么启动介质?
              答:启动介质这里通过bximage工具创建虚拟软盘 a.img
                     bximage a.img -q -fd -size=1.44
第二载、第一个操作系统程序,
        2、如何编译这段汇编代码,并将其存入启动介质的前512字节处?
              答:A、使用nasm编译器将boot.asm汇编源码编译成二进制机器码
                            nasm指令nasm boot.asm -o boot.bin
                     B、使用dd命令将编译生成的二进制机器码写入虚拟软盘a.img的起始位置
                           dd指令dd if=boot.bin of=a.img bs=512 count=1 conv=notrunc
                                         
参数 if
输入文件,这里即为编译后的二进制机器码文件boot.bin
                                                 of输出文件,这里即为创建的虚拟软盘a.img
                                                 bs每次操作的块大小,这里为512字节
                                                 count每次操作的块数量,这里为1
                                                 convnotrunc表示无间隙写入
第二载、第一个操作系统程序,

            C、在虚拟机中将虚拟软盘a.img作为启动盘执行
                将a.img拷贝到windows路径下
        第二载、第一个操作系统程序,

      创建一个新的虚拟机
      第二载、第一个操作系统程序,
              选择典型即可

第二载、第一个操作系统程序,
               这里选"稍后安装操作系统",因为我们要使用a.img作为启动盘

第二载、第一个操作系统程序,
              操作系统选其他
       第二载、第一个操作系统程序,
              给虚拟机起个名字,并选择保存位置

第二载、第一个操作系统程序,
               设置磁盘大小

第二载、第一个操作系统程序,

第二载、第一个操作系统程序,
              对新建的虚拟机进行设置

第二载、第一个操作系统程序,
               软盘选择a.img

第二载、第一个操作系统程序,
               运行设置好的虚拟机,此时操作系统MyOS的启动介质为a.img

,第二载、第一个操作系统程序,
                BIOS执行后加载运行启动介质a.img前512的主引导程序,我们的实现为打印字符串"Hello OS!"

第二载、第一个操作系统程序,

到此为止,尝鲜版 “Hello OS” 编写并运行完成。

总结
        1、主引导程序大小不可超过512字节
        2、主引导程序需要使用汇编语言开发
        3、主引导程序中可以通过BIOS中断使用硬件功能(文章中我们使用了0x10号中断打印字符串)
        4、主引导程序运行于实模式(地址都是实际的物理地址)

 

 

学自 --《狄泰软件学院》- 门徒操作系统

你可能感兴趣的:(操作系统连载)