EABI和OABI

轉自http://blog.csdn.net/ce123/article/details/6925375

引言

         初學嵌入式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,這兩個表是一個內核的跳轉表,存放的是系統調用的指針,這些指針就是系統調用函數的指針,如(sys_open).系統調用是根據一個調用號(通常就是表的索引)找到實際該調用內核哪個函數,然後運行該函數完成的
         首先,對於old ABI,內核給出的處理是給它建立一個單獨的system call table,叫sys_oabi_call_table,這樣,兼容方式下就會有兩個system call table, 以old ABI方式的系統調用會執行sys_oabi_call_table表中的系統調用函數,EABI方式的系統調用會用sys_call_table中的函數指針。
  配置無外乎以下4中
  第一, 兩個宏都配置。行爲就是上面說的那樣。
  第二 ,只配置CONFIG_OABI_COMPAT。 那麼以old ABI方式調用的會用sys_oabi_call_table,以EABI方式調用的用sys_call_table,和1實質相同,只是情況1更加明確。
  第三, 只配置CONFIG_AEABI 。系統中不存在 sys_oabi_call_table, 對old ABI方式調用不兼容。只能 以EABI方式調用,用sys_call_table。
  第四 ,兩個都沒有配置。 系統默認會只允許old ABI方式,但是不存在sys_oabi_call_table,最終會通過sys_call_table 完成函數調用。
因爲CONFIG_OABI_COMPAT對CONFIG_AEABI有依賴關係所以不能只選擇CONFIG_OABI_COMPAT。

什麼是ABI

ABI,application binary interface (ABI),應用程序二進制接口。既然是 接口,那就是某兩種東西之間的溝通橋樑,此處有這些種情況:
A.應用程序 <-> 操作系統;
B.應用程序 <-> (應用程序所用到的)庫
C.應用程序各個組件之間

ABI類似於API的作用是使得程序的代碼間的兼容,ABI目的是使得程序的二進制(級別)的兼容。


         ABI通常是處理器體系結構的一部分,它與平臺是緊密相連的。 我們可以把ABI理解爲一套規則,這套規則一般包括定義了以下內容:
1.應用程序如何發出系統調用來trap到內核態。 
2.如何使用機器的寄存器。比如,RISC處理器的ABI就要規定用那個通用寄存器來作stack pointer和frame pointer。 
3.規定如何進行procedure call。

什麼是OABI 和 EABI

          OABI中的O,表示“Old”,“Lagacy”,舊的,過時的,OABI就是舊的/老的ABI。
          EABI中的E,表示“Embedded”,是一種新的ABI。Embedded application binary interface, 即嵌入式應用二進制接口,是描述可連接目標代碼,庫目標代碼,可執行文件影像,如何連接,執行和調試,以及目標代碼生成過程,和C/ C++語言接口的規範,是編譯連接工具的基礎規範,也是研究它們工作原理的基礎,可惜ARM的EABI迄今爲止沒有完全訂好。作爲EABI的組成部分有過程調用規範,可執行文件格式規範,c/c++ ABI規範和調試格式規範。EABI,說的是這樣的一種新的系統調用方式 。
          EABI有時候也叫做GNU EABI。
          OABI和EABI都是專門針對ARM的CPU來說的。


EABI的好處

  1. 支持軟件浮點和硬件實現浮點功能混用
  2. 系統調用的效率更高
  3. 後今後的工具更兼容
  4. 軟件浮點的情況下,EABI的軟件浮點的效率要比OABI高很多。

OABI和EABI的區別

兩種ABI在如下方面有區別:
  1. 調用規則(包括參數如何傳遞及如何獲得返回值)
  2. 系統調用的數目以及應用程序應該如何去做系統調用
  3. 目標文件的二進制格式,程序庫等
  4. 結構體中的 填充(padding/packing)和對齊。
注意對於同一套系統,比如uboot,kernel,rootfs等等,編譯器最好是用同一版本的,要麼是oabi要麼是eabi,否則不同版本的不同的東西混用,很容易出問題的。
發佈了38 篇原創文章 · 獲贊 35 · 訪問量 23萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章