实验作业三:构建调试Linux内核网络代码的环境MenuOS系统

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

实验环境:

Ubuntu 18.04.2 LTS

实验过程:

(1)取得 linux 内核源码:wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.0.1.tar.xz,然后输入以下命令进行解压:xz -d linux-5.0.1.tar.xz 得到后缀为.tar的压缩包,再输入tar -xvf linux-5.0.1.tar 进行解压,此时你应该得到一个名为 linux-5.0.1的文件夹,输入 cd linux-5.0.1 进行该文件夹。

(2)安装内核编译工具:sudo apt install build-essential flex bison libssl-dev libelf-dev libncurses-dev

(3)配置编译内核:首先输入 make defconfig,然后输入 make menuconfig,此时会弹出来一个界面,我们依次选择 Kernel hacking—>Compile-time checks and compiler options ---> [*] Compile the kernel with debug info,注意,最后一项本来是没有勾选的,即原本是 [] Compile the kernel with debug info,我们需要输入 Y 以勾选此项。类似于下图这样即可。

最后输入 make 进行编译即可,这个过程会比较漫长,请耐心等待。

(4)安装 qemu 虚拟机:sudo apt install qemu

(5)有了内核之后,如果我们直接输入 qemu-system-x86_64 -kernel linux-5.0.1/arch/x86/boot/bzImage 命令启动 linux 内核的话,会报 VFS: Unable to mount root fs on unknown block 的错误,这是因为仅仅有 linux 内核还不是一个完整的 linux 系统,我们需要有根文件系统及用户态的程序,用户态至少要有一个 init 可执行程序。

(6)首先输入 dd if=/dev/zero of=rootfs.img bs=1M count=128,然后输入 mkfs.ext4 rootfs.img,接着输入 mkdir rootfs,此时我们准备制作跟文件系统和 init 程序。

(7)输入 sudo mount -o loop rootfs.img rootfs,再输入 git clone https://github.com/mengning/net.git。先看一下此时的目录结构:

 接着,我们进入 net/lab3下,再开一个终端,输入 make 命令,我们会得到 init 程序,然后将其拷贝到与 linux-5.0.1的同级目录下,然后输入 cp init rootfs/ ,最后输入 sudo umount rootfs,此时所有准备工作就完成了。

(8)我们输入 qemu-system-x86_64 -kernel linux-5.0.1/arch/x86_64/boot/bzImage -hda rootfs.img -append "root=/dev/sda init=/init nokaslr" -s -S 启动虚拟机,此时我们会在 qemu界面上看到 stopped 的字样。我们打开另外一个终端,输入 gdb,

进入  gdb 的调试界面,然后输入 file linux-5.0.1/vmlinux,接着输入 target remote:1234,则可以建立gdb和gdbserver之间的连接,接着输入break start_kernel,再按c 让qemu上的Linux继续运行。我们会看到如下界面:

(9)在 MenuOS中输入 help 可以得到一些命令的提示,其中包括 replyhi 和 hello 这两个命令,我们依次输入这两个命令可以得到:

replyhi 和 hello 是已经集成好的网络通信程序,我们进入 net/lab3下打开 main.c 文件,可以发现 main函数中有以下代码:

MenuConfig 的作用就是对 MenuOS添加新的命令,我们可以看到 replyhi 命令具体调用了 StartReplyhi函数,我们查看该函数,发现它又调用了 ReplyHi函数:

这里调用的诸如 ServiceStart()、RecvMsg()等函数都是定义在 syswrapper.h 头文件中的宏函数,它们其实就是和之前C/S网络通信程序中的 server.c 基本一样。可以看作是对 Linux Socket 的接口。

(10)激活网络设备接口:该项工作也是已经集成好的,直接查看 net/lab3文件夹下的 main.c 文件中的 BringUpNetInterface()函数即可,当我们成功看到 MenuOS时,该项工作就已经完成了,而且上一步成功调用 replyhi 和 hello 命令就已经证实了这一点。

猜你喜欢

转载自www.cnblogs.com/vectorustc/p/12005286.html