温馨提示×

如何调试linux驱动

小樊
59
2026-09-03 12:46:09
栏目: 智能运维

调试 Linux 驱动是内核开发中非常重要、也最容易踩坑的一环。下面从准备、常用手段、典型流程、常见工具几个层面系统地讲一下。


一、调试前的准备

1. 使用合适的内核配置

在编译内核或驱动时,确保开启以下选项:

CONFIG_DEBUG_KERNEL=y
CONFIG_DEBUG_INFO=y
CONFIG_KALLSYMS=y
CONFIG_DEBUG_DRIVER=y
CONFIG_DYNAMIC_DEBUG=y
CONFIG_MAGIC_SYSRQ=y

如果是学习/调试:

CONFIG_DEBUG_STACKOVERFLOW=y
CONFIG_DEBUG_SPINLOCK=y
CONFIG_PROVE_LOCKING=y

2. 使用 printk 是最基本的手段

驱动中最常用的调试方式:

printk(KERN_DEBUG "my_driver: reg=%x\n", reg);

查看日志:

dmesg
dmesg -w   # 实时查看

日志级别(从高到低):

KERN_EMERG > ALERT > CRIT > ERR > WARNING > NOTICE > INFO > DEBUG

控制控制台日志级别:

echo 8 > /proc/sys/kernel/printk

二、动态调试(推荐)

1. 动态调试(dynamic debug)

不需要重新编译驱动:

# 打开某个文件的调试
echo 'file my_driver.c +p' > /sys/kernel/debug/dynamic_debug/control

# 打开某个函数
echo 'func my_probe +p' > /sys/kernel/debug/dynamic_debug/control

查看输出:

dmesg

三、使用 /sys/proc 调试接口

1. 创建调试节点

static ssize_t debug_show(struct device *dev,
                          struct device_attribute *attr, char *buf)
{
    return sprintf(buf, "debug info\n");
}
DEVICE_ATTR_RO(debug);

用户态访问:

cat /sys/class/mydev/debug

四、使用 GDB + KGDB(内核级调试)

1. KGDB(串口 / 网络)

适合死机、Oops、卡死等严重问题。

内核配置:

CONFIG_KGDB=y
CONFIG_KGDB_SERIAL_CONSOLE=y

启动参数(示例):

kgdboc=ttyS0,115200 kgdbwait

主机端:

gdb vmlinux
target remote /dev/ttyS0

五、Oops / Panic 分析(非常重要)

1. 常见错误类型

  • NULL pointer dereference
  • Use after free
  • Stack overflow
  • Lock deadlock

2. 分析 Oops

dmesg

关键字段:

RIP: xxx
Call Trace:

使用 addr2line

addr2line -e vmlinux 0xffffffff81234567

或使用 gdb

gdb vmlinux
list *(func+0x50)

六、使用 Ftrace(函数跟踪,强烈推荐)

1. 基本使用

cd /sys/kernel/debug/tracing
echo function > current_tracer
echo my_probe > set_ftrace_filter
echo 1 > tracing_on
# 触发驱动
cat trace

2. 跟踪函数调用关系

echo function_graph > current_tracer

七、使用 perf(性能 & 调用分析)

perf record -g insmod mydrv.ko
perf report

适合:

  • 驱动性能问题
  • 中断处理耗时
  • 锁竞争

八、常见调试流程(实战思路)

驱动加载失败

  1. dmesg 看 Oops / 错误信息
  2. 检查 probe() 返回值
  3. 确认设备树 / 资源(IRQ、IO、MMIO)

驱动运行时异常

  1. printk 定位大致位置
  2. ftrace 看函数调用
  3. kgdb 断点调试

系统卡死

  1. SysRq
    echo t > /proc/sysrq-trigger   # 查看进程栈
    echo p > /proc/sysrq-trigger   # panic
    
  2. KGDB 断点

九、推荐调试组合(经验)

场景 推荐工具
普通逻辑问题 printk + dynamic debug
函数调用分析 ftrace
严重崩溃 KGDB + Oops
性能问题 perf
并发/锁 lockdep

如果你愿意,可以告诉我:

  • 你调试的是 字符设备 / 块设备 / 网络驱动 / USB / PCI
  • 加载失败 / 运行时崩溃 / 功能异常

我可以直接给你针对性的调试步骤和示例代码

0