遇到的问题和解决方法
1、ramdisk启动之后,必须先ls一下,才能open文件。
问题定位方法:gdb,显示栈。
问题定位:open函数会调用到内核中的kunmap函数,而kumap函数不能在中断上下文中调用(在kunmap函数中有BUG_ON( in_interrupt ( )) ;) ,而我们 f ilp_open正是在中断上下文中调用的,因此出错。
解决方法:启动内核线程,来open文件。
2、结构体的地址被莫名其妙地修改了。
问题定位方法:打印
问题定位:结构体的地址保存在一个局部变量中(在内核栈) ,当在内核中定义个大的局部变量时,就有可能把内核栈堆满,从而冲掉到栈上其它变量。
解决方法:将数组换成指针。
总结:内核栈有限,不要过分的去用,这是常识。
3、内核死在 synchronize_irq函数中。
问题定位方法:gdb,打印栈。
问题定位:synchronize_irq会被disalbe_irq调用,通常情况下会在驱动注册的中断处理函数中调用 disalbe_irq来使中断处理能嵌套。问题出在,在synchronize_irq中会判断
IRQD_IRQ_INPROGRESS标志,而IRQD_IRQ_INPROGRESS会在调用驱动注册的中断处理函数之前的中断处理流程中(handle_irq_event函数中)设置,因此造成死锁。
解决方法:把 disalbe_irq换成disable_irq_nosync。
总结:以后还是使用disable_irq_nosync比较靠谱。
4、timer中断
问题描述:想在内核中写一个 timer的驱动,中断通过setup_irq来建立,一打开 timer的中断,内核就死掉。
问题定位:代码逻辑上捋中断处理流程,发现在zynq平台,这个timer的中断处理和普通的 驱 动 中 断 处 理 不 相 同 。 其 中 断 处 理 必 须 在 arch/arm/include/asm/entry-macro-multi.S中加入,不能使用setup_irq函数来建立。当然不要忘记在init函数中,使能中断。
问题解决:在 arch/arm/include/asm/entry-macro-multi.S加入如下代码:
36 ____test_for_gt irq r0, r6, r5, lr
37 ____movne___r0, sp
38 ____adrne___lr, BSYM(1b)
39 ____bne_internal_t imer2_int
其中 test _for_gt irq为:
76 ____.macro test _for_gt irq, irqnr, irqstat, base, tmp
77 ____bic_\irqnr, \irqstat , #0x1c00
78 ____mov ____\tmp, #0
79 ____cmp_\irqnr, #27
80 ____moveq___\tmp, #1
81 ____streq___\irqstat , [\base, #GIC_CPU_EOI]
82 ____cmp_\tmp, #0
5、记住一点,现在的串口驱动都是使用的定时器轮寻收发数据,而非中断方式。
6、内核不能挂载文件系统
问题定位:内核启动到挂载文件系统之后就会死掉,通过实验发现可能是内核image过大加载时冲掉了ramdisk的空间,但是就是比平常的image大2M应该也没什么影响,后来查看System.map,发现虽然image的大小变化不大,但是一些变量的地址却变化很大,用到了ramdisk的空间。
解决方法:在uboot中讲ramdisk的起始地址后移。