本篇内容,以及接下来几篇内容,是一个长期的工作的楔子。
其中大部分内容是节选自一些经典书籍,以及一些博客内容;结合自己的理解,将其融汇,从而达到对这些关键内容的补充作用,方便理解。希望对你有用。
Bochs是一个虚拟机,可以模拟X86,更值得介绍的是,它可以调试汇编。在两本非常好的书中都用到了Bochs(这两本书分别是:X86汇编语言从实模式到保护模式、Orange`s一个操作系统的实现)。但是书中介绍都比较简单。
如果不知道为什么要介绍Bochs,可能你还没有接触到一些操作系统底层内容,这篇内容,对你没有意义,接触到的时候再来看吧。
本文内容介绍的是,使用Bochs创建一个虚拟机,然后来启动我们自己编写的一个小小的开机启动系统。
用到的工具NASM 汇编编译器 https://www.nasm.us/
Bochs 虚拟机 https://bochs.sourceforge.io/
准备一个小系统以下代码保存到boot.asm
org 07c00h ; 告诉编译器程序加载到7c00处
mov ax,cs
mov ds,ax
mov es,ax
call DispStr ; 调用显示字符串例程
jmp $
DispStr:
mov ax,BootMessage
mov bp,ax ; es:bp = 串地址
mov cx,16 ; cx = 串长度
mov ax,01301h ; ah = 13,al = 01h
mov bx,000ch ; 页号为0(bh=0) 黑底红字(b1=0ch,高亮)
mov dl,0
int 10h ; 10h号中断
ret
BootMessage: db "Hello,OS world!"
times 510-($-$$) db 0 ; 填充剩下的空间,使生成的二进制代码恰好为512字节
dw 0xaa55 ; 结束标志
代码来自Orange`s一个操作系统的实现1.2
用NASM编译
nasm boot.asm -o boot.bin
编译生成的这个bin文件,便是一个可以在x86上开机启动的小段代码。开机后可以在屏幕上打印出“Hello,OS world!”,而且带有颜色奥。
使用Bochs创建一个从软盘启动的虚拟机使用bximage创建软盘windows下使用终端命令cmd,进入Bochs安装目录,里面带有一个bximage,可以用来创建一个软盘(用过qemu的,应该了解)。
bximage创建镜像盘
画横线的表示要手动输入,箭头表示直接按回车键就好了
图片来自:10分钟完成的操作系统(Bochs的使用--windows系统下) - 简书
操作完成后,会在Bochs安装目录下面生成一个a.img的模拟软盘文件
将启动程序写入软盘引导扇区软盘的引导扇区,也就是第一块,512字节,并且以0xaa55结尾。
比较方便的写入工具,就是linux下的dd命令了
dd if=boot.bin of=a.img bs=512 count=1 conv=notrunc
使用上面的命令,就可以将我们开始生成的boot.bin二进制文件,写入到a.img软盘模拟文件的第一个扇区(引导扇区)。
这中间好像又隐含了好多内容,所以,如果是初学者,请回避。
使用Bochs从软盘启动Bochs启动前,先使用配置文件,配置虚拟机参数,Bochs的配置文件在安装目录下有一个bochsrc-sample.txt可以参考,不过内容太多,可以直接复制下面的配置,将其保存在某个目录下,这里保存在Bochs安装目录下了。
# how much memory the emulated machine will have
megs: 32
# filename of ROM images,注意你的路径
romimage: file=BIOS-bochs-latest
vgaromimage: file=VGABIOS-lgpl-latest
# what disk images will be used ,注意你的路径
floppya: 1_44=doudou.img, status=inserted
# choose the boot disk.
boot: floppy
# where do we send log messages?
log: bochsout.txt
# disable the mouse,
mouse: enabled=0
在Bochs安装目录下,cmd启动Bochs,
bochs.exe -f bochsrc
bochs启动
启动后,可以看到Bochs的启动界面如下:
bochs虚拟机界面
注意,“Hello,OS world!”是出现在了左上角。
我们使用Bochs主要是用于debug,如果要进行调试,应该使用Bochs安装目录下的bochsdbg.exe启动,这样就可以单步调试你的系统了。
bochsdbg.exe -f bochsrc
下面代码来自《X86汇编语言从实模式到保护模式》的第五章,功能和上面的boot.asm一样,是一个启动代码;可以将下面代码编译后,写入软盘引导扇区,启动测试。
;代码清单5-1
;文件名:c05_mbr.asm
;文件说明:硬盘主引导扇区代码
;创建日期:2011-3-31 21:15
mov ax,0xb800 ;指向文本模式的显示缓冲区
mov es,ax
;以下显示字符串"Label offset:"
mov byte [es:0x00],'L'
mov byte [es:0x01],0x07
mov byte [es:0x02],'a'
mov byte [es:0x03],0x07
mov byte [es:0x04],'b'
mov byte [es:0x05],0x07
mov byte [es:0x06],'e'
mov byte [es:0x07],0x07
mov byte [es:0x08],'l'
mov byte [es:0x09],0x07
mov byte [es:0x0a],' '
mov byte [es:0x0b],0x07
mov byte [es:0x0c],"o"
mov byte [es:0x0d],0x07
mov byte [es:0x0e],'f'
mov byte [es:0x0f],0x07
mov byte [es:0x10],'f'
mov byte [es:0x11],0x07
mov byte [es:0x12],'s'
mov byte [es:0x13],0x07
mov byte [es:0x14],'e'
mov byte [es:0x15],0x07
mov byte [es:0x16],'t'
mov byte [es:0x17],0x07
mov byte [es:0x18],':'
mov byte [es:0x19],0x07
mov ax,number ;取得标号number的偏移地址
mov bx,10
;设置数据段的基地址
mov cx,cs
mov ds,cx
;求个位上的数字
mov dx,0
div bx
mov [0x7c00 number 0x00],dl ;保存个位上的数字
;求十位上的数字
xor dx,dx
div bx
mov [0x7c00 number 0x01],dl ;保存十位上的数字
;求百位上的数字
xor dx,dx
div bx
mov [0x7c00 number 0x02],dl ;保存百位上的数字
;求千位上的数字
xor dx,dx
div bx
mov [0x7c00 number 0x03],dl ;保存千位上的数字
;求万位上的数字
xor dx,dx
div bx
mov [0x7c00 number 0x04],dl ;保存万位上的数字
;以下用十进制显示标号的偏移地址
mov al,[0x7c00 number 0x04]
add al,0x30
mov [es:0x1a],al
mov byte [es:0x1b],0x04
mov al,[0x7c00 number 0x03]
add al,0x30
mov [es:0x1c],al
mov byte [es:0x1d],0x04
mov al,[0x7c00 number 0x02]
add al,0x30
mov [es:0x1e],al
mov byte [es:0x1f],0x04
mov al,[0x7c00 number 0x01]
add al,0x30
mov [es:0x20],al
mov byte [es:0x21],0x04
mov al,[0x7c00 number 0x00]
add al,0x30
mov [es:0x22],al
mov byte [es:0x23],0x04
mov byte [es:0x24],'D'
mov byte [es:0x25],0x07
infi: jmp near infi ;无限循环
number db 0,0,0,0,0
times 203 db 0
db 0x55,0xaa
运行结果如下:
,