写一个操作系统,目的就是得到一个软盘映像文件 *.img ,笔者首先写了一个映像文件 a.img进行展示,之后再介绍是如何完成的。
使用bochs运行a.img: (图中红色部分即为要输出内容)

使用VMare运行a.img:

可以看到两幅图的红色输出部分是一样的。实际我们已经写了一个极其简单的操作系统,它只含有一个引导扇区(boot sector)。关于这个引导扇区是如何完成的下节再写,这里主要是通过它来详述如何完成一个简单的操作系统,下面简述上面的 a.img 是如何得到的。
流程如下:
1. 首先先写一个引导扇区的汇编代码 boot.asm,代码在下篇笔记中进行详细解释。
org 07c00h
mov ax, cs
mov ds, ax
mov es, ax
call DispStr
jmp $
DispStr:
mov ax, BootMessage
mov bp, ax
mov cx, 38
mov ax, 01301h
mov bx, 000ch
mov dl, 0
int 10h
ret
BootMessage: db "Hey! I am Rooeye, welcome to my blog!"
times 510-($-$$) db 0
dw 0xaa55
这段汇编代码会使得OS在开机的时候显示 “Hey! I am Rooeye, welcome to my blog!”.这句话。
然后对汇编代码进行编译生成二进制文件:
nasm boot.asm -o test.bin
这条命令就可以把汇编文件 boot.asm 转化为二进制文件 test.bin.
2. 生成空白的虚拟软盘映像 a.img,生成虚拟软盘映像 a.img需要使用工具bximage,见下图:

输入命令 bximage后:
第一步:输入 hd 或 fd,输入hd表示新建一个空白的虚拟硬盘映像,输入 fd表示新建一个空白的虚拟软盘映像,这里我们输入的是fd新建一个软盘映像。
第二步: 输入虚拟软盘的大小,可以选择 0.16, 0.18, 0.32, 0.36, 0.72, 1.2, 1.44, 1.68, 1.72, 2.88. 单位是MB。
这里我们默认选择 1.44M即可,毕竟引导扇区的大小只有512个字节。
第三步:输入虚拟软盘的名称,默认是 a.img
这样我们就建立了一个空白的大小为1.44M的虚拟软盘映像 a.img.
3. 将二进制文件 test.bin的内容拷贝到a.img中,我们知道一个引导扇区的大小只有512B,这里可以使用linux自带的dd命令进行拷贝。
dd if=test.bin of=a.img bs=512 count=1 conv=notrunc
这里设置 一个block大小为512B,因为boot sector大小只有512B,所以count设置为1即可。
conv=notrunc的作用是禁止截断,如果没有设置这个参数,在执行dd指令后a.img的大小会变为和test.bin的大小一样,变为了512B,如果是实际软盘,就不需要设置这个参数,因为物理软盘不存在截断问题。
当设置conv=notrunc的时候:

可以看到执行dd命令后 a.img的大小为 1.5M。
当不设置conv=notrunc的时候:

可以看到执行dd命令后 a.img的大小为 512B,剩余部分被截断。
4. 配置bochsrc文件,我们这里bochs就相当于一台计算机,a.img就相当于软盘,那么我们必须告诉我们这台计算机的内存多大,磁盘映像使用的是哪个等等。bochsrc就是对这些参数进行配置。
我们先来看看bochsrc是什么样子的:
################################################
#configure file for Bochs
################################################
# how much memory the emulated machine will have
megs: 32 # 虚拟机内存为32M
# filename of Rom images, 注意下边要根据你安装目录来调整
romimage: file=/usr/share/bochs/BIOS-bochs-latest
vgaromimage: file=/usr/share/vgabios/vgabios.bin
#what disk images will be used
floppya: 1_44=a.img, status=inserted
#choose the boot disk.
boot: floppy
#where do we send log messages?
log: bochsout.txt
#disable the mouse
mouse: enabled=0
# enable key mapping, using US layout as default.
keyboard_mapping: enabled=1, map=/usr/share/bochs/keymaps/x11-pc-us.map
megs:用来指明bochs虚拟机内存大小,笔者这里指定为为32M
romimage 和 vgaromimage :两个参数的路径根据自己的系统的安装位置来确定
floppya: 用来指定bochs使用的具体是哪一个虚拟软盘
boot: 指明我们引导磁盘使用的是什么类型,这里我们用的是软盘所以写的是 floppy
log: 指明系统日志文件
mouse: 是否禁用鼠标
keyboard_mapping : 指明键盘布局,这里使用的是美式键盘布局,参数map的路径也是根据自己安装位置而定。
我们这里要注意对于bochsrc文件来说,不同版本的bochs在语法上略有不同,必要的时候需要略微改变才可以,如何改变可以参照bochs官方给的sample来定。
5. 启动虚拟机bochs,在当前目录使用如下命令:
bochs -f bochsrc(输入bochs也可,bochs命令会自动寻找当前目录下的bochsrc文件)
然后虚拟机就启动了,这时控制台会打印出如下画面:

这个时候虚拟机并没有直接运行,而是进入了调试状态,等待我们输入命令才能继续执行。
6. 我们可以输入指令 c,“c”的含义是“继续执行直到遇上断点”,这样我们就可以得到运行结果

红色部分是我们设置的开机显示内容,其余为bochs自带开机显示,可以通过清屏操作来消除。到此为止,一个简单的OS就制作完成啦!