通过KGDB进行双机Linux内核调试

来源:互联网 发布:男士休闲裤品牌 知乎 编辑:程序博客网 时间:2024/06/09 21:58




# 原理


## 原理结构图



## 原理过程


Kgdb是双机在线调试,一端是Host端(linux),运行GDB,另一端是Target端,运行带Kgdb的linux内核。
两边通过串口(KGDBoc)或网络口(KGDBoE)相连接,kgdb实现了远程调试的功能,主要部件有:
### stub
stub可卸任是一个运行在target端的代理,它负责与远程的Host端进行沟通,接收Host端发来的指令。








# 应用场景 
如上面原理图所示,常常用于嵌入式开发场景中,开发板作为target端,运行打开Kgdb的内核 ,PC机作为Host端,运行GDB,用来远程调试Target端的内核。








# 内核配置


在内核2.6.26版本之前,Kgdb是以Patch的方式提供,要使用它需要经过复杂的配置过程,并且容易出错,之后,就集成到了内核中,只需要打开相关配置项即可使用了。


这里,我们以内核 4.4.19为例,KGDB的配置如下:


```
  Kernel hacking  ---> 
         [*] KGDB: kernel debugger  ---> 
                  [ ]   KGDB: internal test suite                                                                                                     
                  [*]   KGDB: Allow debugging with traps in notifiers                                                                   
                  [*]   KGDB_KDB: include kdb frontend for kgdb 
```
DEBUG相关配置:


```
    Kernel hacking  --->
         Compile-time checks and compiler options  ---> 
                    [*] Compile the kernel with debug info
```




# 实例:利用virtualBox(ubuntu14.04) 使用Kgdb


## 环境:
- Host:deepin 15.2(64Bit)
- Target:virtualbox(Ubuntu14.04_64bit)
- 连接方式:虚拟串口


## 结构图



## 准备工作








1. 设置虚拟串口


详细参考另一篇博文《[Linux主机和VirtualBox之间实现串口通信](http://blog.csdn.net/java211/article/details/52387726)》






2. 在虚拟机中运行开启KGDB的内核
这里,为了方便测试KGDB,直接使用源码中自带的arch/x86/configs/x86_64_defconf


执行 


```
make x86_64_defconf


```
然后再执行 :


```
make menuconfig
```


参考上面开启KGDB和DEBUG相关的内核配置项。


编译带有调试信息的内核


```
make-kpkg --initrd --revision 001.magc --append-to-version -20160901 kernel_debug kernel_image kernel_headers
```
注:这里kernel_debug和kernel_image要同时有,因为它们产生的deb有依赖关系。






编译成功后,会看到生成三个deb包,并使用dpkg 命令将它安装上去。


另外,还要将此源码和产物,放到HOST里面一份。


3. 修改Guest OS的Grub启动参数


在Guset OS中修改/boot/grub/grub.cfg
找到当前系统使用的内核启动命令行,在后面添加:


```
kgdboc=ttyS0 115200 kgdbwait
```
注:
- kgdboc:是指KGDB over console 使用波特率为115200的ttyS0.
- kgdbwait:是让kernel一直等等待直到连上GDB为止。
- 添加此参数后,需要重启系统来激活这些参数。


4. 在HOST中使用socat来连接虚拟串口的命名管道文件




```
# socat -d -d /home/magc/workspace/vmserial PTY
```


注:
- PTY:是一种pseudo-terminal
- /home/magc/workspace/vmserial:是虚拟串口在HOST上的命名管道文件
- 当运行此命令后,终端进入等待状态,如下图示:




如上所示,得到的pseudo-terminal的设备名是/dev/pts/0 ,这个进程需要在调试过程中一直进行,并且HOST上的GDB会使用这个这设备名


## 开始双机调试


通过上面几步准备工作,使HOST和虚拟机的虚拟串口连接起来,此时重新启动虚拟机。此时,虚拟机会卡住,等等连接HOST上的GDB.


**1. 启动HOST上的GDB:**


进入源码编译目录下(此源码目录是从Guest OS中复制过来的),执行下面命令,启动GDB:


```
# cd linux-4.4.19
# gdb ./vmlinux   
(gdb) target remote /dev/pts/0
```
此时虚拟机仍停止等待,当在GDB中输入下面指令:


```
continue
```
此时虚拟机就会继续启动进入系统了。


若想重新回到GDB控制,只需要在Guest OS中执行下面命令:


```
 echo g > /proc/sysrq-trigger
```
此时,Guest OS就会中止当前会话,回到HOST的GDB控制中。这样就可以增加断点以及调试了。




**2. 调试内核模块:**


若是调试内核的话,按上面操作方法即可满足需求,若是想调试某个单独的内核模块,那就在Guest OS中安装此模块,并拿到此模块的.text段地址(/sys/module/<module_name>/sections/.text) ,并在HOST的GDB中通过add-symbol-file 参数加载进来进行调试即可。






## 小结


通过VirtualBox使用KGDB进行双机调试的主要步骤:
1. 在HOST和Guest OS之间建立虚拟串口连接
2. 在Guest OS里编译安装带Debug的内核,并修改Grub启动参数
3. 在Host里启动GDB,并连接到虚拟串口上,开始双机调试








参考:http://opensourceforu.com/2011/03/kgdb-with-virtualbox-debug-live-kernel/







0 0
原创粉丝点击