起初,碰到这样的问题几乎一筹莫展,只能重新编译了好几次内核,时灵时不灵,很是痛苦。错误的症状是:
Kernel Bug,consistent.c,line 42之类的信息,然后告诉我错误是因为访问了0x00000000这个非法地址,打印出一堆寄存器的值
实在没办法,用google一搜,还真有人碰到过这样的问题而且贴出了解决办法,唉,看来以后碰到问题首先就得问google了。。。
解决办法如下(转载达人的文章):
这是在使用2.4系列内核代码的时候遇到的问题和解决办法,记录下来供大家借鉴。
s3c2410平台上,早期mizi发布的2.4.18或2.4.19以及kernel.org的2.4.2X系列linux内核源代码,在使用USB设备的时候会引发一个Kernel panic,报告形式为:
kernel BUG at consistent.c:42!
Unable to handle kernel NULL pointer dereference at virtual address 00000000
这是一个内存分配错误。是由于arch mach-s3c2410在内核中模仿了pci bus,usb ohci
driver通过这个pci bus来和内核交换数据,所以在驱动usb设备的时候,由于pcibuf
driver本身的问题,会在arch/arm/mach-s3c2410/pcibuf.c中的init_safe_buffers部分执行失败引发
Kernel panic。
这个问题也在sa1111中出现,参见:
http://lists.arm.linux.org.uk/pipermail/linux-arm-kernel/2002-August/011197.html
文中Trevor通过预分配一块缓冲区来解决这个问题。这在s3c2410上也同样有效。
方法如下:
在arch/arm/mach-s3c2410/pcibuf.c中增加preallocate_buffers函数:
static int preallocate_buffers(struct pci_pool *pool)
{
char buf[MAX_SAFE];
u32 dma[MAX_SAFE];
int i;
printk("Pre-allocating d buffers for pool 0xx\n",MAX_SAFE,pool);
for (i = 0;i < MAX_SAFE;i++)
buf[i] = pci_pool_alloc(pool,SLAB_ATOMIC,&(dma[i]));
for (i = 0;i < MAX_SAFE;i++)
pci_pool_free(pool,buf[i],dma[i]);
}
然后在init_safe_buffers函数中的
if (large_buffer_cache == 0)
return -1;
后面增加预处理:
preallocate_buffers(large_buffer_cache);
问题解决。
另外,这个错误在2.6系列中已经不存在。