我们上面提到的Virtual PC和VMware都是商业软件,而下面将要介绍的Bochs软件则是开源的和免费的。可以从http://bochs.sourceforge.net/获取它的最新版本和相关信息。
2.7.1 Bochs vs. Virtual PC vs. VMware
不知道开源给你的感觉是什么,对笔者而言,它总是意味着亲切、清新,身上没有讨厌的商业气息。也许你也有同感,如果是的话,可能你已经对本书到现在才提到Bochs感到不满。实际上笔者对Bochs其实是充满好感的,尤其是它可以对操作系统进行调试,这样方便的特性不能不让我们对它青睐有加。理论上讲,Bochs可以完全取代Virtual PC和VMware,但以笔者个人的体会,从一个操作系统开发者的角度来看,Bochs大致有这么几个缺点:
— Virtual PC有共享文件夹功能,可以方便地读取host上的文件,而Bochs不可以。当我们学习保护模式时,免不了要用到DOS,用Virtual PC可以在Windows下编写代码,通过共享文件夹的方式在DOS下执行,而Bochs就没这么方便。
— 跟Virtual PC和VMware比起来,Bochs的速度要慢得多,笔者曾经试图在Bochs上安装Red Hat 9,但随后就发现这是个愚蠢的决定,太慢了,不久笔者就把它中止掉了。
— Virtual PC的图形化界面要比Bochs好用。
读者可能注意到了上文中“从一个操作系统开发者的角度来看”这一句,之所以这样说,是因为我们这样武断地将Bochs拿来跟Virtual PC或Vmware相比是不公平的。虽然它们模拟同一个操作系统时的输出可能差不多,但从实现机制上讲,它们有巨大的不同。
Bochs是一个模拟器,它完全模拟x86的硬件以及一些外围设备。而VMware除了模拟一些特定的I/O之外,还可以用它的x86运行时引擎来完成其余内容的执行。意思是说,当客户PC试图执行一些动作时,VMware并不是利用自己重造的机制来解释它,而是将它传递给实际的硬件。在这里,VMware的工作更应称为“虚拟(virtualize)”而不是“模拟(emulate)”。Virtual PC的原理介于两者之间,它的一些部分是模拟出来的,另一部分则是虚拟出来的。Virtual PC能够实现共享文件夹也是因为同样的原因。
由于Bochs在模拟一台真正的机器的硬件,所以使得它比VMware和Virtual PC都慢得多。
笔者曾经将Tinix分别用Bochs 2.1.1、Virtual PC 5.0、VMware 3.2.0和真实的机器进行比较测试,发现在Virtual PC上运行的效果跟真实的机器居然差不多,而Bochs和VMware则慢得多,这可能跟它们实现机制的差异以及Tinix自身的特点有关。不过,Virtual PC的确因为速度、操作方便性等特点具备很强的吸引力,以至于本书最终将它而不是开源免费的Bochs作为首选。
那么Bochs是不是就被我们抛弃了呢?当然不是,因为Bochs的调试功能实在太令人兴奋了。当我们的操作系统出现问题时,Bochs就变得无法替代。下面,我们就来看一下,Bochs到底如何使用。
2.7.2 Bochs的使用方法
我们先来一点感性认识,首先从http://bochs.sourceforge.net/获取Bochs的安装程序。这里以Bochs 2.1.1为例,安装完成后,在菜单中可以找到快捷方式Linux Demo in Bochs 2.1.1,双击它,几秒钟之后,如图2-44所示的画面出现了。
图2-44 用Bochs启动Linux
感觉怎么样?虽然你已经熟悉了虚拟机这种东西,看到这样的画面还是感到很有趣,不是吗?这是一个非常小的Linux,输入root,然后按回车键,就可以登录进去使用了。如图2-45所示。
图2-45 登录到root
新奇之后,让我们来看看这奇妙的过程是怎么发生的。
首先在桌面上找到快捷方式Linux Demo in Bochs 2.1.1,看看它的目的地:D:\Program Files\Bochs-2.1.1\dlxlinux\run.bat。现在,就让我们看看run.bat的内容:
cd "d:\Program Files\Bochs-2.1.1\dlxlinux"
..\bochs -q -f bochsrc.bxrc
原来Bochs通过bochs -q -f bochsrc.bxrc这样的命令行来启动,那么不用说,启动的各种参数一定就装在bochsrc.bxrc中,下面就让我们来看一下(为节省篇幅,省略了部分内容):
代码2-1 bochsrc.bxrc(请参考\chapter2\bochsrc.bxrc)
# how much memory the emulated machine will have
megs: 32
# filename of ROM images
romimage: file=$BXSHARE/BIOS-bochs-latest, address=0xf0000
vgaromimage: $BXSHARE/VGABIOS-elpin-2.40
# what disk images will be used
floppya: 1_44=floppya.img, status=inserted
floppyb: 1_44=floppyb.img, status=inserted
# hard disk
ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14
ata0-master: type=disk, path="hd10meg.img", cylinders=306, heads=4, spt=17
# choose the boot disk.
boot: c
……
# where do we send log messages?
log: bochsout.txt
# disable the mouse, since DLX is text only
mouse: enabled=0
# enable key mapping, using US layout as default.
……
keyboard_mapping: enabled=1, map=$BXSHARE/keymaps/x11-pc-us.map
内容看起来虽然不少,但是除去以#开头的注释之外,实际起作用的内容并不多,而且凭借字面意思,还是比较容易理解的。
你一定蠢蠢欲动地想把你的Boot Sector拿到这里试一下了,好的,我们就在Bochs- 2.1.1\目录下新建一个目录Tinix\,然后把Bochs-2.1.1\下面的内容全部复制过来,再把我们之前已经做好的Tinix.img复制到这里。好了,打开bochsrc.bxrc,将上面代码中用阴影标出的两行改为:
floppya: 1_44=Tinix.img, status=inserted
以及
boot: a
然后修改一下run.bat:
cd "d:\Program Files\Bochs-2.1.1\Tinix"
..\bochs -q -f bochsrc.bxrc
运行,结果如图2-46所示。
图2-46 用Bochs运行引导扇区
画面有点乱,那是因为Boot Sector没有进行任何的清屏操作,不过毫无疑问,红色的“Hello, OS world”已经出现在眼前,这表明运行成功了,整个操作就是这么简单。在本书附送光盘中的文件夹“\chapter2”中有相应的bochsrc.bxrc和run.bat文件供读者参考。
当然,Bochs的使用不止这么简单,就让我们在实际应用过程中慢慢学习吧。
2.7.3 用Bochs进行调试
用Bochs可以对操作系统进行调试,对于这一点,我们将在5.4.5.2节中再具体介绍。
2.7.4 在Linux上开发
或许你是个不折不扣的开源爱好者,对Linux无比热爱,并且决不肯对任何人妥协,没问题,运用Bochs使得在Linux上的开发变得与刚才介绍的情况非常类似。而且可以想像,在真正的Linux上编译我们的代码一定是非常快的。
为简单起见,我们从http://bochs.sourceforge.net/处直接获得Bochs的RPM包,然后安装,如图2-47所示。
图2-47 在Linux中安装Bochs 2.1.1
然后修改文件bochsrc.bxrc,涉及到的主要是相关路径:
代码2-2 在Linux下使用的bochsrc.bxrc
romimage: file=/usr/local/share/bochs/BIOS-bochs-latest, address =0xf0000
vgaromimage: /usr/local/share/bochs/VGABIOS-elpin-2.40
floppya: 1_44=tinix.img, status=inserted
floppyb: 1_44=floppyb.img, status=inserted
ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14
ata0-master: type=disk, path="hd_dos.img", cylinders=101, heads=16, spt=63
boot: a
log: bochsout.txt
mouse: enabled=0
keyboard_mapping: enabled=1, map=/usr/local/share/bochs/keymaps/ x11-pc-us.map
这样就可以运行了,运行结果如图2-48所示。
图2-48 用Bochs运行引导扇区(在Linux平台下)
可以看到,与在Windows下的运行几乎是一摸一样的,不是吗?
另外,在Linux中使用软盘映像也非常方便,通过类似这样的命令就可以了:
mount /home/TINIX.IMG /mnt/floppy -o loop
总结一下,在Linux上开发可以通过这样的方式:
— GCC编译生成内核。
— 用mount命令将.IMG文件挂载到文件系统。
— 将内核复制到.IMG文件中。
— 用Bochs运行Tinix(可能需要先从文件系统中卸载.IMG文件)。