i.MX6ULL开发板源码交叉编译器.由于开发板的CPU处理能力、外存和内存存储空间的大小限制,它们不足以能够运行 gcc 编译环境嵌入式大部分的过程都是交叉编译。PC编译,在ARM开发板上运行

文章基于HD-IMX6ULL-MB 系列开发板测试验证,该开发板由武汉芯路遥科技有限公司与武汉万象奥科电子有限公司合作推出。此开发板基于 NXP iMX6ULL 系列 Cortex-A7 高性能处理器设计,适用于快速开发一系列具有创新性的产品如人机界面工业 4.0 扫描仪、车载终端以及便携式医疗设备。

i.MX6ULL开发板

1.交叉编译器介绍

1.1. 交叉编译器

 X86 架构 Linux 系统下进行 C 程序开发时, 我们使用系统的 gcc 编译器进行代码的编译, 编译生成的可执行程序直接在 X86 架构下的 PC 下运行的,这个过程叫做 本地编译 (Native Compile) 。 而如果该C程序想要编译出来后放到ARM处理器架构的系统上运行, 则需要在 X86 架构Linux系统下使用支持 ARM 的编译器编译, 这个编译器我们通常称为 交叉编译器 (Cross Compiler)。

而在一种平台上编译出能在另外一种体系结构完全不同处理器上运行程序的编译过程,叫做 交叉编译(Cross Compile)。比如在PC平台(X86 CPU)上编译出能运行在以ARM为内核的CPU平台上的程序,编译得到的程序在X86 CPU平台上是不能运行的,必须放到ARM CPU平台上才能运行,虽然两个平台用的都是Linux系统。

交叉编译器

交叉编译工具链是一个由编译器、连接器和解释器组成的综合开发环境,交叉编译工具链主要由binutils、gcc和glibc三个部分组成。有时出于减小 libc 库大小的考虑,也可以用别的 c 库来代替 glibc, 例如 uClibc 或 newlib。

之所以几乎所有的ARM开发板开发都选择交叉编译,这是因为这些开发板生产出来后并没有系统,这 时需要在PC上使用交叉编译器交叉编译操作系统源码,为它构建一个完整的 Linux 系统。另外,由于CPU处理能力、外存和内存存储空间的大小限制,它们不足以能够运行 gcc 编译环境,所以嵌入式开发绝大部分的过程都是交叉编译

1.2 常用的交叉编译器

1.2.1 Codesourcery 交叉编译器

Codesourcery一直是在做 ARM 目标 GCC 的开发和优化,它直接提供 Windows和Linux下的二进制版本交叉编译器,不用下载源码包一步一步自己编译,非常方便。它的 ARM GCC 早期在市场上非常优秀,很多公司在作嵌入式产品开发时,都会直接下载使用该公司提供的交叉编译器。

Codesourcery 推出的产品叫 Sourcery G++ Lite Edition, 其中基于 command-line 的编译器是免费的, 在官网上可以下载, 而其中包含的 IDE 和 debug 工具是收费的, 当然也有30天试用版本的。后来CodeSourcery 被明导国际(Mentor Graphics)收购, 现在则被西门子(Siemens) 收购了。

其下载地址为: h ttps://www.plm.automation.siemens.com/global/en/products/embedded-softwa re/sourcery-toolchain-services.html

1.2.2 Linaro交叉编译器

除了CodeSourcery外,还有一个组织也提供ARM Toolchain,它就是Linaro。Linaro是在2010年台北国际计算机展(COMPUTEX)期间,ARM、Freescale、Samsung ,ST-Ericsson、德州仪器(TI)与IBM等6家大厂,宣布合资成立的非赢利Linux基础架构软件研发商。

Linaro目标在投入新资源和集成业界的努力,改进与优化在ARM-based架构上运行的开放原始码软件及 开发工具,将过去必须由系统单芯片(SoC)业者,各自将本身产品与Linux操作系统集成与开发的重复投 资,透过这间合资公司推出开放原始码的底层软件工具,解决ARM生态系中,重复投资造成的资源浪 费。

其下载链接地址为: h ttps://launchpad.net/linaro-toolchain-binaries

1.2.3 Ubuntu交叉编译器

