2. 开发环境搭建:交叉编译工具链安装、TFTP/NFS服务配置、串口终端工具使用、虚拟机与开发板网络配置
说实话,嵌入式Linux开发的第一步,往往是最劝退的。我记得刚入行那会儿,光搭环境就折腾了整整两天——工具链版本不对、网络死活ping不通、串口乱码……嗯,这些坑我基本都踩过。这一章,我把这些年积累的「标准操作」和「避坑经验」一起给你,照着做,能省不少时间。
2.1 交叉编译工具链安装
交叉编译,说白了就是在你的x86电脑上编译出能在ARM开发板上运行的代码。为什么不能直接在开发板上编译?你想想看,开发板的CPU性能、内存、存储都有限,编译个Linux内核可能要几个小时,而在PC上只要十几分钟。
2.1.1 工具链的选择
我个人习惯用Linaro提供的GCC工具链,稳定且社区活跃。针对不同的ARM架构,选择也不同:
| 目标架构 | 工具链前缀 | 典型应用 |
|---|---|---|
| ARM Cortex-A7/A8 | arm-linux-gnueabihf- | 全志、瑞芯微入门级芯片 |
| ARM Cortex-A53/A72 | aarch64-linux-gnu- | 树莓派3/4、RK3399等64位芯片 |
| ARM Cortex-M系列 | arm-none-eabi- | 裸机或RTOS开发(非Linux) |
2.1.2 安装步骤
以Ubuntu 20.04为例,安装Linaro 7.5版本的工具链:
# 下载工具链(约200MB)
wget https://releases.linaro.org/components/toolchain/binaries/7.5-2019.12/arm-linux-gnueabihf/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf.tar.xz
# 解压到 /opt 目录
sudo tar -xvf gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf.tar.xz -C /opt/
# 添加环境变量(写入 ~/.bashrc)
echo 'export PATH=$PATH:/opt/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/bin' >> ~/.bashrc
source ~/.bashrc
# 验证安装
arm-linux-gnueabihf-gcc --version
输出类似下面这样,就说明装好了:
arm-linux-gnueabihf-gcc (Linaro GCC 7.5-2019.12) 7.5.0
Copyright (C) 2017 Free Software Foundation, Inc.
2.2 TFTP/NFS服务配置
开发阶段,你不可能每次修改代码都重新烧写整个系统。TFTP和NFS就是用来解决这个问题的——TFTP传内核和设备树,NFS挂载根文件系统。这样你改完代码,重启开发板就能看到效果。
2.2.1 TFTP服务器配置
TFTP(Trivial File Transfer Protocol)是个轻量级的文件传输协议,专门用来在开发阶段快速传输内核镜像(uImage/zImage)和设备树文件(.dtb)。
# 安装TFTP服务器
sudo apt-get install tftpd-hpa
# 创建TFTP根目录
sudo mkdir -p /tftpboot
sudo chmod 777 /tftpboot
# 修改配置文件 /etc/default/tftpd-hpa
sudo vim /etc/default/tftpd-hpa
配置文件内容:
TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/tftpboot"
TFTP_ADDRESS="0.0.0.0:69"
TFTP_OPTIONS="-l -c -s"
重启服务并测试:
sudo systemctl restart tftpd-hpa
sudo systemctl enable tftpd-hpa
# 本地测试
echo "test" > /tftpboot/test.txt
tftp localhost
tftp> get test.txt
tftp> quit
2.2.2 NFS服务器配置
NFS(Network File System)可以把开发板上的根文件系统「映射」到虚拟机的一个目录里。开发板上电后,直接从网络加载根文件系统,所有修改实时生效。
# 安装NFS服务器
sudo apt-get install nfs-kernel-server
# 创建共享目录(假设你的根文件系统在 /home/embedded/rootfs)
sudo mkdir -p /home/embedded/rootfs
# 修改 /etc/exports 文件
sudo vim /etc/exports
添加一行:
/home/embedded/rootfs *(rw,sync,no_root_squash,no_subtree_check)
参数说明:
| 参数 | 含义 |
|---|---|
| rw | 可读写 |
| sync | 同步写入,保证数据一致性 |
| no_root_squash | 允许开发板以root权限访问,否则会映射成nobody用户 |
| no_subtree_check | 禁用子树检查,提高性能 |
# 重启NFS服务
sudo systemctl restart nfs-kernel-server
# 本地验证
sudo mount -t nfs localhost:/home/embedded/rootfs /mnt
ls /mnt
sudo umount /mnt
2.3 串口终端工具使用
串口是嵌入式开发中最基础的调试手段。开发板没有显示器、没有键盘,串口就是你和它沟通的唯一窗口。我个人最常用的是 minicom 和 screen,简单可靠。
2.3.1 安装和配置 minicom
# 安装
sudo apt-get install minicom
# 配置(第一次运行需要设置)
sudo minicom -s
进入配置菜单后,选择「Serial port setup」,设置以下参数:
| 参数 | 典型值 | 说明 |
|---|---|---|
| Serial Device | /dev/ttyUSB0 | USB转串口设备,也可能是 ttyS0 或 ttyACM0 |
| Bps/Par/Bits | 115200 8N1 | 波特率115200,8数据位,无校验,1停止位 |
| Hardware Flow Control | No | 关闭硬件流控 |
| Software Flow Control | No | 关闭软件流控 |
设置完成后,选择「Save setup as dfl」保存为默认配置,然后退出。下次直接运行 sudo minicom 即可。
2.3.2 使用 screen 作为轻量替代
如果你不想装 minicom,screen 也能干这活:
# 安装
sudo apt-get install screen
# 连接串口(波特率115200)
sudo screen /dev/ttyUSB0 115200
# 退出:按 Ctrl+A,然后按 K,再按 Y 确认
2.3.3 常见问题排查
- 找不到 /dev/ttyUSB0:检查USB转串口驱动是否安装,运行
lsusb查看设备是否识别。 - 乱码:波特率不匹配。开发板一般是115200,但也有用57600或9600的,看板子手册。
- 权限问题:把当前用户加入 dialout 组:
sudo usermod -a -G dialout $USER,然后注销重新登录。
2.4 虚拟机与开发板网络配置
网络配置是整个环境搭建中最容易出问题的一环。TFTP、NFS、SSH都依赖网络,网络不通,后面全白搭。我见过太多人卡在这一步了。
2.4.1 网络拓扑
先搞清楚我们要搭什么样的网络:
2.4.2 虚拟机网络模式选择
VMware或VirtualBox有三种网络模式,我直接说结论:
| 模式 | 适用场景 | 缺点 |
|---|---|---|
| 桥接模式 | 推荐。虚拟机直接接入物理网络,和开发板在同一网段 | 占用一个局域网IP |
| NAT模式 | 虚拟机可以上网,但外部无法访问虚拟机 | 开发板无法连接虚拟机,不适合嵌入式开发 |
| 仅主机模式 | 虚拟机与宿主机通信,不连外网 | 需要额外配置,开发板无法直接访问 |
2.4.3 配置步骤
以VirtualBox为例,设置桥接网络:
- 关闭虚拟机。
- 在VirtualBox管理界面,选中虚拟机 → 设置 → 网络。
- 「连接方式」选择「桥接网卡」。
- 「界面名称」选择你宿主机连路由器的网卡(通常是有线或WiFi)。
- 启动虚拟机,在Ubuntu中配置静态IP。
# 编辑网络配置文件(Ubuntu 20.04用netplan)
sudo vim /etc/netplan/01-netcfg.yaml
内容如下:
network:
version: 2
ethernets:
enp0s3:
dhcp4: no
addresses:
- 192.168.1.100/24
gateway4: 192.168.1.1
nameservers:
addresses: [8.8.8.8, 114.114.114.114]
# 应用配置
sudo netplan apply
# 验证
ip addr show enp0s3
ping 192.168.1.1 # 测试网关
ping 8.8.8.8 # 测试外网
2.4.4 开发板网络配置
开发板通常在U-Boot阶段设置IP,然后传给Linux内核。以常见的全志芯片为例:
# 在U-Boot命令行中设置
setenv ipaddr 192.168.1.200
setenv serverip 192.168.1.100 # 虚拟机的IP
setenv gatewayip 192.168.1.1
setenv netmask 255.255.255.0
saveenv
# 测试网络连通性
ping 192.168.1.100
如果ping通,说明网络配置成功。这时候你就可以用TFTP下载内核了:
# 从虚拟机下载内核镜像
tftp 0x42000000 zImage
tftp 0x43000000 sunxi.dtb
2.5 环境验证
所有配置完成后,做一次完整的验证,确保每个环节都正常:
- 工具链验证:编译一个Hello World程序,放到开发板上运行。
- TFTP验证:在开发板U-Boot中通过TFTP下载文件。
- NFS验证:开发板挂载虚拟机的NFS共享目录,读写文件。
- 串口验证:通过串口终端能看到开发板的启动日志和命令行。
- 网络验证:虚拟机与开发板互相ping通。
这五个验证都通过,你的开发环境就算搭好了。后面写驱动、编译内核、调试应用,都会顺畅很多。