移植libffi到SylixOS

1. 開發環境
宿主機:Windows 7
集成開發環境:Real-Evo IDE 3.2.5
虛擬機:Ubuntu 14.04

本篇僅介紹libffi庫的移植過程,包括資源的獲取,工程文件的修改以及編譯出錯處理。移植後的libffi支持ARM、MIPS、PowerPC和x86平臺,本文檔以x86平臺爲例進行移植,在完成本文檔的操作步驟後,只需要修改libffi工程所依賴的base工程,然後重新編譯上傳,即可在所支持的平臺上使用libffi庫。

2. libffi簡介

“FFI” 的全名是 Foreign Function Interface,通常指的是允許以一種語言編寫的代碼調用另一種語言的代碼。而 “libffi” 庫只提供了最底層的、與架構相關的、完整的“FFI”,因此在它之上必須有一層來負責管理兩種語言之間參數的格式轉換。
高級語言編譯器產生代碼時都會依據一系列的規則,這些規則十分必要,特別是對獨立編譯來說。其中之一是“調用約定” (Calling Convention),它包含了編譯器關於函數入口處的函數參數、函數返回值的一系列假設。它有時也被稱作“ABI”(Application Binary Interface)。調用約定(Calling Conventions)定義了程序中調用函數的方式,它決定了在函數調用的時候數據(比如說參數)在堆棧中的組織方式。
通常來說函數調用要用到的兩條基本的指令:“CALL”指令和“RET”指令。“CALL”指令將當前的指令指針(這個指針指向緊接在CALL指令後面的那條指令)壓入堆棧,然後執行一條無條件轉移指令轉移到新的代碼地址。“RET”是與“CALL”指令配合使用的指令,在絕大多數函數中它是最後一條指令。“RET”指令彈出返回地址(就是“CALL”指令壓入堆棧的地址)並將其加載到“EIP”寄存器中,然後從這個地址開始繼續執行。
3. 資源獲取
3.1 libffi源碼獲取
一般的,可以通過官方網站獲取要移植的第三方件的資源。libffi最新版本的下載地址爲https://github.com/libffi/libffi
本篇中使用的libffi版本爲libffi-2.99.9,下載後解壓文件如圖 3-1所示。
這裏寫圖片描述
圖 3-1 libffi解壓後部分文件
其中src目錄下主要包含要編譯的源文件以及支持的平臺文件。configure是配置文件,在Linux平臺下運行該文件可生成Makefile文件,執行make命令即可生成最終的庫文件。
libffi支持的平臺可見src目錄下包含的平臺相關目錄,支持平臺如圖 3-2所示。
這裏寫圖片描述
圖 3-2 libffi支持的平臺
移植到SylixOS後的libffi支持的平臺有ARM、MIPS、POWERPC和x86。
對於新版本的libffi,目錄結構有所不同,配置方法也有差異,在移植時需要結合具體libffi版本進行配置。
4. Linux平臺下配置
4.1 配置
編譯過程中使用的Linux環境爲Ubuntu發行版。將下載的壓縮包文件拷貝到Ubuntu環境中並解壓。由於下載的庫文件已經包含了configure配置文件,因此需要執行該命令生成makefile文件,操作如圖 4-1所示。
這裏寫圖片描述
圖 4-1執行配置文件
生成makefile文件如圖 4-2所示。
這裏寫圖片描述
圖 4-2生成makefile文件
由於只是爲了配置libffi庫,在執行完configure腳本後即完成了libffi的配置,然後保存libffi文件夾以便移植。
5. 新建libffi庫工程
5.1 導入libffi源碼
在Real-Evo IDE中創建libffi共享庫工程,刪去libffi工程中src目錄下的文件libffi.c,並導入libffi源碼文件。導入後的工程文件如圖 5-1所示。
這裏寫圖片描述
圖 5-1 導入libffi源碼文件到libffi庫工程
5.2 修改makefile
修改libffi工程屬性爲專家模式,操作如圖 5-2所示。
這裏寫圖片描述
圖 5-2修改工程屬性爲專家模式
修改libffi.mk文件,加入進行編譯的源碼文件,修改內容如圖 5-3所示。
這裏寫圖片描述
圖 5-3 修改libffi.mk添加源文件
修改libffi.mk文件,加入頭文件路徑,修改內容如圖 5-4所示。
這裏寫圖片描述
圖 5-4 修改libffi.mk添加頭文件路徑
其中PLATFORM定義在Makefile文件中,PLATFORM支持的平臺如圖 5-5所示。
這裏寫圖片描述
圖 5-5 PLATFORM支持的平臺
其中TOOLCHAIN_PREFIX是和所依賴的base工程相關的。在指定好所依賴的base工程之後,TOOLCHAIN_PREFIX的取值就已經確定。
5.3 編譯libffi工程
保存修改並編譯,出現如圖 5-6所示錯誤。
這裏寫圖片描述
圖 5-6 編譯報錯
打開ffitarget.h後可看到其內容是亂碼,所以導致出錯,刪除掉該頭文件之後重新編譯,即可編譯通過。
爲了支持PowerPC平臺,需要在libffi/src/libffi/include/ffi.h文件中添加內容如圖 5-7所示。
這裏寫圖片描述
圖 5-7 增加POWERPC宏
爲了支持MIPS平臺,需要在libffi/src/libffi/src/mips/ffi.c文件中做接口替換,原調用接口爲:

__builtin__clear_cache(clear_location, clear_location + FFI_TRAMPOLINE_SIZE);

替換爲:

__clear_cache(clear_location, clear_location + FFI_TRAMPOLINE_SIZE);

再次編譯,即可生成libffi庫文件,生成庫文件位於Debug目錄下。如圖 5-8所示。

  這裏寫圖片描述

圖 5-8 編譯生成libnopoll庫文件
打開x86虛擬機,並配置好libffi工程的設備IP爲x86虛擬機的IP,即可將生成的庫文件導入到x86虛擬機中。至此,則完成了libffi的編譯及上傳。剩下的工作則是通過測試用例測試移植後的libffi庫是否能夠正常運行。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章