别再费劲了,驱动调试和开发看这篇就够了
一、内核日志快速排错printkdmesg 零基础上手实时追踪运行状态最基础、最常用的调试手段用于打印内核/驱动运行状态、变量值、执行流程。printk内核态打印内核代码中替代 printf带日志级别控制是否输出到控制台C// 内核代码中使用#include// 日志级别优先级从高到低printk(KERN_EMERG紧急系统崩溃\n);printk(KERN_ALERT警报需要立即处理\n);printk(KERN_CRIT严重硬件/软件错误\n);printk(KERN_ERR错误常规错误\n);printk(KERN_WARNING警告潜在问题\n);printk(KERN_NOTICE通知正常但重要信息\n);printk(KERN_INFO信息常规调试信息\n);printk(KERN_DEBUG调试仅调试用\n);// 简化写法推荐pr_info(驱动初始化成功版本%d\n,10);pr_err(寄存器写入失败\n);pr_debug(变量 val %#x\n,val);// 调试级别默认不打印dmesg查看内核日志用户态命令读取内核环形缓冲区的 printk 日志Bash # 基础用法 dmesg # 查看所有日志 dmesg-w # 实时跟踪日志类似 tail-f dmesg-c # 查看并清空日志 dmesg-n8# 开启所有级别日志包含DEBUG dmesg|grep 驱动名 # 过滤自己的驱动日志 # 查看带时间戳的日志 dmesg-T二、免代码查状态procfssysfs 一键洞悉系统与设备底层信息无需修改代码实时查看内核/硬件/进程状态是排查系统、驱动问题的首选。procfs/proc进程内核运行时信息经典虚拟文件系统只读为主用于查看系统状态Bash # 核心调试命令 cat/proc/cpuinfo # 查看CPU信息 cat/proc/meminfo # 查看内存状态 cat/proc/modules # 查看已加载内核模块驱动 cat/proc/cmdline # 查看内核启动参数 cat/proc/interrupts # 查看中断分配排查驱动中断问题 cat/proc/kmsg # 实时内核日志同dmesg cat/proc/[PID]/maps # 查看进程内存映射sysfs/sys设备驱动总线信息Linux 统一设备模型可读写用于调试驱动、硬件寄存器、设备状态Bash # 驱动/设备调试常用路径 ls/sys/class/# 设备类gpio、i2c、tty等 ls/sys/devices/# 所有硬件设备 ls/sys/module/# 内核模块信息 # 实战示例调试GPIO驱动 cat/sys/class/gpio/gpio10/value # 读取GPIO电平 echo1/sys/class/gpio/gpio10/value # 写入GPIO电平 # 查看驱动绑定状态 cat/sys/bus/platform/drivers/xxx_driver/xxx_device三、硬件寄存器直调devmem 硬核读写物理地址跳过驱动速排硬件故障嵌入式/驱动调试神器直接读写物理地址无需驱动即可调试硬件寄存器。用法busybox 自带工具Bash # 格式devmem 物理地址[位宽][值]devmem0x12340000# 读取0x12340000物理地址默认32位 devmem0x123400008#8位读取 devmem0x12340000320x55# 写入0x55到该地址 # 场景排查硬件寄存器配置错误、外设未响应问题⚠️ 警告随意读写物理地址会导致系统崩溃仅用于硬件调试。四、内核崩溃精准定位Oops信息拆解快速锁定崩溃代码行内核/驱动崩溃时自动打印Oops空指针、内存越界、非法指令是定位崩溃代码的核心。关键信息解读Plain Text BUG:Unable to handle kernelNULLpointer dereference at virtual address00000000PC:[]test_driver0x50/0x100# PC指针崩溃的代码地址 LR:[]0xc0654321# 链接寄存器 Processbash(pid:1234,stack limit:0xcf000000)Stack:0xcf001000:...# 栈信息 •PC崩溃的函数偏移直接定位代码行 •NULLpointer dereference空指针访问最常见 •invalid address非法内存访问定位代码行Bash # 用addr2line解析PC地址 arm-linux-gnueabihf-addr2line-e vmlinux c0123456 # 输出/driver/test/test.c:56→ 直接定位崩溃行五、内存bug克星KASAN 内核内存检测越界/泄漏/野指针无所遁形内核级内存越界、内存泄漏、野指针检测工具比Oops更精准是驱动稳定性调试必备。开启方法内核配置Plain Text CONFIG_KASANy # 开启KASAN CONFIG_KASAN_GENERICy # 通用模式推荐 CONFIG_DEBUG_KERNELy调试效果KASAN 会直接打印越界代码行、内存类型栈/堆/全局无需手动分析Plain Text BUG:KASAN:stack-out-of-bounds in test_func0x20/0x50Read of size4at addr0xffffffc000001234task bash直接告诉你栈内存越界在test_func函数第XX行。六、内核用户态交互ioctl 调试利器高效测试驱动命令与参数传递用户态与内核驱动交互的核心接口用于调试驱动命令、参数传递。内核态驱动实现驱动中实现 unlocked_ioctl 回调处理用户态命令Clongtest_ioctl(structfile*file,unsignedintcmd,unsignedlongarg){switch(cmd){caseTEST_CMD_READ:// 自定义命令copy_to_user((void__user*)arg,val,sizeof(val));break;caseTEST_CMD_WRITE:copy_from_user(val,(void__user*)arg,sizeof(val));break;default:return-ENOTTY;}return0;}用户态调试工具编写简单C程序/使用 ioctl 工具测试驱动交互C// 用户态测试代码intfdopen(/dev/test_dev,O_RDWR);ioctl(fd,TEST_CMD_WRITE,write_val);// 发送命令给驱动close(fd);✅ 用途调试驱动命令是否正常响应、参数传递是否正确。七、调试流程标准化一套实战流程搞定内核驱动全场景调试一套驱动开发标准调试流程可以直接套用1.加载驱动insmod xxx.ko2.看日志dmesg -w 查看printk输出排查初始化错误3.查状态cat /proc/modules、ls /sys/class/xxx 确认设备注册成功4.硬件调试devmem 0xXX 读写寄存器验证硬件5.功能测试用户态程序调用ioctl测试驱动功能6.崩溃排查Oops addr2line 定位崩溃代码7.稳定性测试开启KASAN检测内存问题调试技巧核心总结1.基础调试printk 打印 dmesg 查看日志2.系统/设备状态/proc 看系统信息/sys 调试驱动设备3.硬件寄存器devmem 直接读写物理地址4.崩溃定位Oops信息 addr2line 快速找bug5.内存安全KASAN 检测越界/泄漏必用6.驱动交互ioctl 完成用户态与内核态通信这些是 Linux 内核/驱动调试最核心、最高频的技能覆盖90%以上调试场景。