Ubuntu之所以能成为嵌入式系统开发的首选Linux发行版本,正是因为它的软件包在线安装仓库中包含 有海量的开发工具/软件,其中就包括嵌入式系统开发所需的交叉编译器、dtc等开发工具,这也就是为 什么几乎所有主流的半导体厂商在发布SDK时都推荐使用Ubuntu系统。

在Ubuntu 系统中提供了如下四个版本的交叉编译器软件包:

  • gcc-arm-linux-gnueabi ---- armel,ARM EABI Little-endian

  • gcc-arm-linux-gnueabihf ---- armhf,ARM Hard Float

  • gcc-arm-none-eabi ---- bare metal, Linux下用于编译 ARM 架构的裸机系统,使用的是newlib这个嵌入式C库。

  • gcc-aarch64-linux-gnu ---- arm64,用于编译64位ARM处理器系统

在上面的软件包中,gcc-arm-none-eabi 和 gcc-aarch64-linux-gnu 都比较好理解。而 gcc-arm-linux- gnueabi 与 gcc-arm-linux-gnueabihf 有什么区别呢?这就涉及到 ARM 处理器架构中的浮点运算相关知识了。

出于低功耗、封装限制等种种原因,以前的一些ARM处理器没有独立的硬件浮点运算单元,需要使用软 件来实现浮点运算。随着技术发展,现在高端的ARM处理器基本都具备了硬件执行浮点操作的能力。这 样,新旧两种架构之间的差异,就产生了两个不同的嵌入式应用程序二进制接口(EABI)——软浮点

Ubuntu交叉编译器

(SoftFP)与矢量浮点(VFP)。但是软浮点(soft float)和硬浮点(hard float)之间有向前兼容却没有向后兼容的能力,也就是软浮点的二进制接口(EABI)仍然可以用于当前的高端ARM处理器。

在ARM体系架构内核中,有些有浮点运算单元(fpu,floating point unit),有些没有。对于没有fpu内核,是不能使用armel和armhf的。在有fpu的情况下,就可以通过gcc的选项-mfloat-abi来指定使用哪 种,有如下四种值:

1.soft:不用fpu计算,即使有fpu浮点运算单元也不用。

2.armel:(arm eabi little endian)也即softfp,用fpu计算,但是传参数用普通寄存器传,这样中断的时候,只需要保存普通寄存器,中断负荷小,但是参数需要转换成浮点的再计算。

3.armhf:(arm hard float)也即hard,用fpu计算,传参数用fpu中的浮点寄存器传,省去了转换性能最好,但是中断负荷高。

4.arm64:64位的arm默认就是hard float的,因此不需要hf的后缀。

在之前的EABI中,armel(低端ARM硬件)在执行浮点运算之前,浮点参数必须首先通过整数寄存器, 然后传递到浮点运算单元。新的EABI ,也就是armhf,通过直接传递参数到浮点寄存器优化了浮点运算的调用约定。相比我们熟悉的armel,armhf代表了另一种不兼容的二进制标准。在一些社区的支持下,armhf目前已经得到了很大的发展。像Ubuntu,已经计划在之后的发行版中放弃armel,转而支持armhf编译的版本。正如目前依然很火热的Raspberry Pi(ARM11),由于ubuntu只支持armv7架构的编译,Raspberry Pi将不能直接安装ubuntu系统。而 BB Black(Cortex-A8)和 Cubietruct(Cortex-A7)则同时支持ubuntu的armel与armhf的编译。

kernel、rootfs和app编译的时候,指定的必须保持一致才行。使用softfp模式,会存在不必要的浮点到 整数、整数到浮点的转换。而使用hard模式,在每次浮点相关函数调用时,平均能节省20个CPU周期。 对ARM这样每个周期都很重要的体系结构来说,这样的提升无疑是巨大的。在完全不改变源码和配置的 情况下,在一些应用程序上,虽然armhf比armel硬件要求(确切的是指fpu硬件)高一点,但是armhf 能得到20-25%的性能提升。对一些严重依赖于浮点运算的程序,更是可以达到300%的性能提升。

1.3. 交叉编译测试

接下来我们以大家熟悉的 hello world 程序为例,讲解嵌入式交叉编译过程。

