2. 开发环境搭建:交叉编译工具链安装、TFTP/NFS服务配置、串口终端与Minicom使用

说实话,嵌入式开发的第一步往往最劝退。很多新手拿到开发板,第一反应是“我该先装什么?”

环境没搭好,后面全是坑。我见过太多人花了一周时间,最后发现是工具链版本不对,或者TFTP路径配错了。

这一章,咱们就把这些基础工作一次性搞定。你跟着我的步骤走,别跳步,基本不会出问题。

本章核心目标: 搭建一套完整的BSP开发环境,实现“PC编译 → 网络传输 → 板端运行”的闭环。
嵌入式开发环境整体架构 开发主机 (Ubuntu) 交叉编译工具链 TFTP 服务器 NFS 服务器 Minicom 串口终端 以太网 串口线 目标开发板 U-Boot 引导 Linux 内核 根文件系统 串口控制台 TFTP:传输内核/设备树 NFS:挂载根文件系统 串口:调试信息输出 交互命令输入 注意:IP 需在同一网段

2.1 交叉编译工具链:为什么非它不可?

你想想看,你的PC是x86架构,开发板是ARM架构。PC上编译出来的程序,ARM根本跑不了。

交叉编译工具链,说白了就是一套“在x86上生成ARM可执行文件”的工具。它包含编译器、链接器、库文件等。

我的习惯: 我一般不用发行版自带的工具链(比如 apt install gcc-arm-linux-gnueabihf)。版本太旧,而且有时候会有奇怪的bug。我建议直接从芯片厂商官网下载预编译好的工具链,比如 ARM 官方提供的 gcc-arm-xxx。

安装步骤(以 ARM Cortex-A7 为例)

  1. 下载工具链: 从 ARM 官网或 Linaro 下载 gcc-arm-10.3-2021.07-x86_64-arm-none-linux-gnueabihf.tar.xz
  2. 解压到指定目录:
    mkdir -p ~/toolchain
    cd ~/toolchain
    tar -xJf gcc-arm-10.3-2021.07-x86_64-arm-none-linux-gnueabihf.tar.xz
  3. 配置环境变量:
    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
  4. 验证安装:
    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 移植和内核裁剪工作,都建立在这个基础上。