第二章:目标架构与宿主机
好,咱们正式开始动手前的准备工作。
这一章,说白了就是搞清楚两件事:你要给谁编译代码?(目标架构)和你在哪台机器上编译?(宿主机)。这两个概念搞混了,后面所有配置都会乱套。我见过太多新手上来就对着错误提示发懵,其实根源往往就是没分清楚目标机和宿主机。
2.1 常见嵌入式架构:ARM、MIPS、RISC-V、x86
嵌入式世界里,CPU架构五花八门。但咱们做交叉编译,最常打交道的就这四种。我按个人经验,从最常见到相对小众的顺序给你捋一遍。
2.1.1 ARM —— 嵌入式领域的王者
ARM架构,你肯定不陌生。手机、路由器、智能家电,到处都是它的身影。为什么这么流行?功耗低、授权灵活、生态成熟。
我个人习惯把ARM分成两个大类:
- Cortex-A系列:跑Linux、Android的,比如树莓派的BCM2837(Cortex-A53)。性能强,带MMU(内存管理单元)。
- Cortex-M系列:跑裸机或RTOS的,比如STM32F4(Cortex-M4)。没MMU,资源少,但实时性好。
做交叉编译时,你首先要确认目标板用的是A系列还是M系列。因为编译器选项差别很大。嗯,这里要注意:ARMv7、ARMv8这些版本号,直接决定了你该用哪种编译器。
2.1.2 MIPS —— 曾经的RISC明星
MIPS架构,现在可能不如ARM那么火,但在路由器、机顶盒领域,它依然占有一席之地。龙芯早期也用过MIPS指令集。
MIPS有个特点:字节序。它分大端(Big-Endian)和小端(Little-Endian)。你想想看,同一个MIPS芯片,不同厂家可能用不同的字节序。比如,博通的路由器芯片常用大端,而一些嵌入式设备用的小端。
我在项目中遇到过最头疼的事,就是拿到一个MIPS的交叉编译工具链,没注意字节序,编译出来的程序在目标板上跑得乱七八糟。后来我养成了习惯:拿到工具链第一件事,先看名字里有没有"mipsel"(小端)还是"mips"(大端)。
2.1.3 RISC-V —— 开源指令集的新星
RISC-V,这几年太火了。它是完全开源的,没有授权费。说白了,你可以免费用它设计自己的CPU。这对很多初创公司和高校来说,吸引力巨大。
RISC-V的交叉编译,目前还在快速演进中。常见的工具链前缀是riscv64-unknown-linux-gnu-。但要注意,RISC-V有多个扩展指令集,比如RV64GC(通用组合)。你编译时,得确保目标板支持这些扩展。
我记得有一次,帮朋友调试一块RISC-V开发板,他编译时没加-march=rv64gc,结果程序一跑就非法指令。嗯,这就是没对齐指令集扩展的典型问题。
2.1.4 x86 —— 你桌上的电脑,也能当嵌入式目标
等等,x86不是PC架构吗?没错。但很多工业控制、边缘计算设备,用的就是x86架构的CPU,比如Intel Atom、AMD Geode。这时候,你依然需要交叉编译——只不过目标架构是x86,宿主机可能也是x86。
你可能会问:都是x86,为什么还要交叉编译?因为宿主机可能是64位的,目标板是32位的。或者,宿主机是Ubuntu,目标板是Yocto构建的定制Linux。说白了,架构相同,但系统库不同。
2.2 宿主机环境准备
宿主机,就是你用来编译代码的电脑。我建议你至少准备一台Linux机器,或者虚拟机。Windows也能做,但坑比较多。
2.2.1 Linux宿主机(推荐)
我个人习惯用Ubuntu LTS版本,比如20.04或22.04。为什么?社区活跃,软件包全,遇到问题好搜解决方案。
你需要安装的基础工具:
sudo apt update
sudo apt install build-essential git wget flex bison texinfo \
libncurses-dev gawk python3 python3-pip
这些工具是编译交叉编译器本身用的。如果你只是用现成的工具链,那只需要安装对应的交叉编译器包就行。比如:
sudo apt install gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf
2.2.2 Windows宿主机(备选)
如果你非要用Windows,我建议你装WSL(Windows Subsystem for Linux)。WSL2的性能已经很好了,基本可以当原生Linux用。
或者,你也可以用Cygwin或MSYS2,但说实话,体验不如WSL。我早期在Windows上做嵌入式开发,用的是Cygwin,每次配置路径都折腾半天。后来换了WSL,世界清净了。
2.3 目标板与开发板介绍
目标板,就是你最终要运行程序的硬件。开发板,是你用来学习和调试的板子。两者有时候是同一块板子,但概念上要分清。
2.3.1 常见开发板推荐
| 架构 | 推荐开发板 | CPU型号 | 特点 |
|---|---|---|---|
| ARM | 树莓派4B | BCM2711 (Cortex-A72) | 生态最好,资料最多 |
| ARM | STM32MP157 | Cortex-A7 + Cortex-M4 | 双核异构,适合学习 |
| MIPS | Loongson 2K1000 | 龙芯2K1000 | 国产,MIPS64兼容 |
| RISC-V | SiFive HiFive Unmatched | FU740 (U74-MC) | 高性能RISC-V,可跑Linux |
| x86 | Intel NUC | Intel Celeron/Pentium | 小体积,工业级 |
我个人建议,初学者从树莓派入手。为什么?因为遇到问题,网上随便一搜就有答案。我当年学嵌入式,就是从树莓派开始的。那时候还是树莓派2B,512MB内存,跑个Qt程序都卡。但就是那块板子,让我真正理解了交叉编译是怎么回事。
2.3.2 目标板的关键参数
拿到一块目标板,你需要确认以下信息:
- CPU架构:ARM、MIPS、RISC-V还是x86?
- 位数:32位还是64位?
- 字节序:大端还是小端?(MIPS尤其要注意)
- 浮点单元:有没有硬件FPU?是软浮点还是硬浮点?
- 系统库版本:目标板上的glibc版本是多少?
这些信息,决定了你该用哪个交叉编译器。我习惯在目标板上跑一个uname -a和cat /proc/cpuinfo,把信息记下来。然后对照着去选工具链。
-mfloat-abi=soft和-mfloat-abi=hard分别编译,看哪个能在目标板上正常运行。这个方法虽然土,但很管用。
2.4 本章小结
这一章,我们搞清楚了:
- 四种常见嵌入式架构的特点和注意事项
- 宿主机环境怎么准备,Linux和Windows的优劣
- 目标板和开发板的区别,以及如何选择
下一章,我们就要真正动手搭建交叉编译工具链了。到时候,你会用到这一章的所有知识。嗯,做好准备吧。