一、编译qemu
(1) 获取qemu源码
从qemu官网获取源码tar包即可,下面以5.2.0的源码为例。
(2)解压源码
xz -d qemu-5.2.0.tar.xz
tar -xf qemu-5.2.0.tar
(3)进入qemu源码目录
cd qemu-5.2.0
(4)配置编译选项
(x86架构)./configure --target-list=x86_64-softmmu --enable-debug --extra-ldflags='-ldl -Wl,-E'
(arm架构)./configure --target-list=aarch64-softmmu --enable-debug --extra-ldflags='-ldl -Wl,-E' --enable-kvm --enable-virtfs
(5)开始编译
make -j
编译产物在build目录下。
二、使用busybox构建文件系统
(1) 获取源码
从busybox官网获取最新源码,下面以 1.36.1 版本为例。
(2) 解压后进入源码根目录执行以下命令
tar -xf busybox-1.36.1.tar.bz2 && cd busybox-1.36.1
make menuconfig (具体配置参考【busybox配置】)
make
make install
(3) 在 _install 目录下添加以下文件
etc/init.d/rcS
etc/fstab
etc/inittab
其中 etc/init.d/rcS 的内容如下:
#!/bin/sh
/bin/mount -a
/sbin/mdev -s
etc/fstab 的内容如下:
proc /proc proc nodev 0 0
sysfs /sys sysfs nodev 0 0
debugfs /sys/kernel/debug debugfs nodev 0 0
tc/inittab 的内容如下:
::sysinit:/etc/init.d/rcS
console::respawn:-/bin/sh
(4) 在 _install 目录下创建必要的目录
mkdir proc sys tmp
(5) 在 _install 目录下打包 initramfs 文件系统
find . | cpio -o -H newc | gzip -9 > ../initramfs_simple.gz
【busybox配置】
(1) 静态链接
进入 Settings ,选择 Build static binary (no shared libs),即
(2) 指定自定义的库路径
进入 Settings -> Additional LDFLAGS
在文本框内输入库路径,例如自己编译的 glibc 库
-B /home/ctyun/.local/lib
三、使用qemu 启动内核
以 x86 架构为例,把待调试的内核 vmlinuz-5.10.0-136.12.0.90.ctl3.x86_64 和文件系统 initramfs_simple.gz 传给 qemu,具体启动内核的命令如下:
./qemu-system-x86_64 \
-M pc -nographic \
-L ./pc-bios -gdb tcp::1234 -smp 1 -m 2048 \
-append " console=tty0 console=ttyS0 nokaslr " \
-initrd initramfs_simple.gz \
-kernel vmlinuz-5.10.0-136.12.0.90.ctl3.x86_64
此后qemu 的 gdbserver 就会监听 1234 端口,随时等待调试客户端接入。
四、常用的调试方法
【调试内核】
(1) 向 gdb 传入 kernel-debuginfo 包里的 vmlinux 符号:
gdb /path/vmlinux
(2) 连接到arm服务器。假设IP是x.x.x.x,由于端口已确定为1234,则可执行以下命令:
target remote x.x.x.x:1234
(3) 在内核启动处加断点
hbreak start_kernel
(4) 继续启动内核:输入 c 并回车
后续操作基本上与 gdb 调试用户态程序的方法一致。
【调试内核ko模块】
在insmod xxxx.ko 后想调试这个ko的运行代码,那么可以按以下方法进行。
1)查看ko的各section的 addr
有2种方法.
1)方法1:在gdb里打印各section的 addr
以act_ct.ko为例。
首先用readelf -S命令查看act_ct.ko的.text .data .bss的索引,
假设查到的是1、27、33,
然后在do_init_module打断点,断住后执行以下命令:
p /x mod->sect_attrs->attrs[1]->address
p /x mod->sect_attrs->attrs[15]->address
p /x mod->sect_attrs->attrs[18]->address
注:不同ko的.data .bss在attrs里的索引可能不同,可通过如下命令逐一确认:
p mod->sect_attrs->attrs[x]->name
2)方法2:i在OS的shell里通过sysfs文件来查看
假设要看act_ct.ko的.text .data .bss段的 addr,那么依次执行以下命令:
cat /sys/module/act_ct/sections/.text
cat /sys/module/act_ct/sections/.data
cat /sys/module/act_ct/sections/.bss
(2) 添加 ko符号
利用上一步查到的 addr,执行以下命令:
add-symbol-file act_ct.ko [text addr] -s .data [data addr] -s .bss [bss addr]
这样就可以添加断点调试了。