
1.4 搭建调试开发环境
虽然通过上一节的方法获得源代码以后,你将能够顺利地阅读本书,但是有一句话说得很正确:纸上得来终觉浅,绝知此事要躬行。因此强烈建议你按照本节的方法搭建调试开发环境。
1.4.1 安装ubuntu 16.04
在我的笔记本电脑上安装的操作系统是 ubuntu 16.04,因此可以确保本节中的调试开发环境能顺利地运行在ubuntu 16.04系统中。其他的Linux版本应该也是可以的,但并不能保证其他版本可以正常工作。
首先,需要下载ubuntu 16.04的安装镜像。
视你的开发环境PC机CPU配置,可以下载不同的安装镜像:
1.64位PC。
2.32位PC。
在http://old-releases.ubuntu.com/releases/16.04.3/MD5SUMS中,有这两个镜像文件的MD5值,分别为:
c94d54942a2954cf852884d656224186
610c4a399df39a78866f9236b8c658da
请检查下载文件中的MD5值,确保与上面的两个值一致。
小问题1.2:你已经两次提到MD5值了,它有那么重要吗?
有两种方法可以安装ubuntu 16.04。
1.直接在物理机上安装ubuntu 16.04。建议找一台Linux机器,并使用dd命令将镜像烧写到USB中,并通过USB来安装系统。
2.在虚拟机中安装ubuntu 16.04。这种方法可以不用将安装镜像烧写到USB中。在虚拟机中实际搭建开发环境,其效果和物理机中的是一致的。
ubuntu 16.04的安装过程比较简单,这里不再详述。
小问题1.3:可是我没有Linux环境,也不知道怎么用dd命令来烧写镜像到USB,怎么办?
为了给Linux新手提供便利,后续内容中假设是在虚拟机中安装ubuntu 16.04的,并以此为基础搭建调试开发环境。
1.4.2 ubuntu 16.04环境配置
首先,请配置虚拟机,为它创建两个网卡。
在Oracle VM VirtualBox管理器中,通过“设置”→“网络”进入配置界面。
在“网卡 1”选项卡中,选择“启用网络连接”,并在“连接方式”中选择“仅主机(Host-Only)适配器”,在“界面名称”中选择“vboxnet0”。该网卡用于虚拟机与物理机的文件共享连接。
在“网卡2”选项卡中,选择“启用网络连接”,并在“连接方式”中选择“网络地址转换(NAT)”。该网卡用于虚拟机与互联网的连接。后面将看到,无论是安装软件包,还是通过Git下载代码,都需要连接到互联网。
然后启动ubuntu 16.04虚拟机,进行如下基本环境配置。
1.打开命令行控制台,在我的环境中,通过按“Ctrl+Alt+T”组合键打开控制台。
2.在命令行控制台中,输入如下命令切换到 root 用户。当然,为了防止误操作损坏系统,也可以不用切换到root用户,但是请记得为后续的某些操作添加sudo前缀。

3.在命令行控制台中,输入如下命令更新APT仓库:

这一步可能需要花费数秒甚至数分钟的时间,这是由网络的状态来决定的。
由于还没有正确地配置双网卡,因此虚拟机还不能正确地连接到互联网。这时可以简单地禁用第一个网卡。
4.在命令行控制台中,输入如下命令安装VIM:

5.编辑/etc/network/interfaces,输入如下内容:

其中,enp0s3是我创建的虚拟机中的内网网卡,用于虚拟机与主机之间的通信,但在实际的机器上可能用的是其他名称,请注意调整。192.168.0.98 是该网卡的地址,请根据实际配置进行调整。
enp0s8则是我创建的虚拟机中的外网网卡,用于虚拟机与互联网之间的通信,在实际的机器上可能用的是其他名称,请注意调整。
编辑并保存/etc/network/interfaces文件后,请运行如下命令重启网络服务,使配置生效:

最后,运行如下命令创建DIM-SUM根目录:

小问题1.4:一定要在根目录下创建HOT-POT目录吗?使用其他的目录名称可以吗?
1.4.3 搭建编译环境
首先,建议在ubuntu 16.04中安装Git工具。在命令行控制台中输入如下命令开始安装:

