记录一下在 x86 上编译调试 6.7-rc7 的过程。
编译内核
从 kernel.org 或者 github 下载内核源码然后开始配置:
cd linux
export ARCH=x86
make x86_64_defconfig
make menuconfig
需要启用 debug 支持以及禁用随机地址(否则不能打断点)
Kernel hacking --->
[*] Kernel debugging
[*] Miscellaneous debug code
Compile-time checks and compiler options --->
Debug information (Rely on the toolchain's implicit default DWARF version) --->
(X) Rely on the toolchain's implicit default DWARF version
[*] Provide GDB scripts for kernel debugging
Processor type and features --->
[ ] Randomize the address of the kernel image (KASLR)
然后保存 .config,开始编译:
make -j`nproc`
编译完成后会有提示:
Kernel: arch/x86/boot/bzImage is ready (#2)
制作 rootfs
首先从 github 上下载源码(最新版是 1.36)然后编译:
cd busybox
make menuconfig
编译成一个单独的 binary:
--- Build Options
[*] Build static binary (no shared libs)
创建一个文件并格式化成 ext4:
cd kernel-hacking
truncate -s 1073741824 /path/to/rootfs.img
mkfs.ext4 rootfs.img
建一个临时目录写入文件:
cd kernel-hacking
mkdir fs
sudo mount -t ext4 -o loop rootfs.img fs
cd busybox
sudo make install CONFIG_PREFIX=/path/to/kernel-hacking/fs
cd kernel-hacking/fs
sudo mkdir proc dev etc home mnt
sudo cp -r /path/to/busybox/examples/bootfloppy/etc/* etc
umount kernel-hacking/fs
这里使用 busybox 只是一个很基础的环境,如果需要复杂的运行环境,可以参考 这里 打包一个宿主环境,然后解压到 rootfs 中(只解压就行,不需要 grub 那些配置)。
启动
安装 qemu-system-x86,使用下面的命令测试启动:
qemu-system-x86_64 -kernel /path/to/linux/arch/x86_64/boot/bzImage -hda /path/to/kernel-hacking/rootfs.img -append "root=/dev/sda console=ttyS0" -nographic
Ctrl+A 松开后按 C 退出 qemu。
开始调试
在上面的命令基础上加上选项 -s -S -smp 1
:
qemu-system-x86_64 -kernel /path/to/linux/arch/x86_64/boot/bzImage -hda /path/to/kernel-hacking/rootfs.img -append "root=/dev/sda console=ttyS0" -nographic -s -S -smp 1
其中的选项含义:
-s
:选项-gdb tcp::1234
的简写。-S
:启动时不要自动往下执行,需要在 gdb 连接后手动输入c
。-smp 1
:模拟 1 个 cpu。
启动 gdb:
gdb /path/to/linux/vmlinux
target remote localhost:1234
剩下的就和 gdb 调试普通程序一样了。