为何要交叉编译
交叉编译似乎是相对于本地编译(nativebuild)来说的,我相信你们最开始学习C/C++这种语言的时侯,都是在笔记本上写程序,之后在笔记本上编译生成可执行文件,最后在笔记本上运行。程序的编辑——》编译——》运行,整个过程都是在一台X86笔记本上。
当我们开始接触嵌入式开发后,事情变的不一样了,你在笔记本上写程序,在笔记本上编译出可执行文件,最后这个可执行文件须要下载到你的开发板上运行。程序最后运行的环境变了,例如你的开发板是基于Arm的——程序在X86上编辑,编译,最终运行在另一个和X86完全不同的构架的Arm芯片上。
之所以整个流程弄成了这个样子,这是由嵌入式的特点决定的:通常嵌入式系统上面使用的芯片性能都比较弱,但是绝大部份都不能像X86一样运行Windows/Ubuntu桌面系统,虽然能运行,性能也很弱,难以给你提供一个在开发板上写代码、编译代码的环境。所以我们还是离不开X86笔记本强悍高效的桌面环境进行软件开发。
然而这样有一个问题,X86、Arm、MIPS、RISC-V这种芯片,它们的指令集是由不同的组织或则公司设计的,彼此并不兼容——Arm和MIPS的CPU难以运行以X86的指令集编码的程序,反之亦然。所以我们要在X86的笔记本上编译出才能在Arm上运行的程序,我们必须明晰告诉编译器,编译生成的可执行文件须要以Arm指令集的标准编码。为了让这个流程显得简单,开发者们为不同的芯片开发了不同的编译器,例如针对Arm平台的arm-linux-gcc,针对mips平台的mips-linux-gnu-gcc,这种编译器都是基于GCC针对具体的构架指令集进行对应配置,所以它们在运行的时侯就都会生成和该目标平台对应的可执行文件。
这篇文章主要讲Arm的交叉编译linux设置环境变量,所以这儿前面都以Linux开发环境下的Armgcc为例。
工具链的种类
GCC的命名规则为:arch[-vendor][-os][-(gnu)eabi]-gcc
例如arm-linux-gnueabi-gcc,arm-none-eabi-gcc,aarch64-linux-gnu-gcc
带[]的是可选部份。
arch:芯片构架,例如32位的Arm构架对应的arch为arm,64位的Arm构架对应的arch为aarch64。
vendor:工具链提供商,大部份工具链名子上面都没有包含这部份。
os:编译下来的可执行文件(目标文件)针对的操作系统,例如Linux。
arm-none-eabi-gcc通常适用用于ArmCortex-M/Cortex-R平台,它使用的是newlib库。
arm-linux-gnueabi-gcc和aarch64-linux-gnu-gcc适用于ArmCortex-A系列芯片,后者针对32位芯片,前者针对64位芯片,它使用的是glibc库。可以拿来编译u-boot、linuxkernel以及应用程序。
另外须要补充一点的是,32位的Arm和64位的Armlinux交叉编译环境,它们的指令集是不同的,所以须要使用不同的工具链。其实,Arm64为了保证前向兼容,提供了一个32位的兼容模式,所以我们用arm-linux-gnueabi-gcc编译的应用程序也是可以直接在Arm64的系统上运行的,并且LinuxKernel和U-Boot就不行,除非你提早把CPU切换到32位模式。以前有个项目使用了一颗双核的Arm64芯片,然而显存只有64M,为了节约空间,在CPU运行到U-Boot之前,我们就把它切到了32位模式,旁边的U-Boot、LinuxKernel,应用全部都用32位编译,加上Thumb指令集,节约了不少空间。
工具链的下载安装
下载地址
如今Arm平台上用的最广泛的工具链是Linaro发布的,你们可以到Linaro官网下载
同时我发觉Linaro声明称后续新版本的工具链会通过Arm官方发布。
4.9、6.3、7.4这种是工具链的版本号,理论上越新的版本,性能越好。
在一次优化u-boot大小的时侯我发觉6.3版本的工具链生成的二补码文件要比4.9版本生成的小几百个字节,进一步对比剖析后发觉是由于6.3版本的工具链把代码中没用到的一些字符串全部过滤掉了,尽管4.9的版本也有过滤ubuntu linux,而且没有6.3做的干净。
目前用的多的版本应当是6.x,其实我也见到有些开发组织在使用7.x的工具链,例如Armbian目前在用7.4编译内核。
另外目前最新版本的U-Boot早已强制必须使用6.0以上版本的GCC进行编译。
这两个网站下载可能会比较慢,可以考虑使用国外的镜像下载
下载
可以直接点击下载linux交叉编译环境,也可以通过行用wget下载:
下载了两个,arm针对是是32位的,aarch64针对Arm64.
安装
解压:
xz-dgcc-linaro-6.3.1-2017.02-x86_64_arm-linux-gnueabihf.tar.xz
xz-dgcc-linaro-6.4.1-2017.11-x86_64_aarch64-linux-gnu.tar.xz
安装到/usr/local/toolchain/目录下,其实也可以置于其他任何你喜欢的地方:
sudomkdir-p/usr/local/toolchain
tar-xvfgcc-linaro-6.3.1-2017.02-x86_64_arm-linux-gnueabihf.tar-C/usr/local/toolchain/
sudotar-xvfgcc-linaro-6.4.1-2017.11-x86_64_aarch64-linux-gnu.tar-C/usr/local/toolchain/
成功后执行ls,可以见到两个toolchain都被安装到/usr/local/toolchain/目录下了。
添加环境变量
只有把可执行文件对应的路径加入到PATH环境变量里,系统才可以认到那些命令。
这儿的路径就是前面截图中pwd命令显示的路径,可以添加到~/.bashrc文件的最后:
PATH=$PATH:/usr/local/toolchain/gcc-linaro-6.3.1-2017.02-x86_64_arm-linux-gnueabihf/bin:/usr/local/toolchain/gcc-linaro-6.4.
1-2017.11-x86_64_aarch64-linux-gnu/bin
注意:两个独立的路径之间用逗号:隔开。
执行source~/.bashrc命令让配置生效,之后我们就可以在命令行里执行这种命令了:
例如arm-linux-gnueabihf-gcc-v和aarch64-linux-gnu-gcc-v查看编译器版本:
能看见如图的信息,说明早已大功告成了。
编译内核
这儿下载imx的官方内核:
切换到4.19版本:
编译:
假如你笔记本上其他的依赖库都安装的完整,才能顺利编译成功。
本文原创地址://q13zd.cn/wsmyzasyxdcx.html编辑:刘遄,审核员:暂无