1. 下载、编译Linux5.0.1内核
1.1 下载、解压内核
mkdir menuOs # 创建一个实验目录
# 下载内核源码
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 -xvf linux-5.0.1.tar
cd linux-5.0.1
1.2 配置、编译内核
make defconfig
make menuconfig
# 配置编译内核使之携带调试信息
# Kernel hacking ->Compile-time checks and compiler options -> 按下Y选中 [*]Compile the kernel with debug info
make -j2
2.安装qemu、构造MenuOS
2.1 安装qemu、测试
sudo apt install qemu
# 用第一步编译好的内核进行测试,看qemu是否正常安装并且能启动内核
qemu-system-x86_64 -kernel arch/x86_64/boot/bzImage
2.2 构造MenuOS
# 下载MenuOS。和linux-5.0.1同级目录下
git clone https://github.com/mengning/menu.git
cd menu
vim Makefile
# 修改Makefile,注意路径
# 修改前 qemu -kernel ../linux-3.18.6/arch/x86/boot/bzImage -initrd ../rootfs.img
# 修改后 qemu-system-x86_64 -kernel ../linux-5.0.1/arch/x86_64/boot/bzImage -initrd ../rootfs.img
make rootfs
编译成功后,MenuOS启动成功。用help可以看当前支持的命令
3.用hello/hi验证MenuOS的网络功能
3.1 把TCP服务端集合到MenuOS中
cd ~/menuOS
# 下载网络测试程序
git clone https://github.com/mengning/linuxnet.git
cd linuxnet/lab2
make
# 回到menu目录
cd ../../menu
# 重新编译启动MenuOS
make rootfs
3.2 把TCP客户端集合到MenuOS
cd linuxnet/lab3
vim Makefile
# 修改Makefile
# 修改前 qemu -kernel ../../linux-3.18.6/arch/x86/boot/bzImage -initrd ../rootfs.img
# 修改后 qemu-system-x86_64 -kernel ../../linux-5.0.1/arch/x86_64/boot/bzImage -initrd ../rootfs.img
make roofs
3.3 进入MenuOS,敲help可以看到多了replyhi和hello指令。先启动服务端replyhi,再执行指令hello启动客户端
4.gdb调试
4.1 启动menuOS,内核启动前冻结CPU
cd menu
# 修改Makefile
vim Makefile
# 修改前 qemu-system-x86_64 -kernel ../linux-5.0.1/arch/x86_64/boot/bzImage -initrd ../rootfs.img
# 修改后 qemu-system-x86_64 -kernel ../linux-5.0.1/arch/x86_64/boot/bzImage -initrd ../rootfs.img -append "root=/dev/sda init=/inti nokaslr" -s -S
make rootfs
可以看到在新打开的qemu虚拟机上,是一个黑屏,此时qemu在等待gdb的连接
- 启动选项解释
-S freeze CPU at startup (按'c'开始执行)
-s -gdb tcp:1234的缩写。若不想使用1234端口,可以使用-gdb tcp:xxxx来取代-s选项
kaslr是kernel address space layout randomization的缩写。这里nokaslr表示关掉内核起始地址随机化。
4.2 启动gdb server
新起一个终端
# 启动gdb
gdb
# 在gdb界面中target remote之前加载符号表
file linux-5.0.1/vmlinux
# 建立gdb和gdbserver之间的连接
target remote:1234
# 在gdb界面中设置断点
break start_kernel
# 继续运行
c
# 显示断点处相关的源代码
list