此文章为原创,可以转载,请注明来源:https://blog.csdn.net/zhaojia92
kernel是一个庞大的C工程,传统使用gdb+qemu工具调试,但gdb太过简陋,查看源码不方便。本着效率优先的原则,选择eclipse作为kernel的开发环境,可以更方便修改调试kernel代码。下面给出eclipse+qemu调试kernel代码的方法。
一. 软件环境:
1. 操作系统:CentOS 7.5
2. qemu虚拟机:2.12.1
3. kernel源码:4.18.9
4. eclipse版本: eclipse-cpp-2018-12-R-linux-gtk-x86_64
5. 调试平台: x86_64
二. 安装调试软件
1. 安装eclipse
eclipse运行需要Java,首先安装java。下载jre软件包,解压到指定目录/home/jre下:
tar -vzxf ./jre-8u201-linux-x64.tar.gz
在/etc/profile文件末尾添加如下语句并保存:
JAVA_HOME=/home/jre/jre1.8.0_201
PATH=$JAVA_HOME/bin:$PATH
CLASSPATH=$JAVA_HOME/lib
解压eclipse软件包到/home目录:
tar -vzxf ./eclipse-cpp-2018-12-R-linux-gtk-x86_64.tar.gz
进入eclipse目录下,发现存在eclipse可执行文件。至此eclipse安装完成。
2. 编译安装qemu
下载qemu源码包并解压到/home下:
tar -vxf ./qemu-2.12.1.tar.xz
进入目录qemu-2.12.1内,执行如下命令将qemu安装到/usr/local/qemu文件夹内。
./configure --prefix=/usr/local/qemu
make
make install
最后将qemu路径添加到path环境变量内,即修改/etc/profile文件,在文件末尾添加语句:
PATH=/usr/local/qemu/bin:$PATH
qemu安装至此完成。重启机器使JAVA和qemu配置生效。
三. 创建Eclipse工程
解压kernel源码到/home/LinuxProject/下的某一目录。打开Eclipse,点击new->Project,创建Empty C Project,选择编译器为Linux GCC,Workspace路径选择刚才解压kernel源码的路径,点击Finish,即创建了一个kernel工程。但该工程有许多设置需要改变,分别为:
1. 设置编译方式
默认方式为自动生成Makefile文件,需改为使用现有Makefile。
去掉红线标记的复选框,输入Build Command为make -j10,若处理器性能更强,可设置更大的编译并行度。Build directory设置为当前源码路径。接着设置Behavior项,如下图所示:
去掉Build on resource save选项。Build项的Command清空,因为不再需要指定make命令。最后点击Apply and Close保存。
2. include路径指定
打开project属性对话框,设置如下include路径:
3. 生成kernel编译配置文件.config
(1).关闭kernel地址随机化
kernel地址随机化会导致gdb设置的断点无法命中,调试无法进行,必须关闭该特性。Linux kernel 4默认打开该特性。有两种方法可以关闭该特性:
方法1. 直接在menuconfig界面关闭
进入Processor type and features-->Randomize the address of the kernel image(KASLR),去掉勾选。
方法2. 修改Kconfig文件关闭
找到kernel源码的arch/x86/Kconfig文件,修改如下设置并保存:
(2).打开debug info信息
进入kernel源码路径,Bash Shell内输入make menuconfig打开图形配置界面,打开debug info信息。依次按下图操作:
勾选上述划红线部分,save保存后生成.config文件。最后检查一下生成的.config文件是否开启kernel地址随机化,打开.config文件,搜索X86_NEED_RELOCS字符串,发现不存在,证明关闭kernel地址随机化成功。
4. 编译kernel源码
进入eclipse工程内,按下快捷键Ctrl+B开始编译,可见下方Console对话框出现编译信息。经过漫长的等待直至编译完成。
编译完成后,在kernel源码路径下会生成vmlinux大文件,在arch/x86/boot路径下生成bzImage文件。后续调试便使用这两个文件。bzImage为vmlinux的封装和压缩,可以被引导执行。
四. 配置Debug环境
eclipse内点击如下按钮,进入Debug Configuration设置。
创建C/C++ Remote Application对象,设置C/C++ Application为刚才生成的vmlinux文件。由于kernel源码已经编译过,无需再次编译浪费时间,确认已勾选Disable auto build。
点击该页最下方的GDB(DSF) Select other......设置,勾选手动配置并关闭。最后点击Apply完成Main页设置。
注意:Eclipse2018中的设置与旧版eclipse不同,必须将GDB设置为Manual Remote Debugging Launcher,因为默认的自动模式会远程调用gdbserver。在kernel源码调试中,qemu取代了gdbserver,无需自动启动gdbserver。
接着设置Debugger选项卡,设置如下图:
此处设置勾选Stop on startup at,并更改main为start_kernel,表示Debug启动时停留在start_kernel函数处,其他项保持默认。
然后点击该页的Connect选项卡,设置如下图:
设置gdb远程连接的IP和Port,我们此处使用qemu默认的1234端口。点击Apply。
最后将该C/C++ Remote Application显示在Eclipse界面上。即进入Common选项卡,勾选Debug和Run复选框,其他保持默认,点击Apply。
最后Close该对话框。
五. 调试Kernel源码
(1).启动qemu虚拟机。可以编写一个脚本start_qemu.sh方便启动,脚本内容如下:
#!/bin/sh
qemu-system-x86_64 -kernel arch/x86/boot/bzImage -S -s
exit $?
chmod +x ./start_qemu.sh加执行权限。运行脚本 ./start_qemu.sh,弹出Qemu虚拟机界面,Qemu挂起等待gdb远程连接。此时Qemu已经启动gdbserver并默认监听1234端口。
此处没有指定-initrd选项,若需要调试initramfs,可使用Busybox,initramfs文件的详细制作方法此处不再赘述。调试start_kernel函数无需该initramfs文件。
(2). 启动Eclipse Debug调试
切换到Eclipse界面,此时务必不要关闭Qemu。点击Debug按钮,Eclipse开始进入调试模式,暂停到start_kernel函数起始处,此时可以查看汇编代码、变量值、地址等信息。接下来按照一般的程序调试步骤进行即可。