本文是基于linux2.6.28.6版本内核,使用led驱动和内核定时器驱动模拟灯闪(并且在内核定时器驱动中断函数中使用空指针模拟kernel panic错误)。以报错信息为根据,通过对驱动程序进行反编译与获得的系统中函数对应地址进行对比。从而定位kernel panic是哪里引起的。
一、下面为报错的信息:
/usr/local/nbpt/ltx # ./leds_test
[ 4000.935000] Unable to handle kernel NULL pointer dereference at virtual addre[ 4000.955000] Kernel panic - not syncing: Fatal exception in interrupt
二、cat /proc/kallsyms > /usr/local/nbpt/kallsyms 把内核中函数和地址对应信息列出来 如下:(这里只截取关键部分日志)
00000000 a timerdriver.c [timerdriver]
bf0c0000 t second_read [timerdriver]6
bf0c0000 t $a [timerdriver]
bf0c0030 t $d [timerdriver]
bf0c0034 t $a [timerdriver]
bf0c0070 t $d [timerdriver]
bf0c0ad8 d second_major [timerdriver]
bf0c0078 t $a [timerdriver]
bf0c0168 t $d [timerdriver]
bf0c02d0 r second_fops [timerdriver]
bf0c0184 t $a [timerdriver]
bf0c01a8 t $d [timerdriver]
bf0c01ac t $a [timerdriver]
bf0c0228 t $d [timerdriver]
bf0c0234 t second_timer_handler [timerdriver]
bf0c0234 t $a [timerdriver]
bf0c029c t $d [timerdriver]
c49443c0 ? __mod_second_majortype138 [timerdriver]
bf0c038c r __param_second_major [timerdriver]
bf0c038c r $d [timerdriver]
bf0c033c r __param_str_second_major [timerdriver]
c49443dc ? __mod_license136 [timerdriver]
c49443f4 ? __mod_author135 [timerdriver]
bf0c0ad8 d $d [timerdriver]
bf0c02d0 r $d [timerdriver]
00000000 a timerdriver.mod.c [timerdriver]
bf0c0b94 d $d [timerdriver]
c4944400 ? __module_depends [timerdriver]
c494440c ? __mod_vermagic5 [timerdriver]
c494b986 n $d [timerdriver]
c00b53a0 u alloc_chrdev_region [timerdriver]
bf0c0c20 b p [timerdriver]
bf0c0ae0 d __this_module [timerdriver]
bf0c0184 t second_release [timerdriver]
bf0c0034 t cleanup_module [timerdriver]
c00adc0c u kfree [timerdriver]
bf0c0c24 b second_devp [timerdriver]
bf0c0034 t second_exit [timerdriver]
c006b3a8 u init_timer [timerdriver]
bf0c0078 t init_module [timerdriver]
c01a6afc u __put_user_4 [timerdriver]
c00ae32c u kmem_cache_alloc [timerdriver]
c00b4e5c u cdev_add [timerdriver]
c006b620 u mod_timer [timerdriver]
c00628f4 u printk [timerdriver]
c01a6a20 u __memzero [timerdriver]
c0485c30 u jiffies [timerdriver]
c0074c80 u param_set_int [timerdriver]
c00b4fa4 u unregister_chrdev_region [timerdriver]
bf0c01ac t second_open [timerdriver]
c04886b0 u malloc_sizes [timerdriver]
c00b52ec u register_chrdev_region [timerdriver]
c006b4f0 u del_timer [timerdriver]
c0074a48 u param_get_int [timerdriver]
bf0c0078 t second_init [timerdriver]
c00b4bc4 u cdev_init [timerdriver]
c006b560 u __mod_timer [timerdriver]
c00b4e24 u cdev_del [timerdriver]
对比以上获取的信息就可以断定是哪个文件中对应哪个函数导致的错误。
三、/usr/local/arm/4.2.2-eabi/usr/bin/arm-linux-objdump -D timerdriver.ko > timerdriver.dis(截取关键部分信息)
根据内核打印的错误信息:pc指向地址bf0c0254
timerdriver.ko: file format elf32-littlearm
Disassembly of section .note.gnu.build-id:
00000000 <.note.gnu.build-id>:
0: 00000004 andeq r0, r0, r4
4: 00000014 andeq r0, r0, r4, lsl r0
8: 00000003 andeq r0, r0, r3
c: 00554e47 subseq r4, r5, r7, asr #28
10: 1f98492e svcne 0x0098492e
14: a1cc2a60 bicge r2, ip, r0, ror #20
18: fc71b081 ldc2l 0, cr11, [r1], #-516
1c: 32d101c2 sbcscc r0, r1, #-2147483600 ; 0x80000030
20: 1f857cbf svcne 0x00857cbf
Disassembly of section .text:
00000000 <second_read>:
0: e1a0c00d mov ip, sp
4: e92dd800 push {fp, ip, lr, pc}
8: e24cb004 sub fp, ip, #4 ; 0x4
c: e59f301c ldr r3, [pc, #28] ; 30 <second_read+0x30>
10: e1a00001 mov r0, r1
14: e5931000 ldr r1, [r3]
18: e591203c ldr r2, [r1, #60]
1c: ebfffffe bl 0 <__put_user_4>
20: e3500000 cmp r0, #0 ; 0x0
24: 03a00004 moveq r0, #4 ; 0x4
28: 13e0000d mvnne r0, #13 ; 0xd
2c: e89da800 ldm sp, {fp, sp, pc}
30: 00000000 .word 0x00000000
00000034 <cleanup_module>:
34: e1a0c00d mov ip, sp
38: e92dd810 push {r4, fp, ip, lr, pc}
3c: e24cb004 sub fp, ip, #4 ; 0x4
40: e24dd004 sub sp, sp, #4 ; 0x4
44: e59f4024 ldr r4, [pc, #36] ; 70 <cleanup_module+0x3c>
48: e5940000 ldr r0, [r4]
4c: ebfffffe bl 0 <cdev_del>
50: e5940000 ldr r0, [r4]
54: ebfffffe bl 0 <kfree>
58: e59f3014 ldr r3, [pc, #20] ; 74 <cleanup_module+0x40>
5c: e3a01001 mov r1, #1 ; 0x1
60: e5930000 ldr r0, [r3]
64: e1a00a00 lsl r0, r0, #20
68: ebfffffe bl 0 <unregister_chrdev_region>
6c: e89da818 ldm sp, {r3, r4, fp, sp, pc}
...
00000078 <init_module>:
78: e1a0c00d mov ip, sp
7c: e92dd830 push {r4, r5, fp, ip, lr, pc}
80: e24cb004 sub fp, ip, #4 ; 0x4
84: e24dd008 sub sp, sp, #8 ; 0x8
88: e59f50d8 ldr r5, [pc, #216] ; 168 <init_module+0xf0>
8c: e5951000 ldr r1, [r5]
90: e1a00a01 lsl r0, r1, #20
94: e3510000 cmp r1, #0 ; 0x0
98: e50b0018 str r0, [fp, #-24]
9c: 0a00001e beq 11c <init_module+0xa4>
a0: e3a01001 mov r1, #1 ; 0x1
a4: e59f20c0 ldr r2, [pc, #192] ; 16c <init_module+0xf4>
a8: ebfffffe bl 0 <register_chrdev_region>
ac: e3500000 cmp r0, #0 ; 0x0
b0: ba000017 blt 114 <init_module+0x9c>
b4: e59f30b4 ldr r3, [pc, #180] ; 170 <init_module+0xf8>
b8: e3a010d0 mov r1, #208 ; 0xd0
bc: e5930014 ldr r0, [r3, #20]
c0: ebfffffe bl 0 <kmem_cache_alloc>
c4: e59f40a8 ldr r4, [pc, #168] ; 174 <init_module+0xfc>
c8: e3500000 cmp r0, #0 ; 0x0
cc: e5840000 str r0, [r4]
d0: 0a00001f beq 154 <init_module+0xdc>
d4: e3a01058 mov r1, #88 ; 0x58
d8: ebfffffe bl 0 <__memzero>
dc: e5944000 ldr r4, [r4]
e0: e5955000 ldr r5, [r5]
e4: e1a00004 mov r0, r4
e8: e59f1088 ldr r1, [pc, #136] ; 178 <init_module+0x100>
ec: ebfffffe bl 0 <cdev_init>
f0: e59f3084 ldr r3, [pc, #132] ; 17c <init_module+0x104>
f4: e1a05a05 lsl r5, r5, #20
f8: e1a00004 mov r0, r4
fc: e5843024 str r3, [r4, #36]
100: e1a01005 mov r1, r5
104: e3a02001 mov r2, #1 ; 0x1
108: ebfffffe bl 0 <cdev_add>
10c: e3500000 cmp r0, #0 ; 0x0
110: 1a000009 bne 13c <init_module+0xc4>
114: e24bd014 sub sp, fp, #20 ; 0x14
118: e89da830 ldm sp, {r4, r5, fp, sp, pc}
11c: e59f3048 ldr r3, [pc, #72] ; 16c <init_module+0xf4>
120: e24b0018 sub r0, fp, #24 ; 0x18
124: e3a02001 mov r2, #1 ; 0x1
128: ebfffffe bl 0 <alloc_chrdev_region>
12c: e51b3018 ldr r3, [fp, #-24]
130: e1a03a23 lsr r3, r3, #20
134: e5853000 str r3, [r5]
138: eaffffdb b ac <init_module+0x34>
13c: e1a01000 mov r1, r0
140: e3a02000 mov r2, #0 ; 0x0
144: e59f0034 ldr r0, [pc, #52] ; 180 <init_module+0x108>
148: ebfffffe bl 0 <printk>
14c: e3a00000 mov r0, #0 ; 0x0
150: eaffffef b 114 <init_module+0x9c>
154: e51b0018 ldr r0, [fp, #-24]
158: e3a01001 mov r1, #1 ; 0x1
15c: ebfffffe bl 0 <unregister_chrdev_region>
160: e3e0000b mvn r0, #11 ; 0xb
164: eaffffea b 114 <init_module+0x9c>
...
180: 00000008 .word 0x00000008
00000184 <second_release>:
184: e1a0c00d mov ip, sp
188: e92dd800 push {fp, ip, lr, pc}
18c: e24cb004 sub fp, ip, #4 ; 0x4
190: e59f3010 ldr r3, [pc, #16] ; 1a8 <second_release+0x24>
194: e5930000 ldr r0, [r3]
198: e2800040 add r0, r0, #64 ; 0x40
19c: ebfffffe bl 0 <del_timer>
1a0: e3a00000 mov r0, #0 ; 0x0
1a4: e89da800 ldm sp, {fp, sp, pc}
1a8: 00000000 .word 0x00000000
000001ac <second_open>:
1ac: e1a0c00d mov ip, sp
1b0: e92dd830 push {r4, r5, fp, ip, lr, pc}
1b4: e24cb004 sub fp, ip, #4 ; 0x4
1b8: e59f5068 ldr r5, [pc, #104] ; 228 <second_open+0x7c>
1bc: e5950000 ldr r0, [r5]
1c0: e2800040 add r0, r0, #64 ; 0x40
1c4: ebfffffe bl 0 <init_timer>
1c8: e5951000 ldr r1, [r5]
1cc: e59f3058 ldr r3, [pc, #88] ; 22c <second_open+0x80>
1d0: e59f2058 ldr r2, [pc, #88] ; 230 <second_open+0x84>
1d4: e581304c str r3, [r1, #76]
1d8: e5923000 ldr r3, [r2]
1dc: e5951000 ldr r1, [r5]
1e0: e28330c8 add r3, r3, #200 ; 0xc8
1e4: e5813048 str r3, [r1, #72]
1e8: e5950000 ldr r0, [r5]
1ec: e5904040 ldr r4, [r0, #64]
1f0: e3540000 cmp r4, #0 ; 0x0
1f4: 1a000006 bne 214 <second_open+0x68>
1f8: e5901048 ldr r1, [r0, #72]
1fc: e2800040 add r0, r0, #64 ; 0x40
200: ebfffffe bl 0 <__mod_timer>
204: e5953000 ldr r3, [r5]
208: e1a00004 mov r0, r4
20c: e583403c str r4, [r3, #60]
210: e89da830 ldm sp, {r4, r5, fp, sp, pc}
214: e3a03000 mov r3, #0 ; 0x0
218: e5833000 str r3, [r3]
21c: e3a03000 mov r3, #0 ; 0x0
220: e5833000 str r3, [r3]
224: eafffffa b 214 <second_open+0x68>
...
00000234 <second_timer_handler>:
234: e1a0c00d mov ip, sp
238: e92dd830 push {r4, r5, fp, ip, lr, pc}
23c: e24cb004 sub fp, ip, #4 ; 0x4
240: e59f3054 ldr r3, [pc, #84] ; 29c <second_timer_handler+0x68>
244: e59f4054 ldr r4, [pc, #84] ; 2a0 <second_timer_handler+0x6c>
248: e5932000 ldr r2, [r3]
24c: e59f5050 ldr r5, [pc, #80] ; 2a4 <second_timer_handler+0x70>
250: e3a03009 mov r3, #9 ; 0x9
254: e5823000 str r3, [r2]
258: e5940000 ldr r0, [r4]
25c: e5951000 ldr r1, [r5]
260: e2800040 add r0, r0, #64 ; 0x40
264: e28110c8 add r1, r1, #200 ; 0xc8
268: ebfffffe bl 0 <mod_timer>
26c: e5942000 ldr r2, [r4]
270: e10f1000 mrs r1, CPSR
274: e3810080 orr r0, r1, #128 ; 0x80
278: e121f000 msr CPSR_c, r0
27c: e592303c ldr r3, [r2, #60]
280: e2833001 add r3, r3, #1 ; 0x1
284: e582303c str r3, [r2, #60]
288: e121f001 msr CPSR_c, r1
28c: e59f0014 ldr r0, [pc, #20] ; 2a8 <second_timer_handler+0x74>
290: e5951000 ldr r1, [r5]
294: ebfffffe bl 0 <printk>
298: e89da830 ldm sp, {r4, r5, fp, sp, pc}
偏离254,即可找到对应函数的对应行导致的kernel panic