1、主要平台和工具简介
- 硬件:IA-32架构的计算机
- 软件:Bochs、gcc、IDE、Linux0.11源代码、Ubuntu、hit-oslab 集成环境
*PS:Bochs 是一个免费且开放源代码的 IA-32(x86)架构 PC 机模拟器。
VMware 或者 Microsoft Virtual PC是最著名虚拟机软件
hit-oslab 已经内置了 bochs
Boch官网
GCC 是和 Linux 一起成长起来的编译器。Linux 最初的版本就是由 GCC 编译的。GCC是GNU编译器套件(GNU Compiler Collection),是由GNU开发的编程语言编译器
GDB 调试器是 GCC 编译器的兄弟。
2、实验步骤
(1)准备环境
hit-oslab 实验环境简称 oslab,是一个压缩文件(hit-oslab-linux-20110823.tar.gz),这个文件已经下载到了 /home/teacher 目录和 /home/shiyanlou/oslab(大家一进入实验环境,就是点击左边的 terminal 打开终端以后,所在的目录就是 /home/shiyanlou,这是大家的主目录)下,大家可以使用下面的命令解压展开压缩包即可工作。
推荐大家使用如下的命令解压到 /home/shiyanlou/oslab/ 中。
# 进入到 oslab 所在的文件夹
$ cd /home/shiyanlou/oslab/
# 解压,并指定解压到 /home/shiyanlou/
# 这样的话,在 /home/shiyanlou/oslab/ 中就能找到解压后的所有文件
$ tar -zxvf hit-oslab-linux-20110823.tar.gz \
-C /home/shiyanlou/
# 查看是否解压成功
$ ls -al
# 除了压缩包 hit-oslab-linux-20110823.tar.gz 之外,其他的就是压缩包中的内容
(2)文件结构
Image 文件
oslab 工作在一个宿主操作系统之上,我们使用的 Linux,在宿主操作系统之上完成对 Linux 0.11 的开发、修改和编译之后,在 linux-0.11 目录下会生产一个名为 Image 的文件,它就是编译之后的目标文件。
该文件内已经包含引导和所有内核的二进制代码。如果拿来一张软盘,从它的 0 扇区开始,逐字节写入 Image 文件的内容,就可以用这张软盘启动一台真正的计算机,并进入 Linux 0.11 内核。
oslab 采用 bochs 模拟器加载这个 Image 文件,模拟执行 Linux 0.11,这样省却了重新启动计算机的麻烦。
bochs 目录
bochs 目录下是与 bochs 相关的执行文件、数据文件和配置文件。
run 脚本
run 是运行 bochs 的脚本命令。
运行后 bochs 会自动在它的虚拟软驱 A 和虚拟硬盘上各挂载一个镜像文件,软驱上挂载是 linux-0.11/Image,硬盘上挂载的是 hdc-0.11.img。
因为 bochs 配置文件中的设置是从软驱 A 启动,所以 Linux 0.11 会被自动加载。
而 Linux 0.11 会驱动硬盘,并 mount 硬盘上的文件系统,也就是将 hdc-0.11.img 内镜像的文件系统挂载到 0.11 系统内的根目录 —— /。在 0.11 下访问文件系统,访问的就是 hdc-0.11.img 文件内虚拟的文件系统。
hdc-0.11.img 文件
hdc-0.11.img 文件的格式是 Minix 文件系统的镜像。
Linux 所有版本都支持这种格式的文件系统,所以可以直接在宿主 Linux 上通过 mount 命令访问此文件内的文件,达到宿主系统和 bochs 内运行的 Linux 0.11 之间交换文件的效果。
Windows 下目前没有(或者是还没发现)直接访问 Minix 文件系统的办法,所以要借助于 fdb.img,这是一个 1.44M 软盘的镜像文件,内部是 FAT12 文件系统。将它挂载到 bochs 的软驱 B,就可以在 0.11 中访问它。而通过 filedisk 或者 WinImage,可以在 Windows 下访问它内部的文件。
hdc-0.11.img 内包含有:
Bash shell;
一些基本的 Linux 命令、工具,比如 cp、rm、mv、tar;
vi 编辑器;
gcc 1.4 编译器,可用来编译标准 C 程序;
as86 和 ld86;
Linux 0.11 的源代码,可在 0.11 下编译,然后覆盖现有的二进制内核。
(3)编译内核
“编译内核” 比 “编写内核” 要简单得多。
首先要进入 linux-0.11 目录,然后执行 make 命令:
$ cd ./linux-0.11/
$ make all
最后生成的目标文件是一个软盘镜像文件—— linux-0.11/Image(下面的图中给出了详细的信息)。如果将此镜像文件写到一张 1.44MB 的软盘上,就可以启动一台真正的计算机。
linux-0.11 目录下是全部的源代码,很多实验内容都是要靠修改这些代码来完成。修改后需要重新编译内核,还是执行命令:make all。
make 命令会自动跳过未被修改的文件,链接时直接使用上次编译生成的目标文件,从而节约编译时间。但如果重新编译后,你的修改貌似没有生效,可以试试先 make clean ,再 make all(或者一行命令:make clean && make all。make clean 是删除上一次编译生成的所有中间文件和目标文件,确保是在全新的状态下编译整个工程。
(4)运行
在 Bochs 中运行最新编译好的内核很简单,在 oslab 目录下执行:
# 注意是在上层目录
# 刚刚编译是在 oslab/linux-0.11/ 文件夹下
$ cd ~/oslab/
# 执行 run 脚本
$ ./run
如果出现 Bochs 的窗口,里面显示 linux 的引导过程,最后停止在 [/usr/root/]#,表示运行成功,如下图所示。
(5)文件交换
接下来讲解一下 Ubuntu 和 Linux 0.11 之间的文件交换如何启动。
开始设置文件交换之前,务必关闭所有的 Bochs 进程。
oslab 下的 hdc-0.11-new.img 是 0.11 内核启动后的根文件系统镜像文件,相当于在 bochs 虚拟机里装载的硬盘。在 Ubuntu 上访问其内容的方法是:
$ cd ~/oslab/
# 启动挂载脚本
$ sudo ./mount-hdc
之后,hdc 目录下就是和 0.11 内核一模一样的文件系统了,可以读写任何文件(可能有些文件要用 sudo 才能访问)。
# 进入挂载到 Ubuntu 上的目录
$ cd ~/oslab/hdc
# 查看内容
$ ls -al
读写完毕,不要忘了卸载这个文件系统:
$ cd ~/oslab/
# 卸载
$ sudo umount hdc
接下来,我们简单实验一下。
首先通过 sudo ./mount-hdc 进行挂载。
然后在 Ubuntu 的 ~/oslab/hdc/usr/root 目录下创建一个 xxx.c 文件,
sudo gedit ~/oslab/hdc/usr/root/xxx.c
编辑内容之后记得保存。
最后执行 sudo umount hdc 后,再进入 Linux 0.11(即 run 启动 bochs 以后)就会看到这个 xxx.c(即如下图所示)。
这样就避免了在 Linux 0.11 上进行编辑 xxx.c 的麻烦,因为 Linux 0.11 作为一个很小的操作系统,其上的编辑工具只有 vi,使用起来非常不便。
注意 1:不要在 0.11 内核运行的时候 mount 镜像文件,否则可能会损坏文件系统。同理,也不要在已经 mount 的时候运行 0.11 内核。
注意 2:在关闭 Bochs 之前,需要先在 0.11 的命令行运行 “sync”,确保所有缓存数据都存盘后,再关闭 Bochs。
PS:在计算机中,镜像通常指的是一个与原始对象或数据完全相同的副本