下面正式进入实操环节,也就是动手搭建操作系统。看着眼前的Windows/Linux/Mac OS/etc,相信绝大多数同学都会感到兴奋和迷茫:这么大个操作系统,从哪里开始呢?古人有云:“工欲善其事,必先利其器。”我们得以发挥自己聪明才智,进行学习研究创造的前提,是拥有一个好的工具。它能让我们在巨人的肩膀上欣赏与创造。在这里,我想表达对所有在相关领域为后人的方便贡献自己汗水的前辈的衷心的感谢与钦佩。

  话不多说,接下来我们正式切入正题:配置调试操作系统所需的环境。

  1. C/C++编译器,这里采用gcc/g++方案
  2. 汇编器,我们将使用较新的NASM作为我们的汇编器
  3. 虚拟机/模拟器:接下来就欢迎我们今天的主角——Bochs!

简介

  Bochs(发音同"Box"),是一款开源,使用C++编写的,高度便携的 IA-32(X86)架构PC模拟器,它包含了对Intel x86架构各种CPU,常见的IO设备以及定制化BIOS的模拟。支持对早期的386处理器到最新的x86-64架构Intel和AMD处理器,甚至包含未上市的处理器版本。1

上面特别强调了模拟器,这和我们平时使用的VMware或是Virtual Box这类虚拟机有何不同呢?虽然表面上看起来,都是在一台宿主机上运行一个客户机系统,但它们两个的运行原理和适用场景却有着天差地别。

  • 虚拟机:指采用虚拟化技术,在已有主机的硬件设施的基础上,虚拟出的一套独立的硬件设施。从原理上看,简单来说(不太严谨),虚拟机中的计算机指令仍然是交由宿主机中的物理核心执行的。因此,它的执行速度相对较快,适用于在物理机上运行一套完整操作系统并使用的场景。
  • 模拟器:指使用软件模拟出各个计算机硬件及其功能,包括CPU、内设、外接设备、BIOS等,其底层执行完全是由软件模拟的。因此相较虚拟机而言,模拟器的运行速度慢得多。但由于其操作系统的指令并没有真正让物理机的核心执行,其安全性与崩溃后整个系统的稳定性也好得多。常见于操作系统开发。

所以,将要手动编写操作系统的我们,自然也采用Bochs作为运行/调试我们操作系统的工具。

安装

我们的环境搭建在VMware Workstation中创建的Ubuntu 16.04LTS虚拟机里。(比较绕XD)当然,Bochs支持Windows和Mac OS平台,如果没有或没有兴趣配置虚拟机的话,读者可以装在自己喜欢的平台上。

在Ubuntu上,安装有apt支持的软件真是一件十分令人享受的事情。

sudo apt install bochs-x

一行命令即可结束战斗,接下来就可以愉快的玩耍啦!(我们安装的是带有x11图形化插件的版本,它会自动安装主程序,如果你的计算机没有安装x11,在接下来的运行过程中可能会报错,安装一下即可)

默认的软件安装位置在/usr/share/bochs下,所有软件的可执行文件都在其中,系统还为我们配置好了“快捷方式”,直接输入命令bochs,就能启动Bochs模拟器。

hubor 镜像标签 bochs镜像制作_linux


hubor 镜像标签 bochs镜像制作_配置文件_02

启动后会出现一个菜单,默认选项为2,也就是我们后面要讲的内容:从配置文件读取模拟机器的配置。


配置文件

类似于VMware中虚拟机的配置文件,需要Bochs模拟的机器(下面我也称为虚拟机)的各项硬件配置也需要一个配置文件指定。只不过VMWare有一个比较方便的图形化界面而已。

系统给出的样例文件位于/usr/share/doc/bochs/examples/bochsrc,为一个文本文件,里面有非常详尽的注释,可以帮助我们理解各个选项,以及对应值的含义,读者如果有兴趣可以自己研究。

