本篇内容,以及接下来几篇内容,是一个长期的工作的楔子。

其中大部分内容是节选自一些经典书籍,以及一些博客内容;结合自己的理解,将其融汇,从而达到对这些关键内容的补充作用,方便理解。希望对你有用。

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的,应该了解)。

如何使用bochs(Bochs使用详解)(1)

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使用详解)(2)

bochs启动

启动后,可以看到Bochs的启动界面如下:

如何使用bochs(Bochs使用详解)(3)

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

运行结果如下:

如何使用bochs(Bochs使用详解)(4)

,