千家信息网

移植libffi到SylixOS

发表于:2024-12-12 作者:千家信息网编辑
千家信息网最后更新 2024年12月12日,1. 开发环境宿主机:Windows 7集成开发环境:Real-Evo IDE 3.2.5虚拟机:Ubuntu 14.04本篇仅介绍libffi库的移植过程,包括资源的获取,工程文件的修改以及编译出错
千家信息网最后更新 2024年12月12日移植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库是否能够正常运行。


0