Linux内核模块中的数组引起的问题.

调试一个程序的时候遇到这样的问题:


kernel BUG at arch/arm/mm/dma-mapping.c:412!
Unable to handle kernel NULL pointer dereference at virtual address 00000000
pgd = c0004000
[00000000] *pgd=00000000
Internal error: Oops: 817 [#1] PREEMPT
last sysfs file: /sys/class/mtd/mtd1ro/dev
Modules linked in: g_zero ehci_hcd ehci_monitor
CPU: 0    Not tainted  (2.6.35.4 #27)
PC is at __bug+0x20/0x2c
LR is at release_console_sem+0x1d8/0x260
pc : []    lr : []    psr: 60000093
sp : c02d3e38  ip : c02d3d68  fp : c02d3e44
r10: 00000038  r9 : c0310928  r8 : 00000001
r7 : 00000008  r6 : 00000002  r5 : 00004000  r4 : bf01a060
r3 : 00000000  r2 : 00010002  r1 : 00003ca0  r0 : 00000033
Flags: nZCv  IRQs off  FIQs on  Mode SVC_32  ISA ARM  Segment kernel
Control: 0005317f  Table: 029dc000  DAC: 00000017
Process swapper (pid: 0, stack limit = 0xc02d2270)
Stack: (0xc02d3e38 to 0xc02d4000)
3e20:                                                       c02d3e64 c02d3e48
3e40: c0026738 c0024634 c02d3e84 ff01a060 c28a57e0 c0310960 c02d3e84 c02d3e68
3e60: c020a894 c00266e4 00000070 c0310960 c28a57e0 c0310928 c02d3eac c02d3e88
3e80: c020b3e0 c020a7a4 c02d3ec4 00000000 c0310928 00000068 c0310928 00000001
3ea0: c02d3eec c02d3eb0 c020bb1c c020b038 00000010 00000010 0000000f 00000001
3ec0: c0063824 c352ebe0 00000000 00000000 00000015 00000001 c02d2000 0001bcf0
3ee0: c02d3f0c c02d3ef0 c005f828 c020b8d4 c02da0c4 c352ebe0 00000015 00000002
3f00: c02d3f2c c02d3f10 c0061b1c c005f80c c02d3f2c 00000015 00000000 c02e5bec
3f20: c02d3f44 c02d3f30 c0020074 c0061a54 ffffffff f0000000 c02d3fac c02d3f48
3f40: c0020b24 c0020010 c02d4f48 c02d7b30 00000000 60000013 c02d2000 c02d5bd4
3f60: c02e5bec c02d5bc8 0001bd24 41069265 0001bcf0 c02d3fac c02d3f90 c02d3f90
3f80: c002258c c0022560 60000013 ffffffff c02d5bc8 c02d2000 c02e5bb0 c001e018
3fa0: c02d3fc4 c02d3fb0 c02115cc c002253c c001e018 c0308e78 c02d3ff4 c02d3fc8
3fc0: c0008a70 c0211520 c000853c 00000000 00000000 c001e018 00000000 00053175
3fe0: c02e5c20 c001e41c 00000000 c02d3ff8 00008034 c00087e8 00000000 00000000
Backtrace: 
[] (__bug+0x0/0x2c) from [] (___dma_single_cpu_to_dev+0x64/0x9c)
[] (___dma_single_cpu_to_dev+0x0/0x9c) from [] (read_fifo+0x100/0x20c)
 r6:c0310960 r5:c28a57e0 r4:ff01a060
[] (read_fifo+0x0/0x20c) from [] (paser_irq_nep+0x3b8/0x400)
 r7:c0310928 r6:c28a57e0 r5:c0310960 r4:00000070

发现了出现该错误的条件:

1,

模块中定义数组类似

char buf[1024*128]


2,

使用insmod xxx.ko方式加载模块


3,使用了dma

查代码发现错误在语句:

BUG_ON(!virt_addr_valid(kaddr) || !virt_addr_valid(kaddr + size - 1));

然后

#define virt_addr_valid(kaddr) ((unsigned long)(kaddr) >= PAGE_OFFSET && (unsigned long)(kaddr) < (unsigned long)high_memory)


如果addr不在内核空间,((unsigned long)(kaddr) >= PAGE_OFFSET  为0 表达式为0,就会BUG


使用insmod 加载模块时,静态数组地址就在用户空间0xb0000000~0xc0000000

就会出错.


如果直接编译进内核

数组的地址在0xc0000000之后,就正常。

所以在模块中用到DMA,要么用kmalloc之类动态分配,要么把模块编译进内核。

你可能感兴趣的:(debug)