构建调试Linux内核网络代码的环境MenuOS系统

内核编译

下载linux内核源代码

命令

mkdir LinuxKernel #首先创建一个目录,作为本次实验的工作目录,名字随意
cd LinuxKernel #进入该工作目录
sudo wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.0.1.tar.xz #下载linux-5.0.1的内核
sudo xz -d linux-5.0.1.tar.xz #解压后缀为xz的内核文件,并在解压完成之后删除原压缩文件
tar -xvf linux-5.0.1.tar #解压新生成的tar后缀的压缩文件

截图

在下载linux-5.0.1的内核这一步可能需要的时间较长,不挂梯子的话速度有些难顶。

1

2

安装内核编译工具

命令

sudo apt install aptitude #解决各种依赖问题,安装一次永久清爽

sudo apt install build-essential
sudo apt install flex
sudo apt install bison
sudo apt install libssl-dev
sudo apt install libelf-dev
sudo apt install libncurses-dev    

注意事项

在Ubuntu中安装libssl-dev的时候系统总是失败,其原因如下:

我想着:那么先将这个编译工具所需要依赖的软件全部安装应该就能行了吧?
结果,这些软件又有依赖关系!
???

aptitude就是用来治各种依赖问题的,再也不需要手动添加依赖包了。

之后就可愉快地安装所需的内核编译工具了。

配置编译内核

命令

cd linux-5.0.1 #进入之前解压好的内核目录
sudo make i386_defconfig #生成32位的配置文件
sudo make menuconfig #进入内核裁剪界面

界面配置选项

在执行命令sudo make menuconfig之后出现以下界面。

界面

按照以下顺序依次选择

  • Kernel hacking

  • Compile-time checks and compiler options

  • Compile the kernel with debug info
    输入Y

  • 保存并一路Exit退出界面

编译

sudo make #编译内核

然后,可以稍事休息一下。

等

等待大约半小时,编译过程结束。。。

升级当前系统内核

命令

sudo make modules_install  #安装前通过系统快照备份系统
sudo make install
sudo update-grub
reboot
uname -a

这里只是展示执行命令,我自己是没有成功的,原因如下。

失败与恢复操作

前面两步我是执行成功的,但是在重启系统之后就出问题了。
在重启后,Ubuntu会卡在这个界面。

卡住

我前前后后等了大概1个多小时,等的我有些绝望,差点我就删系统了。

还好,在谷歌百度一番之后,终于找到了解决方法
在反复启动失败之后,Ubuntu会出现一个启动的高级选项,选择这个高级选项后会发现它能够按照指定的内核版本来进行启动。
这时候,只要选择除linux-5.0.1之外的选项就能够恢复了。

恢复

执行命令的失败可能与本人安装的系统、环境有关,诸君可大胆尝试去执行。

制作根文件系统

QEMU虚拟机加载内核

命令

sudo apt install qemu  # 安装qemu命令

构造MenuOS

命令

cd /LinuxKernel #进入工作目录
mkdir rootfs #创建MenuOS根目录

sudo git clone https://github.com/mengning/menu.git #下载menu系统
cd menu 
sudo apt-get install libc6-dev-i386 #在64位环境编译32位需要安装

sudo chmod 777 Makefile #将Makefile从只读修改为可读写
vim Makefile  #修改Makefile中的内核版本

运行截图

GitHub的下载速度一直很神奇,挂不挂梯子速度都差不多,好在文件不大,等待一段时间就好了。

下载

我们所使用的内核版本是linux-5.0.1,因此在menuMakefile文件中我们也要将其编译所依赖的内核修改过来。

内核版本

值得一提的是:若是你编译所依赖的内核位置与本人不一致,还需要修改其中的目录信息。

编译

命令

sudo make rootfs  #初始化根目录

运行截图

成功

测试MenuOS环境

将TCP网络通信程序的服务器端集成到MenuOS系统

命令

cd /LinuxKernel #进入工作目录 
sudo git clone https://github.com/mengning/linuxnet.git #下载实验代码

cd linuxnet/lab2 #进入服务器目录
sudo make #编译前检查一下Makefile文件中的目录是否与自己的匹配
cd ../../menu/
sudo make rootfs #编译,将服务器端集成到系统中

注意事项

在实验二的代码编译之前,我们需要看一下其Makefile文件的内容:

makefile-lab2

可以看到按照Makefile文件的内容,编译之后会将lab2目录中的两个代码文件拷贝到menu目录中,
但是前提是你的工作目录结构与其所指定的一致。

将TCP网络通信程序的客户端集成到MenuOS系统

命令

cd /LinuxKernel #进入工作目录 

cd linuxnet/lab3 #进入客户端目录
sudo make #同样,在编译前检查一下Makefile,修改其内核版本
sudo make rootfs #编译,将客户端集成到系统中

注意事项

我们查看lab3目录下的Makefile文件,发现与之前menu目录下的Makefile有些类似。
是的,这里需要修改的也是编译所依赖的内核的版本。

makefile-lab2

运行截图

在我们将客户端与服务器端都集成到系统之后,qemu虚拟机所显示的结果与之前构建MenuOS的相同。

但是输入命令help后会看到其中已经添加了客户端以及服务器端所对应的replyhihello命令。

添加了新命令

测试一下这两个命令,可以得到客户端服务器端交互的结果。

测试命令

构建Linux内核的gdb调试环境

在qemu中启动gdb server

命令

sudo qemu -kernel ../linux-5.0.1/arch/x86/boot/bzImage -initrd ../rootfs.img -append  nokaslr -s -S

运行截图

黑屏

在新打开的qemu虚拟机上,出现的是一个黑屏,此时的qemu在等待gdb的连接。

gdb调试

命令

#新建一个终端,在新终端执行以下命令
gdb #进入gdb命令行
file ../LinuxKernel/linux-5.0.1/vmlinux #在gdb界面中targe remote之前加载符号表
break start_kernel # 设置断点
target remote:1234 # 建立gdb和gdbserver之间的连接
c #continue,让qemu上的Linux继续运行
list #查看断点处的代码。

运行截图

gdb界面中targe remote之前加载符号表,如果没有加载的话,后面则无法根据符号来设置断点

我们在start_kernel处设置断点

其执行结果如下。

断点设置

按c后让qemu上的Linux继续运行,可以看到之前一直黑屏的界面继续执行了。

使用list命令,可以查看断点处的源代码,其结果如下图。

查看断点代码

参考链接

庖丁解牛Linux内核
cmdline menu libary

原文地址:https://www.cnblogs.com/RichardTAO/p/12021971.html