linux下qemu调试内核
Ubuntu 24.04 环境下, 调试 Linux 内核, 之前也写过,但是发现新的版本的工具链和内核版本有一些变化,所以重新整理一下。
第一阶段:环境与依赖准备
在开始编译之前,确保所有必要工具已就绪:
1
2
3
4
# 更新并安装必要的编译和调试依赖
sudo apt update
sudo apt install build-essential libncurses-dev bison flex libssl-dev libelf-dev \
libdw-dev dwarves gdb qemu-system-x86 busybox-static
第二阶段:内核配置与编译
下载代码去kernel.org,选择一个稳定版本(如 7.x):
之后按照流程进行编译:
- 解压代码:
1 2 3
xz -d linux-x.x.x.tar.xz tar -xvf linux-x.x.x.tar cd linux-x.x.x
- 清理环境(如果之前编译失败过):
1
make mrproper
- 加载默认配置并开启调试选项:
1 2
make defconfig make menuconfig
在菜单中务必开启:
Kernel hacking->Compile-time checks->Compile the kernel with debug info(勾选)Kernel hacking->Generic Kernel Debugging Instruments->Provide GDB scripts(勾选)Processor type->Randomize the address of the kernel image (KASLR)(取消勾选) 这些分别是- 告诉编译器(GCC)在编译时生成 DWARF(Debugging With Arbitrary Record Formats) 格式的调试信息。
- 在内核编译输出目录中生成一系列用于 GDB 的辅助脚本(Python 编写的)。
- 如果你开启了 KASLR,每次重启 QEMU,内核加载的物理基地址都在变,关闭了固定内核的内存偏移量。这样你可以在 GDB 中设置固定的断点,甚至编写简单的调试脚本,而不必每次重启都重新计算偏移地址。
- 编译内核:
1
make -j$(nproc)
编译成功后,内核镜像位于
arch/x86/boot/bzImage。如果出现了证书报错
1 2
scripts/config --set-str SYSTEM_TRUSTED_KEYS "" scripts/config --set-str SYSTEM_REVOCATION_KEYS ""
第三阶段:制作根文件系统 (Rootfs)
为了让内核能够启动并提供交互环境:
- 构建目录:
1 2 3 4 5
mkdir -p ~/rootfs/{bin,dev,etc,proc,sys} cd ~/rootfs cp /bin/busybox bin/ cd bin ./busybox --install -s
- 编写
init脚本(在~/rootfs下新建init文件):1 2 3 4 5
#!/bin/busybox sh mount -t proc proc /proc mount -t sysfs sysfs /sys echo "System booted successfully!" /bin/sh
给它执行权限:
chmod +x init - 打包:
1
find . -print0 | cpio --null -ov --format=newc | gzip -9 > ../rootfs.cpio.gz
第四阶段:启动与调试
- 启动 QEMU: 建议创建一个启动脚本
start_qemu.sh:1 2 3 4 5 6
qemu-system-x86_64 \ -kernel arch/x86/boot/bzImage \ -initrd ../rootfs.cpio.gz \ -append "console=ttyS0 nokaslr" \ -nographic \ -s -S
- 启动 GDB 调试: 打开一个新的终端,进入内核源码目录:
1
gdb vmlinux
在 GDB 提示符下:
(gdb) target remote :1234 (gdb) break start_kernel (gdb) continue
调试小贴士:
GDB 自动加载脚本:当你连接后,GDB 可能会提示你“加载自动加载脚本以获取内核辅助功能”。在你的
~/.gdbinit文件中添加一行add-auto-load-safe-path /path/to/your/linux-source/,这样可以使用lx-lsmod等内核专用调试命令。修改内核后:如果修改了代码,只需重新运行
make -j$(nproc),然后重启 QEMU 即可,不需要重新制作rootfs。退出 QEMU:如果使用
-nographic模式,按下Ctrl+A然后按X即可强行退出 QEMU。
This post is licensed under CC BY 4.0 by the author.