结合Yocto Qemu与Eclipse单步调试开发Linux Kernel
2017-04-07 16:36
435 查看
使用说明
在以前的博客中说明过使用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来完成, 例如下面是一个例子:$ runqemu qemux86 qemuparams="-s -S " serial runqemu - INFO - Assuming MACHINE = qemux86 runqemu - INFO - Running MACHINE=qemux86 bitbake -e... runqemu - INFO - MACHINE: qemux86 runqemu - INFO - DEPLOY_DIR_IMAGE: /ExtDisk/Projects/Yocto_Rpi3_Morty/x86_build/tmp/deploy/images/qemux86 runqemu - INFO - Running ls -t /ExtDisk/Projects/Yocto_Rpi3_Morty/x86_build/tmp/deploy/images/qemux86/*.qemuboot.conf... runqemu - INFO - CONFFILE: /ExtDisk/Projects/Yocto_Rpi3_Morty/x86_build/tmp/deploy/images/qemux86/core-image-minimal-qemux86-20170327033520.qemuboot.conf runqemu - INFO - Continuing with the following parameters: KERNEL: [/ExtDisk/Projects/Yocto_Rpi3_Morty/x86_build/tmp/deploy/images/qemux86/bzImage] MACHINE: [qemux86] FSTYPE: [ext4] ROOTFS: [/ExtDisk/Projects/Yocto_Rpi3_Morty/x86_build/tmp/deploy/images/qemux86/core-image-minimal-qemux86-20170327033520.rootfs.ext4] CONFFILE: [/ExtDisk/Projects/Yocto_Rpi3_Morty/x86_build/tmp/deploy/images/qemux86/core-image-minimal-qemux86-20170327033520.qemuboot.conf] runqemu - INFO - Running /sbin/ip link... runqemu - INFO - Setting up tap interface under sudo runqemu - INFO - Acquiring lockfile /tmp/qemu-tap-locks/tap0.lock... runqemu - INFO - Created tap: tap0 runqemu - INFO - Running ldd /ExtDisk/Projects/Yocto_Rpi3_Morty/x86_build/tmp/sysroots/x86_64-linux/usr/bin/qemu-system-i386... runqemu - INFO - Interrupt character is '^]' runqemu - INFO - Running /ExtDisk/Projects/Yocto_Rpi3_Morty/x86_build/tmp/sysroots/x86_64-linux/usr/bin/qemu-system-i386 -device virtio-net-pci,netdev=net0,mac=52:54:00:12:34:02 -netdev tap,id=net0,ifname=tap0,script=no,downscript=no -s -S -cpu qemu32 -m 256 -drive file=/ExtDisk/Projects/Yocto_Rpi3_Morty/x86_build/tmp/deploy/images/qemux86/core-image-minimal-qemux86-20170327033520.rootfs.ext4,if=virtio,format=raw -vga vmware -show-cursor -usb -usbdevice tablet -device virtio-rng-pci -serial mon:vc -serial mon:stdio -serial null -kernel /ExtDisk/Projects/Yocto_Rpi3_Morty/x86_build/tmp/deploy/images/qemux86/bzImage -append 'root=/dev/vda rw highres=off console=ttyS0 mem=256M ip=192.168.7.2::192.168.7.1:255.255.255.0 vga=0 uvesafb.mode_option=640x480-32 oprofile.timer=1 uvesafb.task_timeout=-1' Poky (Yocto Project Reference Distro) 2.2 qemux86 /dev/ttyS1 qemux86 login: root
这里说明一下命令的作用:
$ runqemu qemux86 qemuparams="-s -S " serial
即qemuparams中的参数, 其中-S是停下运行:
-S Do not start CPU at startup (you must type 'c' in the monitor).
然后-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-eclipsehttp://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
相关文章推荐
- 使用eclipse开发jsp,如何进行单步调试
- [原创]Liunx 下使用 Eclipse 开发 nginx module,进行单步调试
- 手把手教你使用eclipse+qemu+gdb来单步调试ARM内核【学习笔记】
- Eclipse 3.4开发调试PHP全攻略
- Eclipse开发调试RMI指南
- Sysdeo为Tomcat开发的Eclipse插件调试时,提示"Source Not Found"错误
- MyEclipse + Tomcat + Eclipse 开发调试WEB应用
- 开发一个调试 JSP 的 Eclipse 插件
- Eclipse 3.4 (Ganymede) 开发调试PHP全攻略
- Eclipse开发调试RMI指南 (转)
- 开发一个调试 JSP 的 Eclipse 插件
- Eclipse开发调试RMI指南
- Eclipse + jboss 结合UML,Struts,Hibernate开发J2EE
- appfuse1.8.2结合eclipse开发流程
- eclipse 的单步调试的技巧!
- MyEclipse + Tomcat + Eclipse 开发调试WEB应用
- 开发一个调试 JSP 的 Eclipse 插件
- 开发一个调试 JSP 的 Eclipse 插件
- 转:appfuse结合eclipse开发流程
- Eclipse中开发Web和Maven2的无缝结合