1.3.1 本地编译运行hello程序

首先,我们使用 vim 编辑器编写 hello.c 测试程序:

我们知道,C程序必须要使用编译器编译生成可执行程序,才能执行。接下来我们使用 Linux服务器上的

gcc 编译该程序并运行:

我们可以使用 file 命令查看 hello 程序的相关信息,由此可知该程序应该在X86-64位的系统上运行:

我们将该程序下载到开发板上运行试试看,这时系统会提示可执行文件格式出错,不能正常运行。

1.3.2 交叉编译运行hello程序

我们知道C程序具有可移植性,使用PC上的编译器编译生成的程序应该在PC上运行,而不能在其他处理 器架构上运行,那怎样让 hello.c 程序在ARM开发板上运行呢?这里就需要使用ARM的交叉编译器来对该程序进行交叉编译,这样编译输出的可执行程序就能在ARM开发板上运行了。

因为我们的 i.MX6ULL 处理器带有硬件浮点FPU,所以这里我们选择安装硬浮点交叉编译器:

接下来,我们使用 ARM 的交叉编译器编译该 hello.c 程序,并尝试在 X86-64位 Linux服务器上运行,我们会发现 Linux 服务器上默认并不能运行该程序:

接下来我们使用 file 命令查看该程序的相关信息,由此可知该程序应该在ARM处理器系统上运行:

我们将该程序下载到开发板上则能正常运行了。

由此可见:

C程序如果想在PC上运行,则应该用PC的编译器来编译;而该程序想要在ARM开发板上运行,则必 须用ARM的交叉编译器对源码重新进行交叉编译;

C程序具有可移植性是指,C程序源代码不用作任何的修改,使用不同的编译器编译生成的可执行程 序可以在不同的处理器架构平台上运行;

版权声明

本文档所有内容文字资料由凌云实验室郭工编著,主要用于凌云嵌入式Linux教学内部使用,版权归属 作者个人所有。任何媒体、网站、或个人未经本人协议授权不得转载、链接、转帖或以其他方式复制发布/发表。已经授权的媒体、网站,在下载使用时必须注明来源,违者本人将依法追究责任。

Copyright (C)2021 凌云物网智科实验室·郭工

Author: GuoWenxue guowenxue@gmail.com

百度安全验证

