kgdb调试内核或ko
为了更加方便内核调试,社区开发了内核级的调试模块kdb和kgdb,
通过它们可以实现对内核的在线调试。
kgdb调试,在该方式下一共需要两台设备,其中一台为本地的被调试设备,
另一台为远程调试主机,它们可通过串口或网口连接。
在该方式中,本地主机的内核运行kgdb模块,而远程主机需要通过gdb attach到本地
主机的kgdb上,从而实现对内核的源码级调试。
当attach成功后,远程主机上的gdb就可以像调试应用程序一样调试内核。
不仅可以执行打断点、修改变量等操作,也可以向其导入符号表,从而实现源码级调试。
以下为其相应的架构:
Remote host Target
.-------. .-------.
| | | |
| GDB |<---------->|KGDB |
| | | |
.-------. .-------.
操作方式:
1、设置内核配置
CONFIG_KGDB=y, CONFIG_DEBUG_INFO = y, CONFIG_FRAME_POINTER=y,CONFIG_STRICT_KERNEL_RWX is not set 屏蔽掉该选型
2、设置kgdboc参数
kgdboc 是kgdb over consle的缩写,Linux内核使用它作为kgdb串口驱动,
所以需要给它传递一些参数。我们的嵌入式Linux,通过uboot传递即可,开机启动,
停在uboot界面,设置bootargs参数如下:
setenv bootargs ‘console=ttymxc0,115200 kgdboc=ttymxc0,115200 kgdbwait root=/dev/nfs nfsroot=192.168.1.103:/home/henryzu/linux/nfs/rootfs,proto=tcp rw ip=192.168.1.251:192.168.1.103:192.168.1.1:255.255.255.0::eth0:off’
重点是 kgdboc=ttymxc0,115200 kgdbwait,这是kgdboc的启动参数
ttymxc0是所需使用的串口设备名,115200代表波特率,kgdbwait 是一个启动参数,
如果添加了这个参数,内核将在启动的时候在某个地方停下来,
其实可以理解为在内核起始处添加了一个断点,方便主机的gdb软件连接。也可以选择不添加该选项。
3、我把源代码的压缩包scp了一份到开发机上,并解压,又把目标机上编译得到
的vmlinux scp到刚解开的linux源代码的根目录并执行 gdb ./vmlinux运行gdb
4、重启目标机,正常启动后在终端里输入" echo g > /proc/sysrq-trigger ", 以后每次想要让目标机停下来都要输入这条命令触发kgdb
5、 在开发机的gdb命令行输入
(gdb) set remotebaud 115200
(gdb) target remote /dev/ttyUSB0
gdb停下来了,剩下的工作就是一个普通的gdb了,你可以给内核下断点,
然后cont让目标机继续执行。如果你要让目标机主动停下来,
你需要在目标机的终端输入“ echo g > /proc/sysrq-trigger "。
到这里已经可以调试内核和编入内核的驱动了,问题是我们更多的工作是调试动态加载的驱动,
而不是内核。为了调试动态驱动,还有几步要完成。
在目标机上编译驱动并把整个驱动的目录都复制到开发机上,而且保持目录一样,这样会让生活更简单一点。
目标机上insmod驱动,insmod driver_name.ko
cat / sys/module/driver_name/sections/.text" 得到text的地址0x7f000000
echo g > /proc/sysrq-trigger" 这个指令是触发kgdb运行的,输入该指令后,内核就会停下,等待远端gdb连接。,
开发机进入gdb
add-symbol-file driver_name.ko 0x7f000000
target remote /dev/ttyUSB0
参考链接:https://blog.csdn.net/weixin_38832162/article/details/115347640