使用Qemu+gdb来调试内核

来源:互联网 发布:蔡珍妮淘宝工作室地址 编辑:程序博客网 时间:2024/05/18 03:05

昨天听别人讲使用Qemu和gdb来实现源码级内核调试,今天试了一下,果然非常方便,现简单的记录一下。

 

Qemu是一个开源的虚拟机软件,能够提供全系统的仿真,可以运行在多个平台上,并仿真多个别的平台。Qemu虚拟机是采用动态翻译来实现CPU的仿真的,对硬件的依赖程度低,通过它提供的众多参数,你能够对虚拟的机器进行定制以满足你的需求。

 

要想对内核进行调试,那自然需要重新编译内核了,编译内核的具体方法这里就不罗嗦了,需要注意的是在配置内核时,要将“kernel hacking"中的“compile the kernel with debug info"选上,否则没有调试信息,gdb也难为无米之炊。

 

编译好内核之后,我们还需要制作一个rootfs作为Qemu虚拟机的硬盘,这个步骤可以通过Qemu来完成,大致的步骤如下:

1. 创建一个虚拟的硬盘

# qemu-img create foobar.img 8G  # 创建一个8G的虚拟硬盘

2. 在虚拟的硬盘上安装一个Linux系统

# qemu -hda foobar.img -cdrom xxx.iso -boot d -m 512 -enable-audio -localtime 

# xxx.iso为某linux的发行版本的iso,该命令就是要从iso启动,并将系统安装到foobar.img中

当然,其实也可以将init ram disk作为Qemu的rootfs,但这时需要对initrd进行修改,如果你对initrd不熟悉的话,最好还是花点时间,做个rootfs,这个可以省去一些麻烦。

 

Qemu虚拟机只是提供了一个虚拟的机器,使得程序运行在虚拟机中如同运行真实的物理机器上一样,除此以外,Qemu还必须能够对虚拟机进行完全的控制,但Qemu和gdb又是怎么扯上关系的呢?这是因为Qemu中内置了gdbserver,这使得Qemu能够和远程的gdb进行通讯,通过远程的gdb来控制Qemu虚拟机的执行,从而达到调试的目的。具体的操作如下:

1. 切换到刚刚编译的内核的路径,然后启动Qemu

# qemu -kernel arch/x86/boot/bzImage -initrd /boot/initrd.img-2.6.31-22-generic -gdb tcp::1234 -S

# -kernel 用来指定内核,注arch/x86/bzImage是不带调试信息的内核,vmlinux是带有调试信息的内核

# -initrd 用来指定内核启动时使用的ram disk,

# -gdb tcp::1234表示启动gdbserver,并在tcp的1234端口监听,-S表示在开始的时候冻结CPU直到远程的gdb输入相应的控制命令

2. 启动gdb,并和Qemu进行联系,然后你就可以像调试应用程序那些调试内核了

# gdb

(gdb) file vmlinux

(gdb) target remote :1234

(gdb) b start_kernel

(gdb) c

呵呵,是不是很简单,下面再简单的介绍一下gdb常用的一些调试命令:
help:即时帮助,当你不太记得或不太熟悉某些命令时,一个help就可以搞定
edit:在gdb中使用$EDITOR对某个文件进行编辑,在开始之前可以将$EDITOR设置为自己喜欢的编辑器
list:列出被调试程序当前上下文的源程序
make:相当于在shell中运行make,对工程进行编译,编译完成后使用run即可重新开始调试
run:简写为r,开始运行被调试的程序
break:简写为b,设置一个断点,该断点可以为某个文件的某行,也可是某个函数名,还可以是某个地址,
此外通过if参数还可以设置条件断点

 

backtrace:输出调用堆栈
info:查看当前gdb的各种信息,如断点信息,调用堆栈等

 

step:简写为s,单步执行,每次执行一行源程序,会跟踪进入函数

 

next:简写为n,单步执行,每次执行一行源程序,不跟踪进入函数

stepi:简写为si,单步执行,每次执行一个指令,会跟踪进入函数

 

nexti:简写为ni,单步执行,每次执行一个指令,不跟踪进入函数

 

 

finish:执行直到从当前函数返回
until:简写为u,执行直到所在的循环结束
continue:简写为c,继续执行直到下一个断点或程序结束或gdb收到信号
print:简写p,用来输出某个变量的值,只输出一次,输出结构时可以设置“set print pretty on“,这样观察更方便 
display:观察某个变量,每次执行时都显示相应的变量

x:查看内存,通过相应的参数来执行内存的地址和要显示多少数据

 

原创粉丝点击