2. 开发环境搭建:交叉编译工具链安装、TFTP/NFS服务配置、串口终端与Minicom使用
说实话,嵌入式开发的第一步往往最劝退。很多新手拿到开发板,第一反应是“我该先装什么?”
环境没搭好,后面全是坑。我见过太多人花了一周时间,最后发现是工具链版本不对,或者TFTP路径配错了。
这一章,咱们就把这些基础工作一次性搞定。你跟着我的步骤走,别跳步,基本不会出问题。
本章核心目标: 搭建一套完整的BSP开发环境,实现“PC编译 → 网络传输 → 板端运行”的闭环。
2.1 交叉编译工具链:为什么非它不可?
你想想看,你的PC是x86架构,开发板是ARM架构。PC上编译出来的程序,ARM根本跑不了。
交叉编译工具链,说白了就是一套“在x86上生成ARM可执行文件”的工具。它包含编译器、链接器、库文件等。
我的习惯: 我一般不用发行版自带的工具链(比如 apt install gcc-arm-linux-gnueabihf)。版本太旧,而且有时候会有奇怪的bug。我建议直接从芯片厂商官网下载预编译好的工具链,比如 ARM 官方提供的 gcc-arm-xxx。
安装步骤(以 ARM Cortex-A7 为例)
- 下载工具链: 从 ARM 官网或 Linaro 下载
gcc-arm-10.3-2021.07-x86_64-arm-none-linux-gnueabihf.tar.xz - 解压到指定目录:
mkdir -p ~/toolchain cd ~/toolchain tar -xJf gcc-arm-10.3-2021.07-x86_64-arm-none-linux-gnueabihf.tar.xz - 配置环境变量:
export PATH=$PATH:~/toolchain/gcc-arm-10.3-2021.07-x86_64-arm-none-linux-gnueabihf/bin export CROSS_COMPILE=arm-none-linux-gnueabihf- export ARCH=arm - 验证安装:
arm-none-linux-gnueabihf-gcc --version # 输出类似:arm-none-linux-gnueabihf-gcc (GNU Toolchain) 10.3.1 20210621
我曾经踩过的坑: 环境变量只写在当前终端,一关窗口就没了。一定要把 export 命令加到
~/.bashrc 或 ~/.profile 里,然后 source ~/.bashrc 让它永久生效。
2.2 TFTP 服务:快速把内核和设备树传给开发板
TFTP 是个轻量级的文件传输协议。它没有认证,没有加密,但胜在简单、快。U-Boot 里内置了 TFTP 客户端,可以直接从服务器下载文件。
安装与配置
# 安装 TFTP 服务器
sudo apt update
sudo apt install tftpd-hpa
# 创建 TFTP 根目录
sudo mkdir -p /srv/tftp
sudo chmod 777 /srv/tftp
# 修改配置文件 /etc/default/tftpd-hpa
sudo vim /etc/default/tftpd-hpa
配置文件内容如下:
TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/srv/tftp"
TFTP_ADDRESS="0.0.0.0:69"
TFTP_OPTIONS="--secure --create"
重启服务:
sudo systemctl restart tftpd-hpa
sudo systemctl enable tftpd-hpa
验证方法: 在
/srv/tftp 下放一个测试文件,然后在开发板的 U-Boot 里执行 tftp 0x80800000 test.txt。如果能下载成功,说明 TFTP 通了。
2.3 NFS 服务:让开发板共享主机的文件系统
NFS 比 TFTP 高级多了。它可以让开发板直接挂载主机上的一个目录,当作自己的根文件系统来用。开发阶段特别方便——改完代码,重新编译,开发板重启就能看到新文件,不用反复烧写。
安装与配置
# 安装 NFS 服务器
sudo apt install nfs-kernel-server
# 创建共享目录
sudo mkdir -p /srv/nfs/rootfs
sudo chmod 777 /srv/nfs/rootfs
# 编辑 /etc/exports
sudo vim /etc/exports
添加一行:
/srv/nfs/rootfs *(rw,sync,no_subtree_check,no_root_squash)
应用配置:
sudo exportfs -a
sudo systemctl restart nfs-kernel-server
注意:
no_root_squash 这个选项很重要。如果不加,开发板上的 root 用户会被映射成 nobody,导致很多操作权限不足。我在项目里吃过这个亏,调试了一下午才发现是权限问题。
2.4 串口终端与 Minicom:和开发板“对话”
开发板刚上电,没有网络,没有显示器。你怎么跟它交互?
靠串口。串口是嵌入式开发者的“眼睛”和“嘴巴”。U-Boot 的启动信息、内核的打印日志、Shell 的交互命令,全走串口。
硬件连接
| 开发板接口 | USB 转串口模块 | 说明 |
|---|---|---|
| TXD | RXD | 交叉连接 |
| RXD | TXD | 交叉连接 |
| GND | GND | 共地,必须接 |
| VCC | (不接) | 开发板自供电,不需要 |
Minicom 安装与配置
# 安装 Minicom
sudo apt install minicom
# 查看串口设备
ls -l /dev/ttyUSB* # 通常是 ttyUSB0 或 ttyACM0
# 配置 Minicom
sudo minicom -s
进入配置菜单后,选择 Serial port setup,设置以下参数:
- Serial Device:
/dev/ttyUSB0(根据实际情况修改) - Bps/Par/Bits:
115200 8N1(波特率 115200,无校验,8 数据位,1 停止位) - Hardware Flow Control:
No - Software Flow Control:
No
保存为默认配置(Save setup as dfl),然后退出。
我的小技巧: 如果 Minicom 显示乱码,多半是波特率不对。如果完全没有输出,检查一下串口线有没有接反,或者是不是权限问题(把当前用户加到 dialout 组:
sudo usermod -a -G dialout $USER)。
2.5 环境验证:跑一个“Hello World”
工具装完了,怎么知道好不好使?写个最简单的程序,交叉编译,传到开发板上跑一下。
// hello.c
#include <stdio.h>
int main()
{
printf("Hello from ARM!\n");
return 0;
}
编译:
arm-none-linux-gnueabihf-gcc -o hello hello.c
把生成的 hello 文件放到 TFTP 目录:
cp hello /srv/tftp/
在开发板的 U-Boot 里下载并执行:
# 在 U-Boot 命令行
tftp 0x80800000 hello
go 0x80800000
如果串口输出 Hello from ARM!,恭喜你,环境搭建成功!
总结一下: 交叉编译工具链负责“造”,TFTP 负责“传”,NFS 负责“挂”,串口负责“看”。这四个东西配合起来,就是嵌入式开发的“四件套”。后面所有的 BSP 移植和内核裁剪工作,都建立在这个基础上。