zoukankan      html  css  js  c++  java
  • EABI和OABI

    相信很多学习嵌入式linux的人都碰到过这样一个问题:

    初学linux的时候大家都用的工具链版本多是3.4.5或3.4.2,名字为arm-linux-gcc或arm-softfloat-linux-gnu-gcc,可突然有一天发现这几个版本的编译器无法编译最新的内核了,并且发现人们都换了工具链了(arm-none-linux-gnueabi-gcc),怎么办,换呗。于是也都换成了这个工具链,编译内核,制作跟文件系统,按部就班的做,和以前没什么区别,很多人甚至想这些操作我都做烂了,闭着眼睛都能完成,一切和以前也没什么区别。可是紧接着问题来了,当内核启动到最后阶段挂载文件系统是出现如下错误:

    kernel panic:attempted to kill init

    或者什么错误都不提示,只是永远进入不了终端。

    这是什么问题呢,答案是大家需要在内核配置的时候选择上如下内容:

    make menuconfig
            Kernel Features --->
                    [*] Use the ARM EABI to compile the kernel
                    [*] Allow old ABI binaries to run with this kernel (EXPERIMENTAL)

    选上这两项重新编译内核,发现上面提到的问题就解决了,为什么呢,这两个选项是什么东西呢。在这里得提到几个概念:

    ABI:application binary interface
            OABI:old application binary interface
            EABI:extended application binary interface

    但上面两项选中后在内核的配置文件.config中CONFIG_AEABI和CONFIG_OABI_COMPAT会被设置为“y”,CONFIG_AEABI表示现在内核为EABI,CONFIG_OABI_COMPAT表示兼容OABI。

    为什么这两个选项会影响到我们的系统启动呢。

    这两个选项可以选择任意一个也可以都选。这里涉及到两个结构sys_call_table和sys_oabi_call_table,这两个表是一个内核的跳转表,存放的是系统调用的指针。当CONFIG_AEABI和CONFIG_OABI_COMPAT都选中的时候,当应用程序使用OABI的是时候调用sys_oabi_call_table中的系统调用,应用程序使用EABI时使用sys_call_table中的系统调用。而如果只选CONFIG_AEABI则使用sys_call_table。两个都不选则使用sys_call_table。应为CONFIG_OABI_COMPAT对CONFIG_AEABI有依赖关系所以不能只选择CONFIG_OABI_COMPAT。

    可以参考如下代码

    arch/arm/kernel/entry-common.S
            #if defined(CONFIG_OABI_COMPAT)

            /*
                    * If we have CONFIG_OABI_COMPAT then we need to look at the swi
                    * value to determine if it is an EABI or an old ABI call.
                    */
            #ifdef CONFIG_ARM_THUMB
                    tst r8, #PSR_T_BIT
                    movne    r10, #0         @ no thumb OABI emulation
                    ldreq        r10, [lr, #-4]        @ get SWI instruction
            #else
                    ldr    r10, [lr, #-4]        @ get SWI instruction
                A710( and ip, r10, #0x0f000000        @ check for SWI )
                A710( teq ip, #0x0f000000 )
                A710( bne .Larm710bug )
            #endif
            #ifdef CONFIG_CPU_ENDIAN_BE8
                    rev    r10, r10        @ little endian instruction
            #endif
            #elif defined(CONFIG_AEABI)
                    /*
                    * Pure EABI user space always put syscall number into scno (r7).
                    */
                A710( ldr      ip, [lr, #-4]        @ get SWI instruction )
                A710( and    ip, ip, #0x0f000000        @ check for SWI )
                A710( teq      ip, #0x0f000000 )
                A710( bne    .Larm710bug )
            #elif defined(CONFIG_ARM_THUMB)
                    /* Legacy ABI only, possibly thumb mode. */
                    tst r8, #PSR_T_BIT        @ this is SPSR from save_user_regs
                    addne    scno, r7, #__NR_SYSCALL_BASE        @ put OS number in
                    ldreq    scno, [lr, #-4]
            #else
                    /* Legacy ABI only. */
                    ldr    scno, [lr, #-4] @ get SWI instruction
                A710( and    ip, scno, #0x0f000000        @ check for SWI )
                A710( teq    ip, #0x0f000000 )
                A710( bne    .Larm710bug )
            #endif
            #ifdef CONFIG_ALIGNMENT_TRAP
                    ldr    ip, __cr_alignment
                    ldr    ip, [ip]
                    mcr    p15, 0, ip, c1, c0        @ update control register
            #endif
                    enable_irq
                    get_thread_info tsk
                    adr tbl, sys_call_table        @ load syscall table pointer
                    ldr    ip, [tsk, #TI_FLAGS]        @ check for syscall tracing
            #if defined(CONFIG_OABI_COMPAT)
                    /*
                    * If the swi argument is zero, this is an EABI call and we do nothing.
                    *
                    * If this is an old ABI call, get the syscall number into scno and
                    * get the old ABI syscall table address.
                    */
                    bics r10, r10, #0xff000000
                    eorne    scno, r10, #__NR_OABI_SYSCALL_BASE
                    ldrne      tbl, =sys_oabi_call_table
            #elif !defined(CONFIG_AEABI)
                    bic    scno, scno, #0xff000000    @ mask off SWI op-code
                    eor    scno, scno, #__NR_SYSCALL_BASE @ check OS number
            #endif


    原文地址:http://www.embedu.org/Column/Column358.htm


  • 相关阅读:
    HDU 4379 水题,大水,但我WA了很多次,做了很久
    HDU 1712分组背包 考试复习安排
    所谓的二维背包Triangular Pastures POJ 1948
    ZOJ 1203 Swordfish Kruskal算法求最小生成树
    POJ 2576 Tug of War二维背包恰好装满.
    O(n*m)复杂度的多重背包coinsPOJ 1742
    拓扑排序POJ 1094
    页面右键下拉表
    gb2312 unicode转换工具
    INPUT读出URL里的变量名称
  • 原文地址:https://www.cnblogs.com/java20130726/p/3218579.html
Copyright © 2011-2022 走看看