免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 8512 | 回复: 13
打印 上一主题 下一主题

使用fiq产生data abort问题,大侠帮分析下吧 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-12-24 14:04 |只看该作者 |倒序浏览
我在ARMlinux2.6.14下使用开启了fiq功能,一般情况下工作正常,运行过程中,当另外一个应用模块加载时,老是出现data abort现象,兄弟刚学习linux不久,有点摸不着头脑,兄弟们帮忙分析下吧,错误信息如下:
open TW2835                                                                     
DvrExe: start audio encoder                                                     
DvrExe: start audio input                                                      
DvrExe: start video encoder                                                     
usb 1-2: new full speed USB device using hisilicon-ohci and address 3           
DvrExe: start video input                                                      
hub 1-2:1.0: USB hub found                                                      
hub 1-2:1.0: 4 ports detected                                                   
  Vendor: USB TO I  Model: DE/SATA Device    Rev: 0009                          
  Type:   Direct-Access                      ANSI SCSI revision: 00            
Attached scsi disk sda at scsi0, channel 0, id 0, lun 0                        
Bad mode in data abort handler detected: mode FIQ_32                           
Internal error: Oops - bad mode: 0 [#1]                                         
Modules linked in: xx_tw2835 xx_perspm xx_ssp xx_sio xx3510_vs xx_irdadrv misc_o
CPU: 0                                                                          
PC is at asm_do_fiq+0x24/0x58                                                   
LR is at 0xc1c05080                                                            
pc : [<c0027f60>]    lr : [<c1c05080>]    Not tainted                           
sp : c0377ecc  ip : ffffffff  fp : c0377f8c                                    
r10: c036cbc0  r9 : 00000000  r8 : c0021fa4                                    
r7 : 00000004  r6 : c1c05148  r5 : c1c05080  r4 : c1c00188                     
r3 : bf00b128  r2 : c1c05174  r1 : 00000001  r0 : c0226a3c                     
Flags: NzCv  IRQs off  FIQs off  Mode FIQ_32  Segment user                     
Control: 5317F  Table: 60380000  DAC: 00000015                                 
Process init (pid: 1, stack limit = 0xc0376194)                                 
Stack: (0xc0377ecc to 0xc0378000)                                               
7ec0:                            c0226a3c 00000001 c1c05174 bf00b128 c1c00188   
7ee0: c1c05080 c1c05148 00000004 c0021fa4 00000000 c036cbc0 c0377f8c ffffffff   
7f00: c0377ecc c1c05080 c0027f60 a00000d1 ffffffff c0377f20 c02200d0 c004676c   
7f20: 00000000 c0376000 c036cc80 4b87ad6e 00000001 becf7dec ffffffff 00000000   
7f40: c036cbc0 c00394b8 00000000 00000000 00000000 c036cbc0 c00394b8 c036fe9c   
7f60: c036fe9c ffffffea 00000000 00000000 00000072 c0021fa4 c0376000 40091714   
7f80: c0377fa4 c0377f90 c00411e4 c00404d8 00000000 becf7dec 00000000 c0377fa8   
7fa0: c0021e20 c00411bc becf7dec c00298c0 ffffffff becf7dec 00000000 00000000   
7fc0: becf7dec 00000000 00000000 becf7f34 00000001 00000000 40091714 0000d334   
7fe0: 40091a28 becf7de4 00033ef8 40080da4 60000010 ffffffff ffffffff ffffffff   
Backtrace:                                                                     
[<c00404c8>] (do_wait+0x0/0xc50) from [<c00411e4>] (sys_wait4+0x38/0x44)        
[<c00411ac>] (sys_wait4+0x0/0x44) from [<c0021e20>] (ret_fast_syscall+0x0/0x2c)
r4 = BECF7DEC                                                                  
Code: e5933000 e3530000 e59f0030 0a000003 (e593200                           
<0>Kernel panic - not syncing: Attempted to kill init!

还有一个错误信息
usb 1-2: new full speed USB device using hisilicon-ohci and address 3           
hub 1-2:1.0: USB hub found                                                      
hub 1-2:1.0: 4 ports detected                                                   
  Vendor: USB TO I  Model: DE/SATA Device    Rev: 0009                          
  Type:   Direct-Access                      ANSI SCSI revision: 00            
Attached scsi disk sda at scsi0, channel 0, id 0, lun 0                        
Bad mode in data abort handler detected: mode FIQ_32                           
Internal error: Oops - bad mode: 0 [#1]                                         
Modules linked in: xx_tw2835 xx_perspm xx_ssp xx_sio xx3510_vs xx_irdadrv misc_o
CPU: 0                                                                          
PC is at asm_do_fiq+0x24/0x58                                                   
LR is at 0x710                                                                  
pc : [<c0027f60>]    lr : [<00000710>]    Not tainted                           
sp : c0377de8  ip : 00000200  fp : c0377e44                                    
r10: c02ca3c0  r9 : c0376000  r8 : 0000000e                                    
r7 : 00000000  r6 : c0377eb8  r5 : 00000001  r4 : c0291310                     
r3 : bf00b164  r2 : 00000003  r1 : c1bdbe7c  r0 : c0226a3c                     
Flags: NzCv  IRQs off  FIQs off  Mode FIQ_32  Segment user                     
Control: 5317F  Table: 60380000  DAC: 00000015                                 
Process init (pid: 1, stack limit = 0xc0376194)                                 
Stack: (0xc0377de8 to 0xc0378000)                                               
7de0:                   c0226a3c c1bdbe7c 00000003 bf00b164 c0291310 00000001   
7e00: c0377eb8 00000000 0000000e c0376000 c02ca3c0 c0377e44 00000200 c0377de8   
7e20: 00000710 c0027f60 a00000d1 ffffffff c1cc2a60 00000000 c0377e68 c0377e48   
7e40: c0022bbc c019c5a0 c02ca698 0000000e c0377eb8 c025dd60 c0377eb8 c0377e84   
7e60: c0377e6c c0022e4c c0022b78 0000000e c02ca698 00000001 c0377eb4 c0377e88   
7e80: c0022efc c0022dec c0377ea0 2cf7baa0 ffffffff fc040000 00000001 00000002   
7ea0: 00000001 c036cbc0 c0377f10 c0377eb8 c00219f8 c0022eb4 c025c000 00000001   
7ec0: c0376000 00000001 fffffe00 c025c000 c036cc80 00000004 c0021fa4 00000000   
7ee0: c036cbc0 c0377f10 c0377f00 c0377f00 c02207b4 c02207b8 80000013 ffffffff   
7f00: c1c000c0 c0377f8c c0377f14 c0040554 c02207ac c0377f20 c02200d0 c004676c   
7f20: 00000000 c0376000 c036cc80 4b87ad6e 00000001 bedf1dec ffffffff 00000000   
7f40: c036cbc0 c00394b8 00000000 00000000 00000000 c036cbc0 c00394b8 c036fe9c   
7f60: c036fe9c ffffffea 00000000 00000000 00000072 c0021fa4 c0376000 40091714   
7f80: c0377fa4 c0377f90 c00411e4 c00404d8 00000000 bedf1dec 00000000 c0377fa8   
7fa0: c0021e20 c00411bc bedf1dec c00298c0 ffffffff bedf1dec 00000000 00000000   
7fc0: bedf1dec 00000000 00000000 bedf1f34 00000001 00000000 40091714 0000d334   
7fe0: 40091a28 bedf1de4 00033ef8 40080da4 60000010 ffffffff ffffffff ffffffff   
Backtrace:                                                                     
[<c019c590>] (i2c_hi3510_handler+0x0/0x834) from [<c0022bbc>] (__do_irq+0x54/0x)
r5 = 00000000  r4 = C1CC2A60                                                   
[<c0022b68>] (__do_irq+0x0/0xa4) from [<c0022e4c>] (do_level_IRQ+0x70/0xc     
r8 = C0377EB8  r7 = C025DD60  r6 = C0377EB8  r5 = 0000000E                     
r4 = C02CA698                                                                  
[<c0022ddc>] (do_level_IRQ+0x0/0xc from [<c0022efc>] (asm_do_IRQ+0x58/0x15c)  
r6 = 00000001  r5 = C02CA698  r4 = 0000000E                                    
[<c0022ea4>] (asm_do_IRQ+0x0/0x15c) from [<c00219f8>] (__irq_svc+0x38/0x8c)     
[<c022079c>] (_read_lock+0x0/0x24) from [<c0040554>] (do_wait+0x8c/0xc50)      
r5 = C1C000C0                                                                  
[<c00404c8>] (do_wait+0x0/0xc50) from [<c00411e4>] (sys_wait4+0x38/0x44)        
[<c00411ac>] (sys_wait4+0x0/0x44) from [<c0021e20>] (ret_fast_syscall+0x0/0x2c)
r4 = BEDF1DEC                                                                  
Code: e5933000 e3530000 e59f0030 0a000003 (e593200                           
<0>Kernel panic - not syncing: Aiee, killing interrupt handler!

论坛徽章:
0
2 [报告]
发表于 2009-12-24 22:38 |只看该作者
没人回奥,不知道是不是我提供的信息太少了,还是发错地方了,应该算是内核源码的吧?!

论坛徽章:
0
3 [报告]
发表于 2009-12-25 15:05 |只看该作者
把你的asm_do_fiq贴出来

论坛徽章:
0
4 [报告]
发表于 2009-12-25 16:32 |只看该作者
谢谢楼上的回复,这部分代码如下:

static void __attribute__ ((naked)) asm_do_fiq(void)
{
    //int ret;
    //struct pt_regs regs;

    asm __volatile__ (  
        "mov     ip, sp ;"  
        "stmdb  sp!, {r0-r8, r10-r12,  lr};"  
        "stmdb  sp!, {r9};"  
        "sub     fp, ip, #256 ;"  
        :  
        :  
        :"r9"  
        );
    if (current_fiq && current_fiq->fiq_op) {
        current_fiq->fiq_op(current_fiq->dev_id, 0);
    } else {
        printk(KERN_ERR "no fiq handler is found\n");
        dump_stack();
    }  
    asm __volatile__ (   
        "ldmia  sp!, {r9};"  
        "ldmia  sp!, {r0-r8, r10-r12, lr};"  
        "subs   pc, lr, #4;"  
    );
}

论坛徽章:
0
5 [报告]
发表于 2009-12-26 00:25 |只看该作者
1. 从现象看 Bad mode in data abort handler detected: mode FIQ_32
是在FIQ处理函数里访问了非法地址导致Data abot异常。arm里的Data abort异常优先级高于FIQ,产生了异常嵌套。
所以直接从fiq_mode转到dabt_mode。cpsr 处理器模式位这时的值是两种模式同时存在。
代码上执行到
__dabt_invalid:
        inv_entry BAD_DATA
        b        common_invalid

而common_invalid最终调用了bad_mode
common_invalid:
        zero_fp

        ldmia        r0, {r4 - r6}
        add        r0, sp, #S_PC                @ here for interlock avoidance
        mov        r7, #-1                        @  ""   ""    ""        ""
        str        r4, [sp]                @ save preserved r0
        stmia        r0, {r5 - r7}                @ lr_<exception>,
                                        @ cpsr_<exception>, "old_r0"

        mov        r0, sp
        and        r2, r6, #0x1f
        b        bad_mode

bad_mode函数里最后执行了panic
asmlinkage void bad_mode(struct pt_regs *regs, int reason, int proc_mode)
{
        console_verbose();

        printk(KERN_CRIT "Bad mode in %s handler detected: mode %s\n",
                handler[reason], processor_modes[proc_mode]);

        die("Oops - bad mode", regs, 0);
        local_irq_disable();
        panic("bad mode");
}

2.从代码看
先检查一下current_fiq 和 current_fiq->fiq_op 有没有问题, 特别是current_fiq->fiq_op,因为你代码里加了判断
if (current_fiq && current_fiq->fiq_op) {
        current_fiq->fiq_op(current_fiq->dev_id, 0);
但这两个指针不为NULL并不代表这两个指针指向的地址有效。

如果确认current_fiq 和 current_fiq->fiq_op 没有问题
在检查一下你的代码怎样从FIQ的地址(0x0000001c或0xFFFF001C)跳到asm_do_fiq里的,贴出来看看

论坛徽章:
0
6 [报告]
发表于 2009-12-26 10:23 |只看该作者
谢谢readkernel。
我的代码一般情况下是工作正常的,只有在以特定条件下才出问题,这是很重要的一点,而且从错误地址来看是在asm_do_fiq+0x24/0x58,这里感觉因该是已经进入了current_fiq->fiq_op(current_fiq->dev_id, 0);函数,个人刚学linux不久,不太知道如何定位到具体的指令上。

论坛徽章:
0
7 [报告]
发表于 2009-12-26 13:51 |只看该作者
有一点必须明确:
arm的R13是bank register,arm的七种处理器模式有各自的R13(user模式和system模式共用一个,总共六个不同的R13),也就是arm汇编默认的SP(堆栈指针),就是说一旦产生了模式切换(IRQ,FIQ,异常等), 接着的代码就使用模式对应的SP.

linux2.6.14源代码中对arm fiq几乎没有处理,因此所有用到FIQ的代码都必须自己实现.
从你的代码看,你用到了FIQ的SP(R13_fiq),不知道你在系统初始化的时候有没有对FIQ的SP初始化,如果没有,则肯定要出问题的.

arm\kernel\setup.c中对用到的IRQ, ABT, UND模式的SP都作了初始化,但FIQ没有

struct stack {
        u32 irq[3];
        u32 abt[3];
        u32 und[3];
} ____cacheline_aligned;

void cpu_init(void)
{
        unsigned int cpu = smp_processor_id();
        struct stack *stk = &stacks[cpu];

        if (cpu >= NR_CPUS) {
                printk(KERN_CRIT "CPU%u: bad primary CPU number\n", cpu);
                BUG();
        }

        if (system_state == SYSTEM_BOOTING)
                dump_cpu_info(cpu);

        /*
         * setup stacks for re-entrant exception handlers
         */
        __asm__ (
        "msr        cpsr_c, %1\n\t"           //切换到IRQ_MODE
        "add        sp, %0, %2\n\t"          //设置r13_irq,此时sp是r13_irq
        "msr        cpsr_c, %3\n\t"           //切换到ABT_MODE
        "add        sp, %0, %4\n\t"          //设置r13_abt,此时sp是r13_abt
        "msr        cpsr_c, %5\n\t"           //切换到UND_MODE
        "add        sp, %0, %6\n\t"          //设置r13_und,此时sp是r13_und
        "msr        cpsr_c, %7"                 //切换回SVC_MODE
            :
            : "r" (stk),
              "I" (PSR_F_BIT | PSR_I_BIT | IRQ_MODE),
              "I" (offsetof(struct stack, irq[0])),
              "I" (PSR_F_BIT | PSR_I_BIT | ABT_MODE),
              "I" (offsetof(struct stack, abt[0])),
              "I" (PSR_F_BIT | PSR_I_BIT | UND_MODE),
              "I" (offsetof(struct stack, und[0])),
              "I" (PSR_F_BIT | PSR_I_BIT | SVC_MODE)
            : "r14");
}

你应该在此处对FIQ做相应的SP初始化
可以看到,IRQ, ABT, UND模式的堆栈大小都只有3个int,
你可能会问,进入这三个模式后, 怎么保存大量的寄存器?
呵呵,进入这三种模式后,linux会把模式切换到SVC_MODE,使用的是SVC_MODE的堆栈.

vector_\name:
        .if \correction
        sub        lr, lr, #\correction
        .endif

        @
        @ Save r0, lr_<exception> (parent PC) and spsr_<exception>
        @ (parent CPSR)
        @
        stmia        sp, {r0, lr}                @ save r0, lr  //R13_<mode>保存两个int
        mrs        lr, spsr
        str        lr, [sp, #8]                @ save spsr    //R13_<mode>再保存一个int

        @
        @ Prepare for SVC32 mode.  IRQs remain disabled.
        @
        mrs        r0, cpsr
        eor        r0, r0, #(\mode ^ SVC_MODE)            //切换到SVC,之后的堆栈操作都用R13_svc,sp都是R13_svc的值
        msr        spsr_cxsf, r0

        @
        @ the branch table must immediately follow this code
        @
        and        lr, lr, #0x0f
        mov        r0, sp
        ldr        lr, [pc, lr, lsl #2]
        movs        pc, lr                        @ branch to handler in SVC mode
        .endm

具体FIQ的堆栈怎么处理就看你怎么实现了.

[ 本帖最后由 readkernel 于 2009-12-26 14:08 编辑 ]

论坛徽章:
0
8 [报告]
发表于 2009-12-26 16:58 |只看该作者
readkernel 兄弟,你在认真的回我的问题,谢谢了。希望以后能多多交流!
上面你说的这些我有注意到,最初我也为如何建立fiq的堆栈发了不少的时间,由于刚接触linux,不太熟悉。以前都是在arm7上开发,没有什么mmu之类的东西!
堆栈问题我会再仔细的检查一下。
另外我刚开始在cpu_init里面建立fiq的堆栈不成功,不知道为什么,是不是太早了。有了解的兄弟可以指点下。

论坛徽章:
0
9 [报告]
发表于 2009-12-26 18:15 |只看该作者
俺也是顺着你的问题到内核去挖点学习一下,以前做过arm9 wince的开发,最近对linux来电。

多多交流

fiq栈开了多大?
        "stmdb  sp!, {r0-r8, r10-r12,  lr};"  
        "stmdb  sp!, {r9};"  
看你这里用了 14*4,里面还有C函数嵌套,C的嵌套深度决定栈的大小。

论坛徽章:
0
10 [报告]
发表于 2009-12-26 23:40 |只看该作者
1024*4字节,应该够用了,中断处理程序是fiq末实现执行的,不过我没有在中断处理中做太多的事情,把实实时性的东西处理完就退出去了,而且我的代码中每次中段对栈的使用是固定的。
因为问题不是一运行就出问题,而是在USB驱动加载后探测SD卡时才会出现,而且如果我先加载USB驱动,然后在运行使用fiq的程序,也不会出问题,所以比较棘手,我想使用一些方法进行源码级的调试,但是没用过,不知兄第是否有些经验?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP