Welcome 微信登录
编程资源 图片资源库 蚂蚁家优选 PDF转换器

首页 / 操作系统 / Linux / Linux 内核调试4-Qemu调试Linux内核

通过UML可以方便的在本机调试Linux内核,UML是一种特殊的虚拟机,另外一种更为灵活的虚拟机是Qemu,Qemu是一种完全仿真虚拟机, 可以在i386平台仿真任意其他处理器构架,而且支持GDB调试,这里尝试一下使用Qemu调试Linux内核,Qemu参数-kernel可以直接指定 内核启动,这与UML有相似之处。首先需要编译安装Qemu,这里并没有什么疑惑之处,直接从官方网站下载源码,使用Linux最常用的编译命令即可:# 默认选项会编译所有处理器构架虚拟机# 可以 ./configure --help 查看编译特定平台的配置cpp@dark:~/qemu-0.12.4$ ./configure --target-list=i386-softmmucpp@dark:~/qemu-0.12.4$ makecpp@dark:~/qemu-0.12.4$ make install接下来以默认选项编译内核,不过巨崩溃的是内核默认没有DEBUG_INFO选项,所以虽然能在导出符号部分断下来,但是没有源码,所以需要选则Compile the kernel with debug info选项。# 默认选项cpp@dark:~/linux-2.6.34$ make defconfig# 配置菜单,选择调试信息cpp@dark:~/linux-2.6.34$ make menuconfig# 编译内核cpp@dark:~/linux-2.6.34$ make然后使用Qemu加载内核启动cpp@dark:~/linux-2.6.34$ qemu -s -S -kernel arch/x86/boot/bzImage -hda rootfs.img -append "root=/dev/sda"# 其中一些选项的解释如下# -s 监听tcp:1234端口以等待GDB连接# -S 虚拟机启动后停止,以便GDB连接后调试启动过程# -kernel 压缩内核# -hda 硬盘# -appand 启动参数这里系统很容易启动不了,如果系统由于VFS加载错误无法启动,首先尝试启动参数root=/dev/sda为root=/dev /hda,hda是IDE硬盘标识,sda为SCSI硬盘,这要看内核识别成哪种,如果仍然不行,那要检测rootfs.img根文件系统的格式跟内核所 支持的格式是否匹配,2.6.34支持ext3格式,如果格式错误,可以利用 Linux 内核调试1 里的方法,自己手工创建一个ext3格式的文件,然后mount到临时文件,把其他根文件系统全部拷贝进去即可。这 样启动Qemu之后,发现系统一片黑屏,这里因为Qemu启动参数被设置为禁止,Qemu本身具有显示窗口和控制窗口,利用 Ctrl+Alt+2 进入控制台,c命令继续虚拟机,Ctrl+Alt+1 返回显示窗口,Qemu的控制台可以控制很多选项,从这点来看要比VMware等要灵活一些,UML本身也支持运行时控制。接下来使用GDB启动虚拟机,当系统停止在启动之后时,用GDB加载:# 启动GDB,GDB加载未压缩内核cpp@dark:~/linux-2.6.34$ gdb vmlinuxGNU gdb 6.8Copyright (C) 2008 Free Software Foundation, Inc.License GPLv3+: GNU GPL version 3 or later This is free software: you are free to change and redistribute it.There is NO WARRANTY, to the extent permitted by law.Type "show copying"and "show warranty" for details.This GDB was configured as "i486-slackware-linux"...(gdb)# 设置断点(gdb) br start_kernelBreakpoint 1 at 0xc172f5d4: file init/main.c, line 533.# 连接Qemu监听端口1234(gdb) target remote localhost:1234Remote debugging using localhost:1234[New Thread 1]0x0000fff0 in ?? ()# 继续Qemu虚拟机执行(gdb) cContinuing.# 内核解压之后很快便到达断点Breakpoint 1, start_kernel () at init/main.c:533533 smp_setup_processor_id();(gdb)# 接下来便可任意调试内核(gdb) list528 asmlinkage void __init start_kernel(void)529 {530 char * command_line;531 extern struct kernel_param __start___param[], __stop___param[];532533 smp_setup_processor_id();534535 /*536* Need to run as early as possible, to initialize the537* lockdep hash:(gdb)Qemu由于是完全仿真实现,所以可以在任意平台调试其他构架内核,理论上甚至可以在Windows平台交叉编译Linux内核,再去由Qemu加载调试(交叉编译比较麻烦,需要先编译目标构架的binutil,而后链接内核)。相关系列文章:
Linux 内核调试1-UML http://www.linuxidc.com/Linux/2012-07/66410.htm
Linux 内核调试2-UML调试内核 http://www.linuxidc.com/Linux/2012-07/66411.htm
Linux 内核调试3-UML网络配置 http://www.linuxidc.com/Linux/2012-07/66412.htm
Linux 内核调试4-Qemu调试Linux内核 http://www.linuxidc.com/Linux/2012-07/66413.htm
Linux 内核调试5-UML和Qemu调试模块 http://www.linuxidc.com/Linux/2012-07/66414.htm
Linux 内核调试6-使用KGDB双机调试 http://www.linuxidc.com/Linux/2012-07/66415.htm