温馨提示×

linux驱动怎样调试

小樊
40
2026-09-09 14:53:57
栏目: 智能运维

在 Linux 下调试驱动(kernel module / 设备驱动)常见手段和思路如下,按“从简单到深入”整理,你可以根据场景选用。


一、基础日志调试(最常用)

1. printk

驱动里最常用:

printk(KERN_INFO "drv: value = %d\n", val);

级别:

  • KERN_ERR
  • KERN_WARNING
  • KERN_INFO
  • KERN_DEBUG

查看日志:

dmesg
dmesg | tail

实时查看:

sudo dmesg -w

sudo tail -f /var/log/kern.log

⚠️ 注意:频繁 printk 会影响性能,甚至死锁。


二、动态调试(Dynamic Debug)

适合不想改代码重新编译的场景。

开启动态调试

mount -t debugfs none /sys/kernel/debug

打开某个文件的 debug 日志

echo "file mydriver.c +p" > /sys/kernel/debug/dynamic_debug/control

查看输出

dmesg

常见选项:

  • +p 打印
  • -p 关闭
  • +f 显示函数名
  • +l 显示行号

三、proc / sysfs 调试接口

在驱动中创建调试节点:

proc 示例

static int my_proc_show(struct seq_file *m, void *v)
{
    seq_printf(m, "debug info\n");
    return 0;
}

sysfs 示例

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

用户态:

cat /sys/class/mydev/debug
echo 1 > /sys/class/mydev/debug

✅ 非常适合参数调试、状态查看。


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

1. KGDB(需要串口或虚拟机)

  • 编译内核:
CONFIG_KGDB=y
CONFIG_KGDB_SERIAL_CONSOLE=y
  • 启动参数:
kgdboc=ttyS0,115200 kgdbwait
  • 主机 GDB:
gdb vmlinux
target remote /dev/ttyS0

✅ 可断点、单步、看变量
❌ 配置复杂,多用于开发板/虚拟机


五、QEMU + GDB(强烈推荐)

如果是学习或调试新驱动:

qemu-system-x86_64 -kernel bzImage -append "console=ttyS0" -nographic -s -S

另一个终端:

gdb vmlinux
target remote :1234

✅ 安全、可重复、不影响真实系统


六、ftrace(函数级跟踪)

查看函数调用

cd /sys/kernel/debug/tracing
echo function > current_tracer
echo my_driver_func > set_ftrace_filter
echo 1 > tracing_on
# 操作驱动
cat trace

✅ 不用改代码
✅ 非常适合分析调用流程


七、崩溃分析(Oops / Panic)

出现 Oops 后:

dmesg

关键信息:

  • RIP(出错指令)
  • Call Trace
  • 寄存器值

使用 addr2line

addr2line -e vmlinux 0xffffffff81234567

使用 crash 工具

crash vmlinux vmcore

八、常见调试建议

  1. 先确认模块是否加载
lsmod | grep mydrv
  1. 确认设备节点
ls /dev/
ls /sys/class/
  1. 确认权限
sudo insmod mydrv.ko
  1. 避免死锁
  • 不要在中断里 printk 太多
  • 不要睡眠(msleep)在原子上下文

九、推荐组合(实战)

场景 推荐方式
快速定位 printk + dmesg
不想重编 dynamic debug
学习驱动 QEMU + GDB
分析流程 ftrace
内核崩溃 Oops + addr2line

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

  • 你用的是 哪个内核版本 / 架构
  • 字符设备 / 块设备 / 网络驱动
  • 现在是 加载失败 / 崩溃 / 行为不对

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

0