搭建内核开发调试环境
闲来无事, 总结一下内核开发调试环境的搭建过程, 希望能对和我一样的内核新手们有所帮助.
方案
我的测试系统在QEMU中运行, Host和Guest的架构都是x86_64, 用Busybox生成的initrd做为根文件系统, KGDB做为调试器.
生成内核
内核中需要打开的选项是CONFIG_EXPERIMENTAL
, CONFIG_DEBUG_INFO
, CONFIG_KGDB
和CONFIG_KGDB_SERIAL_CONSOLE
, 同时需要关闭CONFIG_DEBUG_RODATA
选项. 然后make bzImage
编译生成内核. 具体选项的意义可以去翻内核文档, 这里就不罗嗦了.
生成根文件系统
打开Busybox的CONFIG_STATIC
和CONFIG_INSTALL_NO_USR
选项, 执行make
和make install
编译并生成, 然后参照下面的步骤创建initrd根文件系统:
mkdir temp && cd temp
#创建系统目录
mkdir -p dev etc/init.d mnt proc root sys tmp
chmod a+rwxt tmp
cp -rf ../busybox/_install/* ./
#挂载系统目录
cat << EOF > etc/fstab
proc /proc proc defaults 0 0
sysfs /sys sysfs defaults 0 0
tmpfs /tmp tmpfs defaults 0 0
EOF
cat << EOF > etc/inittab
::sysinit:/etc/init.d/rcS
::respawn:-/bin/sh
tty2::askfirst:-/bin/sh
::ctrlaltdel:/bin/umount -a -r
EOF
cat << EOF > etc/init.d/rcS
#!bin/sh
/bin/mount -a
#用mdev生成设备文件
/sbin/mdev -s
EOF
chmod 755 etc/init.d/rcS
find ./ | cpio -o -H newc | gzip > ../rootfs.img
启动QEMU
qemu-system-x86_64 -kernel kernel.img -append \
"root=/dev/ram rdinit=/sbin/init" -initrd rootfs.img 或
qemu-system-x86_64 -kernel kernel.img -append \
"root=/dev/ram rdinit=/sbin/init kgdboc=ttyS0,115200 kgdbwait" \
-initrd rootfs.img -serial tcp::1234,server 第二个命令开启了KGDB, 将Guest系统的串口映射到了Host系统的1234端口, 并在启动过程中等待gdb的连接.
启动gdb
内核开启KGDB的情况下, 执行gdb vmlinux
, 其中vmlinux是未压缩的内核. 然后target remote localhost:1234
连接kgdb.
接下来就和普通的gdb没什么大的区别了, 比如在sched_clock函数处设置断点break sched_clock
, continue
继续运行, 到达断点后打印jiffies_64变量print jiffies_64
等等.
另外, 运行过程中可以在测试系统里执行echo g > /proc/sysrq-trigger
让gdb重新得到控制权.
For 懒人
顺手在github上建了个项目, 可以自动搭建整个内核开发调试环境, 详见README.
http://github.com/adam8157/kernel-studio
git clone git://github.com/adam8157/kernel-studio.git