概述
UML这里不是统一建模语言,而是UserMode Linux的缩写,从字面上看,是在用户态运行
linux内核,即将内核当作一个应用程序在跑,这样我们就可以用调试应用层程序的方法调试内
核了,应用层的强大调试工具gdb就派上用场了。很多时候我们写内核代码,当遇到算法比较
复杂但又不涉及底层结构的时候总是喜欢现在应用层实现并调试,然后在写到内核层。为什
么,就是因为用户层调试比内核调试方便。但是UML的最大局限性就是不能调试硬件关联性强
的代码,但是还是有很多方面可以应用的,比如调度算法、VFS等。用gdb像跟踪用户程序一
样跟踪这样的代码,相信你一定非常感兴趣,那么让我们马上开始第一步:搭建一个UML测试
环境。
安装
下载编译内核代码
1. 首先从网上下载你感兴趣的内核代码版本,比如我下载的版本是2.6.36.4。
2. 编译内核
在真正进入编译之前(make linux ARCH=um之前),需要先进行内核配置,具体配置可参考下图:
注意ARCH=um是必不可少的,否则就不是编译UML平台的内核了。如果编译过正常平台下
(如amd64, i386,ppc等)的内核的人会发现,这个配置列表和以往的有一些不同,这就是
ARCH=um的作用,我们现在要配置的是一个要跑在应用层的内核。除了选上你需要的功能对
应选项以外,还有一些选项是必要为UML选的:
* 在UML-specific options--->Host Processor typefeatures--->Processor family里选择你的处理器平台,如果你发现有Generic x86 support配置(不一定会出现),请保证它不生效。
* Character devices中的stderr console, Virtual serial line, nullchannel support, port channel support, pty channel support, tty channelsupport, xterm channel support等是需要选中的。
* Enable loadable module support 在UML中一般是不需要的,可以取消它,当然你不取消也没关系。
* Networking support 里的Amateur Radio support, IrDA (infrared)subsystem support, Bluetooth subsystem support等的也是可以去掉的。而UML Network Devices里的东西是需要依据具体情况而定的,我这里就使用了默认的配置,如果你有特殊需求还请根据自己的需求选。NetLabel subsystem support我选了,因为我需要调试网络标签。
* Block Devices---> Virtual block devices需要选中。
* File systems嘛……这个就比较复杂了,你需要什么就自己选吧。
* SCSI device support中可以不需要。
* Multiple devices driver support也可以不需要。
* Kernel Hacking是一个比较重要的,需要选中Kernel debugging, Compile the kernel with debuginfo这两个需要选上,Show timing information on printks可以选上,其它的选项根据你要调试需求自己选择。
好了,配置好后你就可以保存退出了。
构建运行环境
让uml的内核跑在一个独立出来的运行环境中,我们需要一块磁盘,并在这块磁盘上作一个文
件系统,即根文件系统,再在上面作一个可运行的最小系统(因为要让系统可运行,需要的不
仅仅是一个内核,还有一些相关的运行环境的支持)。这里可以自己制作带最小系统的根文件
系统,也可以从网上直接下载一个现成的,刚开始的时候我采用了自己制作的方法,但是系统
运行没有成功,我便从网上下载了一个现成的,最终算是大功告成。我在这里分别给出两种办
法,任各位自己挑选。
手动制作方法:
1. 首先创建一个设备用来作为文件系统的载体并格式化成想要的文件系统:
mkdir disk
dd if=/dev/zero of=disk/um-rootbs=1024K count=1000
mkfs.ext3 disk/um-root
2. 挂载设备:创建目录挂载点目录并将上面已格式化的设备挂载
mkdir -p mnt/
mount -o loop disk/um-rootmnt/
3. 构建最小化系统
debootstrap squeeze mnt/ http://ftp.debian.org/debian(ubuntu上)
4. 等到一切就绪以后,系统运行所需的一切条件就已经具备了。
网上下载办法:(推荐)
上面我们介绍了自己手动制作根文件系统的办法,这种办法可能会让你对系统有更深入的理
解,但是出错的可能性也更大,我在第一次尝试的时候就出错了,而且手机号码出售平台地图找不到出错的原因,让
我很是郁闷,于是选择了这种方法。这种办法非常简单,只需要从网上下载适合你的root_fs即
可。下载地址为:
Distribution Disk Imagesfs.devloop.org.uk
比如,我下载的就是DebianSqueeze。
运行UML
准备工作就绪以后,就可以让UML跑起来了。再次申明,让UML跑起来需要的两个条件:1.编
译好的内核;2. 制作好的根文件系统,在我自己的系统中,我将他们存储在不同的目录下,编
译好的内核位于目录kernel/linux-2.6.36.4下,而制作好的根文件系统位于disk下,名为
root_fs。
运行UML很简单,直接输入下面的命令即可:
./kernel/linux-2.6.36.4/linux ubda=disk/root_fs mem=256m
UML执行的结果是会弹出一个登陆对话框,提示你输入用户名和密码,
网上下载的根文件系统,默认用户名是root,密码为空,如下图所示:
等你正确输入用户名和密码以后,展现在你面前的就是一个用户态的linux系统了,你可以完成
和普通操作系统的所有功能。
使用UML调试内核
搞清楚了如何使用UML以后,利用UML调试内核也就变得易如反掌了,我们使用的工具还是
强大的GDB 。
使用GDB加载编译好的内核,然后设置断点,用法与gdb调试普通应用程序无异。这里不妨给
出我的gdb调试截图:
Q&A
在编译使用和调试UML的过程中,可能会遇到很多意想不到的麻烦,这部分我将自己遇到过的
意外贴在这里,希望对初学者有所帮助,如果你有任何的补充,希望你能给出问题以及行得通
的解决方案并留言,我会不断补充。
1. 在debug UML的时候,会遇到如下问题:
解决办法:tell gdb to ignore SIGSEGV: 告诉gdb忽略SIGSEGV。
在gdb命令框中输入:handle SIGSEGV noprint nostop pass
2. Debug UML的时候遇到一个问题:
Program received signal SIGTRAP, Trace/breakpoint trap.
0x08066a4c in get_signals () atarch/um/os-Linux/signal.c:284
解决办法:
在gdb命令框中输入:handle SIGTRAP nostop noprint