本文是基于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 address 00000000
[ 4000.935000] pgd = c3d9c000
[ 4000.940000] [00000000] *pgd=33f30031, *pte=00000000, *ppte=00000000
[ 4000.945000] Internal error: Oops: 817 [#1]
[ 4000.945000] Modules linked in: timerdriver leddriver rt3070sta s3c2440_adc p7
50_driver_1
[ 4000.945000] CPU: 0 Not tainted (2.6.28.6 #69)
[ 4000.945000] PC is at second_timer_handler+0x20/0x78 [timerdriver]
[ 4000.945000] LR is at run_timer_softirq+0x17c/0x1f4
[ 4000.945000] pc : [<bf0c0254>] lr : [<c006b7f4>] psr: 20000013
[ 4000.945000] sp : c3b53dd8 ip : c3b53df0 fp : c3b53dec
[ 4000.945000] r10: c0485c30 r9 : 0000000a r8 : c3b52000
[ 4000.945000] r7 : bf0c0234 r6 : 00000100 r5 : c0485c30 r4 : bf0c0c24
[ 4000.945000] r3 : 00000009 r2 : 00000000 r1 : c3b53df0 r0 : 00000000
[ 4000.945000] Flags: nzCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment user
[ 4000.945000] Control: c000717f Table: 33d9c000 DAC: 00000015
[ 4000.945000] Process leds_test (pid: 1150, stack limit = 0xc3b52268)
[ 4000.945000] Stack: (0xc3b53dd8 to 0xc3b54000)
[ 4000.945000] 3dc0: c04bc
a80 c3b53df0
[ 4000.945000] 3de0: c3b53e1c c3b53df0 c006b7f4 bf0c0244 c3b53df0 c3b53df0 00000
001 00000004
[ 4000.945000] 3e00: 00000100 c04bc934 c3b52000 c04bc934 c3b53e54 c3b53e20 c0066
c4c c006b688
[ 4000.945000] 3e20: c0483db4 0000001e c3cd97c0 0000001e c04ce294 00000000 c3cd9
7c0 c00456ac
[ 4000.945000] 3e40: c3b52000 00900036 c3b53e64 c3b53e58 c0066fcc c0066be0 c3b53
e84 c3b53e68
[ 4000.945000] 3e60: c0044068 c0066f98 c04abbb8 ffffffff f4000000 00004000 c3b53
edc c3b53e88
[ 4000.945000] 3e80: c0044a64 c0044010 fb000010 fffffffe fffffbff fffffb7f 00000
000 00000001
[ 4000.945000] 3ea0: 00000001 c3cd97c0 c00456ac c3b52000 00900036 c3b53edc 00000
00a c3b53ed0
[ 4000.945000] 3ec0: 60000013 c005175c 60000013 ffffffff c3b53eec c3b53ee0 bf0ba
05c c0051724
[ 4000.945000] 3ee0: c3b53f04 c3b53ef0 c00be394 bf0ba024 c3cd97c0 00000000 c3b53
f7c c3b53f08
[ 4000.945000] 3f00: c00be764 c00be32c 000085b8 0000001e c04ce294 00000000 00008
5b8 40000010
[ 4000.945000] 3f20: 00000000 ef900003 c3b53f44 c3b53f38 c0066fcc c0066be0 c3b53
f64 c3cd91c0
[ 4000.945000] 3f40: bee77dc0 c3b53f78 c3b53f74 c3b53f58 c00b2b10 00000003 00000
000 00000001
[ 4000.945000] 3f60: c3cd97c0 c00456ac c3b52000 00900036 c3b53fa4 c3b53f80 c00be
8d4 c00be3d4
[ 4000.945000] 3f80: 00000001 00000000 bee77e14 0000856c 00000001 00000036 00000
000 c3b53fa8
[ 4000.945000] 3fa0: c0044e80 c00be8a4 bee77e14 0000856c 00000003 00000001 00000
000 00000000
[ 4000.945000] 3fc0: bee77e14 0000856c 00000001 000085b8 00008490 00000000 4023f
64c bee77de8
[ 4000.945000] 3fe0: 000107b4 bee77dc0 00008558 401e6644 60000010 00000003 00000
000 00000000
[ 4000.945000] Backtrace:
[ 4000.945000] [<bf0c0234>] (second_timer_handler+0x0/0x78 [timerdriver]) from [
<c006b7f4>] (run_timer_softirq+0x17c/0x1f4)
[ 4000.945000] r5:c3b53df0 r4:c04bca80
[ 4000.945000] [<c006b678>] (run_timer_softirq+0x0/0x1f4) from [<c0066c4c>] (__d
o_softirq+0x7c/0x128)
[ 4000.945000] [<c0066bd0>] (__do_softirq+0x0/0x128) from [<c0066fcc>] (irq_exit
+0x44/0x4c)
[ 4000.945000] [<c0066f88>] (irq_exit+0x0/0x4c) from [<c0044068>] (__exception_t
ext_start+0x68/0xc4)
[ 4000.945000] [<c0044000>] (__exception_text_start+0x0/0xc4) from [<c0044a64>]
(__irq_svc+0x24/0xa0)
[ 4000.945000] Exception stack(0xc3b53e88 to 0xc3b53ed0)
[ 4000.945000] 3e80: fb000010 fffffffe fffffbff fffffb7f 00000
000 00000001
[ 4000.945000] 3ea0: 00000001 c3cd97c0 c00456ac c3b52000 00900036 c3b53edc 00000
00a c3b53ed0
[ 4000.945000] 3ec0: 60000013 c005175c 60000013 ffffffff
[ 4000.945000] r6:00004000 r5:f4000000 r4:ffffffff
[ 4000.945000] [<c0051714>] (s3c2410_gpio_setpin+0x0/0x4c) from [<bf0ba05c>] (le
ds_ioctl+0x48/0x4c [leddriver])
[ 4000.945000] [<bf0ba014>] (leds_ioctl+0x0/0x4c [leddriver]) from [<c00be394>]
(vfs_ioctl+0x78/0x80)
[ 4000.945000] [<c00be31c>] (vfs_ioctl+0x0/0x80) from [<c00be764>] (do_vfs_ioctl
+0x3a0/0x4d0)
[ 4000.945000] r5:00000000 r4:c3cd97c0
[ 4000.945000] [<c00be3c4>] (do_vfs_ioctl+0x0/0x4d0) from [<c00be8d4>] (sys_ioct
l+0x40/0x68)
[ 4000.945000] [<c00be894>] (sys_ioctl+0x0/0x68) from [<c0044e80>] (ret_fast_sys
call+0x0/0x2c)
[ 4000.945000] r7:00000036 r6:00000001 r5:0000856c r4:bee77e14
[ 4000.945000] Code: e59f4054 e5932000 e59f5050 e3a03009 (e5823000)
[ 4000.945000] s3c2410fb: blank(mode=0, info=c3875800)
[ 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