在 x86 上调试 linux kernel

记录一下在 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 调试普通程序一样了。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注