命令执行完毕后,在命令行控制台中输入如下命令验证Git工具是否被正确安装:

如果看到如下控制台输出,则表示Git工具安装成功:

然后将dim-sum.20200616.tar.bz2解压,获取其中的源代码和编译工具:

解压后,使用ls-al命令可以看到如下输出:

其中,c2_gbk.sh脚本文件用于将src目录中的源代码转换为gbk编码,这样方便读者在Source Insight工具中浏览文件内容。
c2_utf8.sh脚本用于将src目录中的源代码转换为utf-8编码,这样方便读者在Linux环境中浏览文件内容。
src目录是DIM-SUM的源代码目录。
toolchains目录是工具链目录,其中包含两个工具链,分别用于编译DIM-SUM及调用专用工具链。
接着,在控制台中输入如下命令,检查工具链是否能够正常运行:

如果在控制台中看到如下输出,那么恭喜你:

最后,在命令行控制台中输入如下命令,确认GDB工具是否正常:

是不是迫不及待地想为HOT-POT编译出一个可以运行的版本?请接着看下一节。
1.4.4 编译HOT-POT
编译HOT-POT的方法很简单。首先进入src目录,然后运行下面的编译命令:

如果你编译过Linux源代码,就应该对上面的命令非常熟悉。该命令位于脚本build.sh中。
如果在控制台中看到如下输出信息,则表示编译成功:

目前,HOT-POT借用了Linux的编译框架,因此输出的符号表文件仍然是“vmlinux”,正如上面代码中“LD vmlinux”一行所示。当然,如果你能够提交一个补丁来修正这些问题,我们会非常感激你。
小问题1.5:你为什么不详细解释一下编译命令,就像大多数书中所做的那样?
在命令行控制台中输入如下命令,查看HOT-POT镜像是否生成成功:

预期的结果大概是这样的:

小问题1.6:生成的镜像竟然超过1MB?
1.4.5 运行HOT-POT
要运行 HOT-POT,需要安装 QEMU,这免除了购买单板的需要。在命令行控制台中,输入如下命令:

安装完成后,使用如下命令确认成功安装QEMU模拟器:

应当会在命令行控制台中看到如下输出:

在源代码目录下运行如下命令,就可以在QEMU中启动HOT-POT:

实际上,也可以在源代码目录下运行run.sh来启动HOT-POT。
现在看到的应该是如下所示的窗口:

别急,按“Ctrl+Alt+2”组合键看看。激动人心的界面应当出现了,如下图所示:

在这个界面中按下“Enter”键,并输入ls命令,将看到如下所示的界面:

小问题1.7:如果我想看看前面的输出,那该怎么办?
看起来大功告成,但是似乎还缺少了一点什么。
1.4.6 开始调试
在前面的步骤中,已经将GDB调试工具解压到工具链目录中,其具体地址如下:

现在是时候用到它了。
首先,应当换一种方式启动HOT-POT,使用如下命令:

请注意该命令中的“-s-S”参数,它会暂停HOT-POT的运行,并等待GDB调试。
实际上,也可以在源代码目录下运行qemu.run脚本来开始调试。
在命令行控制台中,按“Ctrl+Shift+T”组合键启动一个新的控制台,我们称之为“调试控制台”。在调试控制台中,进入源代码目录,输入如下命令启动GDB,准备开始调试HOT-POT:

在(gdb)提示符下,输入如下命令,连接到QEMU:

现在的调试控制台看起来是这样的:

在(gdb)提示符下,输入“c”命令,启动HOT-POT。然后切换到QEMU窗口,看看HOT-POT是不是已经正常启动了。
接下来,在调试控制台中,按“Ctrl+C”组合键,暂停HOT-POT的运行,并在(gdb)提示符下输入“bt”命令,查看HOT-POT当前停留在什么地方?看起来应当是这样的:

当然了,在调试控制台中可以使用所有 GDB 调试命令,进行诸如单步跟踪、查看变量、查看寄存器、查看堆栈、切换CPU、汇编单步等操作。
小问题1.8:在调试Linux内核时,我无论是用KGDB,还是用QEMU,发现在单步跟踪时都会杂乱无章地跳转,有些变量值也看不到。但在HOT-POT中不会这样,作者有什么办法?