实验的基本流程是根据实验要求编写应用程序、修改Linux 0.11的源代码,用gcc编译后,在Bochs的虚拟环境中运行、调试目标代码。
(本实验仅涉及在Linux环境下操作的代码,仅供个人学习)
Bochs是一个免费且开放源代码的IA-32(x86)架构PC机模拟器。在它模拟出的环境中可以运行Linux、DOS和各种版本的Windows等多种操作系统。而Bochs本身具有很高的移植性,可以运行在多种软硬件平台之上,hit-oslab已经内置了bochs。
关于Bochs的更详细的介绍请访问它的主页及Bochs使用手册。
GCC是和Linux一起成长起来的编译器。Linux最初的版本就是由GCC编译的。现在GCC也是在自由软件领域应用最广泛的编译器。
GDB调试器是GCC编译器的兄弟。做为自由软件领域几乎是唯一的调试器,它秉承了*nix类操作系统的一贯风格,采用纯命令行操作,有点儿类似dos下的debug。
关于它的使用方法请看GDB使用手册。
Ubuntu的主页是http://www.ubuntu.com/ ,这里不仅可以免费下载到iso文件,甚至能免费申领Ubuntu的安装光盘。
hit-oslab实验环境简称oslab,是一个压缩文件(hit-oslab-linux-20110823.tar.gz(https://download.csdn.net/download/yxh505613923/10143550)),大家可以将这个文件拷贝到自己的实验工作目录下,用tar zxvf hit-oslab-linux-20110823.tar.gz
命令解压展开即可工作。oslab工作在一个宿主操作系统之上,我们使用的Linux,在宿主操作系统之上完成对Linux 0.11的开发、修改和编译之后,在linux-0.11目录下会生产一个名为Image的文件,它就是编译之后的目标文件。该文件内已经包含引导和所有内核的二进制代码。如果拿来一张软盘,从它的0扇区开始,逐字节写入Image文件的内容,就可以用这张软盘启动一台真正的计算机,并进入Linux 0.11内核。oslab采用bochs模拟器加载这个Image文件,模拟执行Linux 0.11,这样省却了重新启动计算机的麻烦。
bochs目录下是与bochs相关的执行文件、数据文件和配置文件。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文件的格式是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内包含有:
$ cd ~/oslab
把当前目录切换到oslab下,用pwd命令确认,用“ls -l”列目录内容。
“编译内核”比“编写内核”要简单得多。首先要进入linux-0.11目录,然后执行:
$ make all
因为“all”是最常用的参数,所以可以省略,只用“make”,效果一样。在多处理器的系统上,可以用-j参数进行并行编译,加快速度。例如双CPU的系统可以:
$ make -j 2
最后几行中没有“error”就说明编译成功。最后生成的目标文件是一个软盘镜像文件——linux-0.11/Image。如果将此镜像文件写到一张1.44MB的软盘上,就可以启动一台真正的计算机。
linux-0.11目录下是全部的源代码,很多实验内容都是要靠修改这些代码来完成。
修改后需要重新编译内核,还是执行命令:
$ make all
make命令会自动跳过未被修改的文件,链接时直接使用上次编译生成的目标文件,从而节约编译时间。但如果重新编译后,你的修改貌似没有生效,可以试试先“make clean”,再“make all”。“make clean”是删除上一次编译生成的所有中间文件和目标文件,确保是在全新的状态下编译整个工程。
在Bochs中运行最新编译好的内核很简单,在oslab目录下执行:
$ ./run
如果出现Bochs的窗口,里面显示linux的引导过程,最后停止在“[/usr/root/]#”,表示运行成功
内核调试分为两种模式:汇编级调试和C语言级调试。
汇编级调试需要执行命令:
$ ./dbg-asm
C语言级调试,首先执行如下命令:
$ ./dbg-c
然后再打开一个终端窗口,进入oslab目录后,执行:
$ ./rungdb
新终端窗口中运行的是GDB调试器。
关于gdb调试器请查阅GDB使用手册。
oslab下的hdc-0.11-new.img是0.11内核启动后的根文件系统镜像文件,相当于在bochs虚拟机里装载的硬盘。
$ sudo ./mount-hdc
之后,hdc目录下就是和0.11内核一模一样的文件系统了,可以读写任何文件(可能有些文件要用sudo才能访问)。读写完毕,不要忘了卸载这个文件系统:
$ sudo umount hdc
经过sudo ./mount-hdc
这样处理以后,我们可以在Ubuntu的hdc目录下创建一个xxx.c文件,然后利用Ubuntu上的编辑工具(如gedit等)实现对xxx.c文件的编辑工作,在编辑保存以后。执行sudo umount hdc
后,再进入Linux 0.11(即run启动bochs以后)就会看到这个xxx.c。
注意1:不要在0.11内核运行的时候mount镜像文件,否则可能会损坏文件系统。同理,也不要在已经mount的时候运行0.11内核。
注意2:在关闭Bochs之前,需要先在0.11的命令行运行“sync”,确保所有缓存数据都存盘后,再关闭Bochs。
(参考实验楼—操作系统实验步骤
https://www.shiyanlou.com/courses/115/labs/374/document)