构建调试Linux内核网络代码的环境MenuOS系统
首先,下载Linux内核源代码。下载网址为:https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.0.1.tar.xz。
这里建议在Windows系统下用迅雷下载,然后将文件拖动至虚拟机。为了方便宿主机和虚拟机之间的文件交换,有两条建议:
一是在给虚拟机安装Ubuntu系统时,建议给出操作系统iso镜像文件的地址,由VMware自动安装之,而不是构建一空硬盘的虚拟机由用户自行安装操作系统。由VMware自动安装操作系统有一个好处是它会自动为用户安装VMtools,这样可以在虚拟机全屏,以及虚拟机与宿主机复制粘贴,文件交换方面提供很多便利;
二是建议将虚拟机与宿主机的网络连接方式设置为“桥接模式”:
此后,将宿主机中下载好的安装包直接拖进用户想要存放内核文件的目录下即可,在本例中,内核文件被存放在本用户的家目录下的MenuOS目录,通过mkdir命令创建该目录:
1 #切换到当前用户的家目录,~就代表当前用户的家目录,相当于/home/当前用户名 2 cd ~ 3 #查看当前工作目录,确定目录切换成功 4 pwd 5 #创建目录命令,在当前工作目录下创建MenuOS目录 6 mkdir MenuOS
将安装包存于MenuOS目录下后,通过如下命令将其解压:
1 #xz -d命令是解压命令,得到一个tar的归档包 2 xz -d linux-5.0.1.tar.xz 3 #tar -xvf是解包命令,将归档包中的文件解放出来;-cvf是打包 4 tar -xvf linux-5.0.1.tar 5 #上述两步完成后,MenuOS目录下多了一个linux-5.0.1目录,进入 6 cd ./linux-5.0.1
下一步是安装内核编译工具,也就是整个实验所需要的依赖包,命令如下,一条语句涵盖所有要安装的包:
1 sudo apt install build-essential flex bison libssl-dev libelf-dev libncurses-dev
完成上述步骤之后,接下来配置编译内核:
1 #使用现存内核的配置文件:xxx指命令输入此处可以按Tab键补全 2 sudo cp /boot/config-xxx -r .config 3 #应用现存配置文件 4 sudo make oldconfig 5 #仅安装已有module 6 sudo make localmodconfig 7 #配置其他编译选项 8 sudo make menuconfig
紧接着就会出现下方的界面,用键盘↑↓键依次选择Kernel hacking,Compile-time checks and compiler options,[*]Compile the kernel with debug info并用Enter敲击,再用键盘←→键选定Save,Enter敲击,然后即可逐步选定Exit,直到退出该界面。
至此,编译内核的一切准备工作都已结束,下面开始编译内核:
1 #保证此时的工作目录是在MenuOS/linux-5.0.1下 2 cd ~/MenuOS/linux-5.0.1 3 #编译,我的主机是i5-9300H+4G虚拟机内存,编译用时约40分钟 4 sudo make
如果想要升级内核,需要的命令如下:
1 sudo make modules_install 2 sudo make install
升级后需重启虚拟机操作系统,然后可以输入uname -a查看升级后的内核版本。
有了内核之后,接下来要做的是通过QEMU加载内核。
这个过程整体上分为三步,分别为,下载安装QEMU,构建MenuOS的根文件目录rootfs,构造MenuOS(在64位环境下编译32位需安装一依赖包)
命令如下:
1 cd .. 2 sudo apt install qemu 3 qemu-system-x86_64 -kernel linux-5.0.1/arch/x86_64/boot/bzImage 4 mkdir rootfs 5 git clone https://github.com/mengning/menu.git 6 cd menu 7 sudo apt-get install libc6-dev-i386
此时距离成功构建MenuOS只差最后一步,此时需要修改~/MenuOS/menu目录下Makefile文件下的一行内容,保证Makefile文件为如下内容:
如果Makefile是只读权限无法修改,那就需要得到root权限,命令如下:
1 cd ~/MenuOS/menu 2 sudo root 3 gedit Makefile
该步骤完成后,即可初始化根目录:
1 make rootfs
若初始化成功,则可以看到如下图所示的界面:
至此,通过本地Linux系统完成构建调试Linux内核网络代码的环境MenuOS系统成功。
下一步开始验证MenuOS的网络可以正常工作。
分别将TCP的服务端集成至MenuOS中,命令如下:
1 cd .. 2 git clone https://github.com/mengning/linuxnet.git 3 cd ./linuxnet/lab2 4 make 5 cd ../../menu/ 6 make rootfs
再集成TCP的客户端:
在此之前需要先修改lab3下的Makefile文件,使其内容如下,修改方法同上:
1 cd .. 2 cd ./linuxnet/lab3 3 make rootfs
客户端和服务端都集成入MenuOS后,此时可以在QEMU下输入如下命令:
1 replyhi 2 hello
如果出现了如下图所示场景,则说明MenuOS的网络可以正常工作:
接下来,利用gdb跟踪内核start_kernel的代码。
首先,修改menu目录下的Makefie文件,在上一次修改的那一行末尾添加 -append nokaslr -s -S
然后,在这个终端下输入如下命令,将QEMU重启:
1 cd ../../menu 2 make rootfs
得到如下界面:
此时切不可将此终端和QEMU界面关闭!
再重新开启一终端,如在MenuOS目录所在的用户家目录下,在这个终端内使用gdb,输入如下命令:
1 gdb 2 file ~/MenuOS/linux-5.0.1/vmlinux 3 target remote:1234 4 break start_kernel 5 c 6 list
结果如下图,可以清楚看到gdb追踪到start_kernel
函数,断点在init/mian.c
的538行:
参考资料:
https://github.com/mengning/net/tree/master/lab3