Linux内核驱动开发之KGDB单步调试内核(kgdboc方式)

       如何单步源码级调试Linux内核一直困扰着linux驱动开发人员,内核有其代码量大、逻辑复杂、与硬件交互的特性。因此,有着不同于应用程序的调试方法,据统计Linux内核开发者使用最普遍的调试方法是printk方法,而其他的方法大多是在特殊情况下才会使用。本文介绍的Kgdb调试方法是一种源码级的Linux内核调试器。使用Kgdb调试内核时,需要结合gdb一起使用,使用他们可以对内核进行单步调试,设置断点,观察变量、寄存器的值等。然而也有其限制条件,本文仅简单介绍使用串口的Kgbd的流程(kgdboc方式),除此之外还网卡方式即kdgboe方式,Kgdb调试原理及kgdboe方式配置请参阅博文《Linux内核驱动开发之KGDB原理介绍及kgdboe方式配置》。

/**********************************************************************************************************************************/

原创作品,转载时请务必以超链接形式标明文章原始出处:http://blog.csdn.net/gqb666/article/details/9117597,作者:gqb666  
/**********************************************************************************************************************************/

     关键步骤:

一、配置Linux内核,使其支持KGDB。

    依次进行如下配置:

    $make menuconfig(下面配置为必须进行的           

    Kernel hacking--->
           -*- Magic SysRq key
           [*] Kernel debugging
           [*] Compile the kernel with debug info
           [*] KGDB: kernel debugging with remote gdb --->
                  <*> KGDB: use kgdb over the serial console

         配置成功后进行Linux内核的编译。make uImage并生成uImage拷贝到nfs/tftp服务器,等待u-boot下载内核或者直接烧到flash从flash启动。

二、修改u-boot的启动参数bootargs以支持kgdb调试

          setenv bootargs 'console=ttyS0,115200n8 kgdboc=ttyS0,115200 kgdbwait …… nfsroot=……'

         主要增加以上红色字体部分,指定kgdb使用开发板上的哪个串口,注意这里是串口名而不是设备文件/dev/ttyS0。

三、配置虚拟机与PC机的串口映射。如博主的Vmware虚拟机使用usb转串口到linux下串口设备名为/dev/ttyS1(将在第五步使用)。可以通过mincom进行实际测试。

四、在虚拟机linux系统下使用minicom启动开发板的内核方法如下

                     tftp进行下载内核                  

OMAP3_EVM # tftp
smc911x: detected LAN9220 controller
smc911x: phy initialized  #by guoqingbo
smc911x: MAC 02:01:05:96:02:01
Using smsc911x-0 device
TFTP from server 192.168.1.93; our IP address is 192.168.1.94
Filename 'uImage'.
Load address: 0x82000000
Loading: ################################################################# 
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         ##########################
done
Bytes transferred = 2459200 (258640 hex)

 使用bootm启动linux后会在下面输出信息处停下(要注意的是完成此步骤后务必要手工关闭该minicom会话,因为gdb远程连接时也需要此串口)等待gdb的连接:        

Serial: 8250/16550 driver, 4 ports, IRQ sharing enabled
serial8250.0: ttyS0 at MMIO 0x4806a000 (irq = 72) is a ST16654
console [ttyS0] enabled  #by guoingbo
serial8250.1: ttyS1 at MMIO 0x4806c000 (irq = 73) is a ST16654
serial8250.2: ttyS2 at MMIO 0x49020000 (irq = 74) is a ST16654
kgdb: Registered I/O driver kgdboc.
kgdb: Waiting for connection from remote gdb...

截图来说明一下:


五、使用gdb调试vmlinux文件。使用前述博文在ubuntu10.04成功移植gdbserver及gdbserver使用介绍(用于CCSV5.2远程调试ARM CORTEX-A8程序)移植的 arm-none-linux-gnueabi-gdb进行调试内核文件vmlinux。方法如下

             在linux内核源码根目录下创建一个.gdbinit文件其内容为            

set remotebaud 115200
target remote /dev/ttyS1

           然后同样在Linux内核源码目录下运行如下命令

             arm-none-linux-gnueabi-gdb ./vmlinux

           不出意外的会有如下信息输出则说明已经连接成功,可以像gdb调试应用程序一样调试linux内核了      

Reading symbols from /home/ss/develop_environment/v2/sys/dvsdk/ti-dvsdk_dm3730-evm_4_02_00_06/psp/linux-2.6.32-psp03.00.01.06.sdk/vmlinux...done.
During symbol reading, DW_AT_name missing from DW_TAG_base_type.
During symbol reading, unsupported tag: 'DW_TAG_const_type'.
During symbol reading, Child DIE 0x408b33 and its abstract origin 0x4085ee have different parents.
During symbol reading, DW_AT_type missing from DW_TAG_subrange_type.
kgdb_breakpoint () at kernel/kgdb.c:1744
1744            arch_kgdb_breakpoint();
(gdb) 

截图:


六、若用DDD图形界面调试四个步骤相同,只需第五步中的命令换成

   ddd --debugger arm-none-linux-gnueabi-gdb ./vmlinux  命令即可


                                                           DDD调试内核的界面

  • 8
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: gdb是一个强大的调试工具,可以用于调试Linux内核。使用gdb调试Linux内核需要以下步骤: 1. 编译内核时添加调试信息 在编译内核时需要添加调试信息,可以通过在Makefile中添加以下选项来实现: CONFIG_DEBUG_INFO=y CONFIG_DEBUG_KERNEL=y 2. 启动内核调试 在启动内核时需要添加调试选项,可以通过在grub或者lilo中添加以下选项来实现: debug debug earlyprintk=serial,ttyS0,115200 3. 连接gdb 使用gdb连接内核需要使用kgdb插件,可以通过以下命令加载kgdb插件: modprobe kgdb 然后使用以下命令连接gdbgdb vmlinux (gdb) target remote /dev/ttyS0 4. 使用gdb调试 连接成功后,可以使用gdb进行调试,例如: (gdb) b start_kernel (gdb) c 这将在内核启动时设置断点,并继续执行内核。当内核执行到断点时,gdb将停止执行并等待命令。 以上是使用gdb调试Linux内核的基本步骤,具体调试方法和命令可以参考gdb文档和Linux内核调试文档。 ### 回答2: gdb是一款功能强大的调试器,在日常的编程开发中得到了广泛应用。然而,gdb调试Linux内核时与调试用户态应用程序时有所不同。调试内核需要使用gdb的特殊功能来处理调试内核的问题。在下面的几个方面中,我将解释如何使用gdb调试Linux内核。 1. 准备gdb环境 首先需要将gdb环境设置为可以使用内核符号。在编译内核时,需要在Makefile中添加CONFIG_DEBUG_INFO和CONFIG_DEBUG_KERNEL选项,以支持调试信息。此外,还需要安装所需的内核符号,然后通过"sudo sysctl -w kernel.yama.ptrace_scope=0"以解决防止调试器附加的安全机制问题。 2. 加载内核映像 通过gdb来加载内核映像。使用gdb命令"file vmlinux"来加载内核映像,其中vmlinux是含有调试符号的内核镜像文件。 3. 内核断点调试 可以使用gdb设置内核断点,以调试内核时确定内核程序执行过程中的问题。使用gdb命令"b <function>"设置函数断点,而使用"b * <address>"设置指定地址的断点。 4. 调试内核panic 当内核执行时发生错误时,系统会进入panic状态。如果需要调试内核panic,可以使用gdb命令"handle SIGTRAP noprint pass"来设置中断处理。使用"monitor halt"或直接ctrl+c可以停止内核,查看是什么出问题了,并且使用"cont"命令让内核继续运行。 5. 查看内核堆栈 可以使用gdb命令"bt"来查看内核的堆栈,以确定调试内核时的问题。在通过gdb调试内核处理内核问题时,内核堆栈非常有用。 总的来说,使用gdb调试Linux内核需要更多的操作方式和技巧,但是如果熟练掌握gdb的某些功能和命令,并且了解内核基本结构和运行机制,就可以高效地调试内核出现的问题。 ### 回答3: GDB(GNU调试器)是一个强大的调试工具,也可以用来调试Linux内核。但是,与调试应用程序或用户空间程序相比,内核调试可能会更加复杂。下面是关于如何使用GDB调试Linux内核的一些指南和步骤。 1.编译内核 为了调试内核,首先需要编译内核并安装它。在编译内核时,需要启用符号表。使用如下命令: $ make menuconfig 在Kernel hacking中设置Debug kernel,这将启用符号表的编译。然后使用命令“make”编译内核并安装它。 2.配置调试环境 在内核启动时,启用调试合适的调试器非常重要。例如,可以使用串线调试器而不是控制台输出,因为调试信息可能无法立即打印到控制台。可以通过UART控制台或JTAG调试器进行调试,这通常比控制台输出更可靠。 3.使用GDB连接到内核 使用GDB的第一步是启动GDB,同时指定内核映像文件作为第一个参数。例如,如果内核映像文件为”vmlinuz”,可以使用如下命令连接GDB内核: $ gdb vmlinuz 然后,需要设置GDB的默认连接地址: add-symbol-file /path/to/kernel/vmlinux 0xADDRESS 这里的ADDRESS 应该是编译内核时已知的地址。可以在内核映像文件的/System.map文件中找到地址信息。 4.使用GDB调试 在连接GDB内核后,可以使用GDB来单步执行内核代码或设置断点。可以使用GDB的“step”命令来进入下一个函数调用,并使用“next”命令来执行下一行代码。还可以使用“break”命令设置断点,以捕获特定的行动或事件。 也可以在调试内核时使用一些GDB调试命令,例如:“watch”命令用于设置监视点,以监视变量的值,而不必停止调试器。可以使用“info” 命令,以获取关于调试目标状态的信息。 总之,调试Linux内核需要仔细的计划和准备。在内核源代码中随时插入代码并编译并不是一个高效的方法。使用GDB可以更轻松地捕获和解决内核的问题。通过使用GDB,可以提高软件开发的效率,并确保Linux内核的稳定性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值