闲来无事, 总结一下内核开发调试环境的搭建过程, 希望能对和我一样的内核新手们有所帮助.
方案
我的测试系统在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
<code>git clone git://github.com/adam8157/kernel-studio.git</code>
转载请注明:爱开源 » 搭建内核开发调试环境