本帖最后由 xcoder 于 2016-3-15 22:18 编辑
实战01 安装交叉编译器
交叉编译是指在一种平台(主机)上通过编译程序生成另一种平台(目标机)上可运行的代码。这个编译程序称之为交叉编译工具链(cross compilation tool chain)或编译器。前面我们安装的Ubuntu系统是基于X86平台的,如果使用默认的编译器进行源码编译,得到的可执行程序由X86指令集组成,只能在X86平台上运行,而pcDuino板处理器A20属于ARM架构,无法运行X86指令集的程序。因此,我们需要一个交叉编译器,它可以在X86平台上运行,将源码编译成ARM平台可以运行的程序。 图1.1 交叉编译器
图1.2 交交叉编译器下载 Linaro提供了不同平台多种版本的交叉编译工具,可以根据的开发计算机配置选择合适版本。这里我们选择版本gcc-linaro-arm-linux-gnueabihf-4.9-2014.09_linux.tar。 1.1解压
- # tar xvf gcc-linaro-arm-linux-gnueabihf-4.9-2014.09_linux.tar -C /home/ubuntu/pcduino/
复制代码
1.2查看gcc等二进制工具(binutils)
- # cd /home/ubuntu/pcDuino
- # cd gcc-linaro-arm-linux-gnueabihf-4.9-2014.09_linux
- # ls bin
复制代码
图1.3 工具链
1.3设置环境变量 为了在使用的时候省去绝对路径的引用,我们将编译工具所在目录 /home/ubuntu/pcduino/gcc-linaro-arm-linux-gnueabihf-4.9-2014.09_linux/bin加入环境变量PATH中。修改文件/home/ubuntu/.bashrc,在文件尾新增一行, - PATH=$PATH:/home/ubuntu/pcduino/gcc-linaro-arm-linux-gnueabihf-4.9-2014.09_linux/bin
复制代码
并保存。在当前shell终端执行 - # source /home/ubuntu/.bashrc
复制代码使配置生效。
1.4工具链介绍
相信读者已经发现,这些工具名称都有共同的前缀“arm-linux-gnueabihf”, 对于arm-linux容易理解,分别是体系架构和OS类型,那么gnueabihf是什么含义呢?在理解其含义之前,先了解以下几个名词:GNU、ABI和EABI。 GNU:是GNU's NotUnix 的递归缩写。GNU计划,是由RichardStallman在1983年9月27日公开发起的,它的目标是创建一套完全自由的操作系统。 - ABI:应用二进制接口(ApplicationBinary Interface)。描述了应用程序和操作系统之间,应用程序和使用的库之间,以及与其他应用程序的低级接口。 - EABI:嵌入式ABI(Embedded ABI)。嵌入式应用二进制接口指定了文件格式、数据类型、寄存器使用、堆积组织优化和在一个嵌入式软件中的参数的标准约定。开发者使用自己的汇编语言也可以使用 EABI 作为与兼容的编译器生成的汇编语言的接口。
现在我们明白了gnueabihf中的gnueabi部分,即:这是一个GNU 编译器,支持EABI,剩下的hf部分呢?它与ARM对待浮点数运算的策略有关。ARM在 处理浮点数运算时引入了软浮点(soft-float)和硬浮点(hard-float)的概念。 - 硬浮点:依赖FPU(浮点运算单元),编译器将代码编译成使用硬件浮点协处理器的指令,由FPU去执行。FPU通常有一套额外的寄存器来完成浮点参数传递和运算。使用硬件浮点运算单元FPU会带来性能上的提升。 - 软浮点:不依赖于FPU,编译器把浮点运算转换成浮点运算的函数调用和库函数调用,浮点参数的传递也是通过ARM寄存器或者堆栈完成。不进行FPU的指令调用,也不使用浮点寄存器的参数传递。 实际上,与“arm-linux-gnueabihf”类似的还有一种前缀“arm-linux-gnueabi”,二者属于不同的EABI架构。 - arm-linux-gnueabi属于armel 架构EABI - arm-linux-gnueabihf属于armhf架构EABI 在armel中,有三种方式处理浮点数计算,以gcc为例,对应的-mfloat-abi参数值有三个选择:soft、softfp和hard。 - soft是指所有浮点运算全部在软件层实现,效率低,会存在浮点到整数、整数到浮点的转换,只适合于早期没有FPU、的ARM处理器; - softfp是armel默认设置,由FPU处理浮点计算,但函数参数的传递不使用FPU寄存器,而是使用ARM通用的整型寄存器; - hard是指由FPU处理浮点计算,函数参数的传递也使用FPU寄存器。 soft与softfp和hard是兼容的,但softfp和hard两种模式不兼容。默认情况下,armel使用softfp,同时将hard模式的armel单独作为一个abi,称之为armhf,可见armhf是armel的一个特例。现在回头看下arm-linux-gnueabihf的含义:GNU编译器,支持硬件浮点运算。为了确认这一点,我们可以从gcc的版本信息中查看:
- # arm-linux-gnueabihf-gcc -v
- ...
- linux/install/arm-linux-gnueabihf/libc --enable-languages=c,c++,fortran --disable-multilib --enable-multiarch --with-arch=armv7-a --with-tune=cortex-a9 --with-fpu=vfpv3-d16 --with-float=hard --with-pkgversion='crosstool-NG linaro-1.13.1-4.9-2014.09 - Linaro GCC 4.9-2014.09'
- ...
- mode=thumb --disable-multilib --with-float=hard
- Thread model: posix
- gcc version 4.9.2 20140904 (prerelease) (crosstool-NG linaro-1.13.1-4.9-2014.09 - Linaro GCC 4.9-2014.09)
复制代码我们可以看到版本信息中含有“--with-float=hard”,说明arm-linux-gnueabihf使用的是硬浮点。与硬浮点有关的还有一个选项--with-fpu=vfpv3-d16,这个选项描述了FPU类型是vfpv3-d16。其中VFP (vector floating Point) 为半精度、单精度和双精度浮点运算提供硬件支持,符合 IEEE 754 标准。VFP目前有多个版本,如VFPv2 (一些 ARM9 / ARM11)、VFPv3-D32(使用32个浮点寄存器)、 VFPv3-D16(只使用16个浮点寄存器)和VFPv3+NEON等。
关于交叉编译器几个重要的目录: arm-linux-gnueabihf/libc: libc头文件、库相关 arm-linux-gnueabihf/libc/usr/include: libc头文件目录 arm-linux-gnueabihf/libc/usr/include/linux: linux头文件目录 arm-linux-gnueabihf/libc/lib/arm-linux-gnueabihf: libc动态链接库 bin:目标板编译工具(binutils) arm-linux-gnueabihf/bin:主机编译工具(binutils) arm-linux-gnueabihf/include/c++:C++有关头文件和库
1.5总结
本章介绍了交叉编译器分作用,并演示了安装过程,此外对EABI以及浮点运算做了简要的阐述。我们在接下来的章节就用这个交叉编译器编译boot、linux等镜像。
|