http://man.chinaunix.net/linux/lfs/htmlbook/chapter06/chapter06.html参考具体的gcc相关件安装 本人的联系方式为:549827768@qq.com,西华大学 我们采用crosstool0.42来作为我们编译交叉编译工具链的脚本。详细的用法说明请阅读网站上的文档crosstool-how to 。 [zzl@localhost] tar -xzvf crosstool-0.43.tar.gz [zzl@localhost]cd crosstool-0.42 我们可以看到目录下有很多.sh脚本和.dat配置文件。每一个支持的CPU都有它所相应的脚本,如我们选用demo-arm9tdmi.sh 需要我们记住的三个重要的变量: TARBALLS_DIR=$HOME/downloads #$HOME为用户的主目录,如fedora这个目录,是固定的,与$PWD为当前路径不同 RESULT_TOP=/usr/local/arm #做了更改 GCC_LANGUAGES="c,c++" 我们需要如下压缩包:gcc-3.4.1.tar.gz glibc-2.3.3.tar.gz linux-2.6.17binutils-2.15.tar.gz glibc-linuxthreads-2.3.3.tar.gz gdb6.0a.tar.gz,且还要下载内核arm补丁,给它打补丁,之后再压缩成原来格式,并删除解压的文件,只保留打补丁后的文件 下面为打补丁的格式,其中linuxlinux内核解压后产生的目录: tar jxvf patch-2.4.18-rmk7.bz2;cp patch-2.4.18-rmk7 linux;cd linux;patch -p1<patch-2.4.18-rmk7 最后再次还原成原来的包文件:tar czvf linux-2.4.18.tar.gz linux ,即将linux目录及其文件打包为前面的文件名 首要任务是下载这些源代码件包,并将它们放在/home/fedora/downloads下面,保证这些包的所有者为当前用户而不是根用户。 可以用chown usr 文件名,更改使用者,更改后的使用者为usr,我的用户名为fedora,可以用ll查看用户名 我们选择的配置是:demo-arm9tdmi.sh,其内容具体如下: #!/bin/sh set -ex TARBALLS_DIR=$HOME/downloads RESULT_TOP=/usr/local/arm #原本是:/opt/crosstool ,后修改了 export TARBALLS_DIR RESULT_TOP GCC_LANGUAGES="c,c++" export GCC_LANGUAGES # Really, you should do the mkdir before running this, # and chown /opt/crosstool to yourself so you don't need to run as root. mkdir -p $RESULT_TOP #应该先创建/usr/local/arm目录,并chmod fedora /usr/local/arm 目录的用户为fedora #-p, --parents 需要时创建目标目录的上层目录,但即使这些目录已存在也不当作错误处理 # Build the toolchain. Takes a couple hours and a couple gigabytes. eval `cat arm9tdmi.dat gcc-3.2.3-glibc-2.2.5.dat` sh all.sh --notest --gdb#增加调试 echo Done. 从 eval `cat arm9tdmi.dat gcc-3.2.3-glibc-2.2.5.dat` sh all.sh --notest --gdb 可以看出,我们的gcc版本采用3.2.3,glibc版本采用2.2.5。 我们再来看gcc-3.2.3-glibc-2.2.5.dat这个文件,并做一些更改 BINUTILS_DIR=binutils-2.15 GCC_DIR=gcc-3.2.3 GLIBC_DIR=glibc-2.2.5 LINUX_DIR=linux-2.4.18 #修改后的内容,为了匹配内核 GLIBCTHREADS_FILENAME=glibc-linuxthreads-2.2.5 GDB_DIR=gdb-6.0 #增加的内容 修改 armtdmi.dat 文件如下红色部分: KERNELCONFIG=`pwd`/arm.config TARGET=arm-9tdmi-linux-gnu(这个名字可以改成你想要的交叉工具链前缀名) TARGET_CFLAGS="-O" GCC_EXTRA_CONFIG="--with-cpu=arm9tdmi --enable-cxx-flags=-mcpu=arm9tdmi" 修改all.sh 文件如下: 修改 all.sh 文件第 41 行,指定存放工具链文件夹的名称; vimall.sh +41 将:TOOLCOMBO=$GCC_DIR‐$GLIBC_DIR 改为: TOOLCOMBO=3.2.3 #gcc版本号作为文件名 修改第 70 行,更改安装路径,将: PREFIX=${PREFIX‐$RESULT_TOP/$TOOLCOMBO/$TARGET} 改为 PREFIX=${PREFIX‐$RESULT_TOP/$TOOLCOMBO} #即路径最终为:/usr/local/arm/3.2.3,gcc就在3.2.3的bin库中 最后: #vi /etc/profile在if代码 语句中添加绝对路径 PATH=$PATH :/usr/local/arm/3.2.3/gcc-3.2.3-glibc-2.2.5/arm9tdmi-linux-gnu/bin 也可以设置为临时变量:export PATH=$PATH :/usr/local/arm/3.2.3/gcc-3.2.3-glibc-2.2.5/arm9tdmi-linux-gnu/bin 但每次开机要重启,此时我们编译就上上述的路径中,包含arm-9tdmi-linux-gnu-gccarm-9tdmi-linux-gnu-g++,arm-9tdmi-linux-gnu-ld 如果gcc版本太高,可以用 yum install compat-gcc-34 ,3.4版本的gcc不过之前应该在/usr/bin下重命名gcc,以保证之后还能运行,可以查看它的版 本,cat /proc/version,用它的版本号来重命名,gcc -v查看当前gcc版本号 ftp://ftp.sunet.se/pub/Linux/distributions/scientific/53/i386/SL/ 上面这个网站中有一些低版本的gcc和glibc,另外还有一些nfs工具等等,其中就有以compat开头的gcc和glibc,另外当然还有以gcc、glibc开头的 specs文件最后在/usr/local/arm/3.2.3/gcc-3.2.3-glibc-2.2.5/arm9tdmi-linux-gnu/lib中,specs文件中一般有一句/lib/ld-linux.so.2,有可能要修改为自己的库
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值