交叉编译实际上是相对于本地编译(build)来说的。 相信大家刚开始学习C/C++等语言时,都是在计算机上编写程序,然后在计算机上编译生成可执行文件,最后在计算机上编译。 运行。 程序编辑->编译->运行,整个过程是在X86计算机上进行的。
当我们开始涉足嵌入式开发时,事情发生了变化。 你在电脑上编写程序,在电脑上编译出可执行文件,最后需要将可执行文件下载到你的开发板上运行。 程序最终运行的环境发生了变化。 例如,如果你的开发板是基于Arm的——程序在X86上编辑编译,最后运行在另一个与X86架构完全不同的Arm芯片上。
整个流程之所以变成这样,是由嵌入式系统的特点决定的:一般嵌入式系统所使用的芯片性能都比较弱,大部分都不能像X86/桌面系统那样运行,即使可以运行性能也很弱,无法为你提供在开发板上编写和编译代码的环境。 因此,我们进行软件开发仍然离不开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开发环境下的Arm gcc为例。
工具链的类型
GCC的命名规则为:arch [-] [-os] [-(gnu)eabi]-gcc
例如,arm-linux--gcc、arm-none-eabi-gcc、-linux-gnu-gcc
arm-none-eabi-gcc 一般适用于 Arm-M/-R 平台,并且使用该库。
arm-linux--gcc 和 -linux-gnu-gcc 适用于 Arm-A 系列芯片。 前者适用于32位芯片,后者适用于64位芯片。 它使用 glibc 库。 可用于编译u-boot、linux和应用程序。
另外需要补充的是,32位Arm和64位Arm具有不同的指令集,因此需要使用不同的工具链。 当然,为了保证向前兼容,Arm64提供了32位兼容模式,所以我们用arm-linux--gcc编译的应用程序也可以直接在Arm64系统上运行,但是Linux和U-Boot不能,除非你提前将CPU切换到32位模式。 曾经有一个项目,使用了四核Arm64芯片,但内存只有64M。 为了节省空间,在CPU运行到U-Boot之前,我们将其切换到32位模式。 后来的U-Boot、Linux,所有的应用程序都用32位编译,再加上Thumb指令集,这样就节省了很多空间。
下载安装工具链下载地址
Arm平台上使用最广泛的工具链现已发布。 您可以从官方网站下载,地址如下:
同时,我找到了一份声明,表示后续新版本的工具链将通过Arm正式发布。
4.9、6.3、7.4 这些是工具链的版本号。 理论上来说,版本越新,性能越好。
在优化u-boot大小时,发现6.3版本工具链生成的二进制文件比4.9版本生成的二进制文件小了几百字节。 经过进一步的对比分析,发现是因为6.3版本的工具链导致代码没用了。 收到的一些字符串已被过滤掉。 4.9版本虽然也有过滤,但是不如6.3干净。
目前最常用的版本应该是6.x。 当然,我也看到一些开发组织使用7.x工具链。 例如,目前使用7.4来编译内核。
另外,最新版本的U-Boot已经强制使用GCC 6.0以上版本进行编译。
这两个网站的下载速度可能会很慢。 您可以考虑使用国内镜像下载:
下载
可以直接点击下载,也可以通过命令行使用wget命令下载:
wget https://mirrors.tuna.tsinghua.edu.cn/armbian-releases/_toolchains/gcc-linaro-6.3.1-2017.02-x86_64_arm-linux-gnueabihf.tar.xz
wget https://mirrors.tuna.tsinghua.edu.cn/armbian-releases/_toolchains/gcc-linaro-6.4.1-2017.11-x86_64_aarch64-linux-gnu.tar.xz
复制
我下载了两个,arm版本是32位的,arm版本是针对Arm64的。
安装
解压:
xz -d gcc-linaro-6.3.1-2017.02-x86_64_arm-linux-gnueabihf.tar.xz
xz -d gcc-linaro-6.4.1-2017.11-x86_64_aarch64-linux-gnu.tar.xz
复制
安装到 /usr/local// 目录,当然你也可以把它放在你喜欢的任何地方:
sudo mkdir -p /usr/local/toolchain
tar -xvf gcc-linaro-6.3.1-2017.02-x86_64_arm-linux-gnueabihf.tar -C /usr/local/toolchain/
sudo tar -xvf gcc-linaro-6.4.1-2017.11-x86_64_aarch64-linux-gnu.tar -C /usr/local/toolchain/
复制
成功执行ls命令后,可以看到两者都安装在/usr/local//目录下。
添加环境变量
只有将可执行文件对应的路径添加到PATH环境变量中,系统才能识别这些命令。
这里的路径就是上面截图中pwd命令显示的路径,可以添加到~/. 文件:
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
复制
注意:使用冒号:分隔两个独立的路径。
执行~/. 命令使配置生效,然后我们可以在命令行执行这些命令:
例如,arm-linux--gcc-v 和 -linux-gnu-gcc-v 检查编译器版本:
如果你能看到如图所示的信息,就说明你已经完成了。
编译内核
在这里下载imx的官方内核:
git clone https://source.codeaurora.org/external/imx/linux-imx
复制
切换到4.19版本:
git checkout -b imx_v2019.04_4.19.35_1.0.0 origin/imx_v2019.04_4.19.35_1.0.0
复制
编译:
make ARCH=arm imx_v7_defconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-
复制
如果你的电脑上所有其他依赖库都安装完整,就可以编译成功。