结合Yocto Qemu与Eclipse单步调试开发Linux Kernel

使用说明

在以前的博客中说明过使用Qemu + BuildRoot来构建一个虚拟的嵌入式开发平台, 还写过使用Yocto + Qemu来构建一个Cortex-A9的嵌入式开发调试平台. 同时在很久以前也写过使用Eclipse + JLINK来调试ARM9. 而在工作学习中,有时候, 对内核源码的研究中, 需要单步对linux内核跟踪调试, 且大部分是关注与内核中某些组件的实现, 例如MM, Binder驱动, 这个时候直接使用Qemu + Eclipse来调试与开发就比使用硬件方便快捷得多了.

那么这篇文章中将使用: Yocto + Qemu + Eclipse来调试与开发kernel.

准备

获取Yocto的layers, 即metas, 然后构建一个MACHINE为qemux86的rootfs, 使用core-image-minimal为bitbake target构建对应的rootfs. 构建完成后就可以直接启动Yocto构建出来的Qemu来模拟调试了.

内核的准备

开启debug info, 以及Provide  GDB scripts.


勾选FRAME POINTER


为gdb准备还需要开启KGDB.

关于如何开启与编译, 可以参考以前的Yocto的专栏文章.

编译完成后, 得到的vmlinux将会非常庞大, 因为包含了debug info. 而这个vmlinux将会在Eclipse中使用.

在Eclipse中准备调试配置

在Eclipse的Debug Configurations中新建一个C/C++ Attach to Application, 为什么是这个? 这是因为我们在Kernle中配置了KGDB, 配合Qemu的参数, 那么相当于开启了一个gdbserver在等待gdb的连接.

在Main Tab中选择要添加时候加载的文件, 为带有调试信息的vmlinux.


在Debugger中选择我们要连接到gdbserver中:


而且gdbserver的连接方式使用TCP, Port为1234:


接下来选择kenrel source code, 注意新版本的Yocto的kernel source code path已经变更:


完成配置后保存.

开启Qemu等待EClipse gdb调试

可使用runqemu来完成, 例如下面是一个例子:

这里说明一下命令的作用:

即qemuparams中的参数, 其中-S是停下运行:

然后-s则是开启kgdb端口, 即相当于使用gdbserver加载了内核, 同时这个端口是默认的1234

而serial则表示将console=stdio, 即将Guest OS中的串口output到这个Terminal的stdout, 即我们的终端中.

使用

在准备好后, 我们确定一下Qemu中的kernel的gdbserver是否已经准备好, 使用netstat查看对应TCP端口是否已经创建:


上面的图中, 我们可以看到qemu-system-i386, 即runqemu封装的, 开启了端口1234.

然后我们开启Eclipse的Debug, 如果正确的话, 我们可以看到前面图中的gdb那行也是打开了1234端口. 

启动调试后, 此时Qemu的vmlinux处于等待status, 我们可以先设定一个breakpoint, 要完成这个设置, 即可在source code中直接设置, 也可以使用命令设置, 例如下面的第一行蓝色字体的就是使用命令设置:


第二行则是加载了要Qemu/gdbserver运行的程序, 当然实际上我们前面已经指定了, 所以这个地方并不需要.

同时可以留意到, 里面使用了vmlinux-gdb.py, 我们前面在内核menuconfig中指定的要生成的script.

因为没有.gdbinit, 所以其实前面的这个gdb init script无效. 如果需要做特殊处理那么可以放在这里面.

开始调试

然后我们自己点击continue按钮, 让内核开始运行, 它会在我们设置的断电处stop:


且自动打开source.

那么如果我们想到某个文件中设置断电该怎么办呢?

我们可以直接使用Eclipse的菜单File中的Open去打开, 然后设置即可:


然后在对应行双击设置即可:


在我们需要查看的地方也可以看变量, dump memory, 查看regs, 效果图如下.


到此就可以愉快的进行调试了. 但是因为我们没有创建Project, 所以无法对Kernel Source Code进行index, 因此大家还可以添加kernel code进行index从而更好的调试.

问题与解决

使用过程中, 因为Host CPU是Intel的支持虚拟化, 因此我一开始尝试使用了KVM, 结果发现无法单步调试, 因此在使用qemu来调试的时候不要开启KVM.

参考

http://www.yonch.com/tech/84-debugging-the-linux-kernel-with-qemu-and-eclipse

http://www.sw-at.com/blog/2011/02/11/linux-kernel-development-and-debugging-using-eclipse-cdt/

http://issaris.blogspot.jp/2007/12/download-linux-kernel-sourcecode-from.html

Leave a Reply

Your email address will not be published. Required fields are marked *