我们也可以使用如下的简化版bochsrc(注意其中路径可能需要修改,以安装路径为准

# Bochs配置文件

# 配置机器内存,建议使用新的Memory选项
memory: guest=32, host=64
# 总占用64MB宿主机内存,分配给虚拟机32MB

# 对应真实机器的bios (使用bochs提供的BIOS)
romimage: file=/usr/share/bochs/BIOS-bochs-latest

# 对应真实机器的VGA bios
vgaromimage: file=/usr/share/bochs/VGABIOS-lgpl-latest
# 启动方式
boot: disk

# 关闭鼠标
mouse: enabled=0

# 设置键盘映射
keyboard: keymap=/usr/share/bochs/keymaps/x11-pc-us.map

# 硬盘设置
ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14

我们将其命名为bochsrc.disk,表明从硬盘启动操作系统。

**与VMware相同,Bochs同样不要求虚拟机和Bochs软件在同一目录下,这会增加操作的复杂度。**我们可以在任何位置(如家目录等)放置我们的虚拟机配置文件以及其他内容。

需要注意的是,Bochs同样拥有工作目录,也就是我们打开的bochsrc的位置。最好将一个虚拟机的所有文件归入一个目录中,这样可以在配置文件里方便地使用相对路径,也可以避免不必要的文件混淆。


启动Bochs

第一次

Bochs有足够的安全性,即使系统执行失败了,一般也不会对宿主机产生什么影响。所以,如果你已经迫不及待了的话,那就试试吧!

  1. 切换到bochsrc,也就是你的虚拟机所在的目录
  2. 输入bochs命令启动Bochs
  3. 在上面说过的主菜单上,选择默认选项2(也可以不输入,就是默认)
  4. 它将提示你输入一配置文件名称,输入我们刚刚配置好的bochsrc.disk
  5. 窗口猛烈输出调式信息,停在了<bochs:1>处,这就是虚拟机调试的命令行。接下来弹出了一个黑框,也就是我们的虚拟机窗口

此时,虚拟机处于调试状态,类似于程序准备执行入口指令,但被入口断点截停了

我们需要在命令行中输入c(continue,继续运行),让我们的”操作系统“开始运行,这里是不是有点像gdb调试呢?(其实我们也可以使用gdb调试,但其自带的调试个人感觉更好)

我们的空”操作系统”继续执行,刚才弹出的黑框窗口有了边上的基本UI,然后不出意料地,我们遇到了一个错误。

hubor 镜像标签 bochs镜像制作_linux_03

来自BIOS的一个错误,没有可启动的设备,这是当然,我们甚至没有为虚拟机配置一个硬盘!XD

点击Quit退出,如果你不慎关闭了窗口还没有结束调试命令行,则输入q退出调试

生成硬盘

上面的错误让我们配置一块硬盘,我们可以用Bochs自带的bximage工具生成一块虚拟硬盘。

这个工具拥有与Bochs相同的的交互界面,可以直接打开,并按照步骤操作,也可以使用静默命令行一行搞定。

bximage -hd -mode="flat" -size=10 -q disk.img

上面命令的参数含义如下:

  • hd: 生成一块硬盘(fd为floppy disk,软盘)
  • mode: 硬盘模式,这里使用flat平坦模式,详见bochsrc样例
  • size: 硬盘大小,单位MB
  • -q: 重要,静默生成磁盘,而不是使用交互模式询问
  • disk.img: 想要生成的磁盘映像文件名

执行完成后,在当前目录下,生成了一个磁盘。

hubor 镜像标签 bochs镜像制作_linux_04

工具还贴心地为你生成了一个配置语句,帮助你直接写入bochsrc配置文件中,我们把这条语句复制进去。

ata0-master: type=disk, path="disk.img", mode=flat, cylinders=20, heads=16, spt=63

这样就相当于将一块硬盘装入了我们的虚拟机中。

再次启动

再次启动,我们可以使用更方便的方法。

  1. 使用命令行参数直接指定我们的配置文件
bochs -f bochsrc.disk
  1. 将配置文件改名为默认的bochsrc,后启动Bochs直接载入默认配置文件

然而,启动遇到了同样的错误。这也是显然的,虽然我们生成了一块硬盘,但我们没有向其中写入任何数据,BIOS并没有在里面找到主引导记录,也就不会启动系统,系统到这里就终止了。

关于引导的编写,我们将在下面的章节中一起学习。


参考书目:《操作系统真象还原》


  1. 翻自Bochs官网 ↩︎