正儿八经上了半年的班了,也接触linux驱动几个月了,不过今天之前还是不会调试。今天也还是没有彻底学会。这篇博客主要是把今天的收获记录下来,方便以后参考。
我的内核版本是:4.9.88
我在3.14.52里面也实验过。
先贴我内核打印的错误信息:
Unable to handle kernel NULL pointer dereference at virtual address 00000004
pgd = 80004000
[00000004] *pgd=00000000
Internal error: Oops: 817 [#1] PREEMPT SMP ARM
Modules linked in: spi_lqd(O)
CPU: 1 PID: 96 Comm: spi1 Tainted: G O 3.14.52-1.1.1_ga #235
task: a8326d00 ti: a82f6000 task.ti: a82f6000
PC is at spi_pump_messages+0xdc/0x480
LR is at _raw_spin_lock_irqsave+0x18/0x5c
pc : [<8041c40c>] lr : [<8075bdc8>] psr: 60070093
sp : a82f7f08 ip : 00000000 fp : a837ddcc
r10: 80d0f504 r9 : 00000001 r8 : a82f6000
r7 : a837ddb4 r6 : a837dc00 r5 : 80d0f504 r4 : a837dde8
r3 : a8902704 r2 : 00000000 r1 : a0070013 r0 : 00000000
Flags: nZCv IRQs off FIQs on Mode SVC_32 ISA ARM Segment kernel
Control: 10c53c7d Table: 38af404a DAC: 00000015
Process spi1 (pid: 96, stack limit = 0xa82f6238)
Stack: (0xa82f7f08 to 0xa82f8000)
7f00: a837ddcc 80d0f504 00000000 a837ddb4 a82f6000 a837ddcc
7f20: 80d0f504 00000000 a837ddb4 a82f6000 00000001 80d0f504 a82f6000 80045408
7f40: a8326d00 00000000 a8194d00 a837ddb4 800453bc 00000000 00000000 00000000
7f60: 00000000 8004528c 36e5fded 00000000 dcd7bffd a837ddb4 00000000 00000000
7f80: a82f7f80 a82f7f80 00000000 00000000 a82f7f90 a82f7f90 a82f7fac a8194d00
7fa0: 800451c0 00000000 00000000 8000e500 00000000 00000000 00000000 00000000
7fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
7fe0: 00000000 00000000 00000000 00000000 00000013 00000000 ff9df7fd f5f7fedb
[<8041c40c>] (spi_pump_messages) from [<80045408>] (kthread_worker_fn+0x4c/0x164)
[<80045408>] (kthread_worker_fn) from [<8004528c>] (kthread+0xcc/0xe4)
[<8004528c>] (kthread) from [<8000e500>] (ret_from_fork+0x14/0x34)
Code: eafffff5 e2432024 e58b2028 e8930005 (e5802004)
---[ end trace 004e9320330cff5a ]---
note: spi1[96] exited with preempt_count 1
它告诉空指针什么的。怎么看懂这个错误信息,可以百度。
我们找到关键的两行:
PC is at spi_pump_messages+0xdc/0x480
LR is at _raw_spin_lock_irqsave+0x18/0x5c
LR就是异常的地方:
这个时候,你可以使用gdb去调试。
操作如下:
arm-poky-linux-gnueabi-gdb vmlinux //arm-poky-linux-gnueabi-gdb 这个是我的交叉编译链。好像直接使用gdb也行
然后输入: l *spi_pump_messages+0xdc 就可以具体到对应的代码处,它会告诉你在哪个文件的哪一行。
如果出现:Reading symbols from vmlinux...(no debugging symbols found)...done.
说明你内核编译的时候没有加添加调试信息的选项。那么你需要重新编译内核,操作如下:
make menuconfig
Kernel hacking --->
Compile-time checks and compiler options --->
[*] Compile the kernel with debug info //我这里之前没有勾选。按y勾选,勾选后就有*号
然后保存,退出,重新编译。
编译完成后,在内核源码的根目录下就有 vmlinux
编译完成,使用 arm-poky-linux-gnueabi-gdb vmlinux 就可以了。