开发环境搭建:工欲善其事,必先利其器
做嵌入式Linux开发,第一关就是搭环境。我见过太多新手卡在这一步,折腾几天连个Hello World都跑不起来。说白了,环境没搭好,后面全是坑。这一章咱们就把Ubuntu虚拟机、交叉编译工具链、TFTP/NFS服务、串口终端这些基础工具一次性搞定。
2.1 Ubuntu虚拟机安装
我个人习惯用VMware Workstation,当然VirtualBox也行。选哪个不重要,关键是版本要对。我建议用Ubuntu 20.04 LTS或22.04 LTS,这两个版本社区支持好,软件包全,遇到问题容易搜到答案。
安装时注意几点:
- 磁盘空间: 至少分配80GB,别抠门。交叉编译工具链、内核源码、文件系统镜像,随便一放就是几十G。
- 内存: 4GB起步,8GB更舒服。编译内核时内存不够会直接OOM(Out Of Memory),我吃过这个亏。
- CPU核心: 给2-4核,编译能快不少。
- 网络模式: 选桥接模式,这样开发板和虚拟机能在同一网段,方便后续NFS和TFTP通信。
sudo apt update && sudo apt upgrade -y 把系统更新到最新。然后装个 build-essential 和 vim,这是最基本的开发工具包。
2.2 交叉编译工具链配置
交叉编译,说白了就是在x86的电脑上编译出ARM架构能跑的二进制文件。你想想看,开发板那点算力,编译个Linux内核得等到猴年马月?所以必须在PC上搞定。
工具链的选择,我推荐两种:
| 类型 | 来源 | 适用场景 |
|---|---|---|
| Linaro GCC | 官方发布包 | 通用ARM Cortex-A系列,社区支持好 |
| Buildroot / Yocto | 源码构建 | 定制化需求,需要精确控制库版本 |
这里我以Linaro GCC 7.5.0为例,演示安装步骤:
# 下载工具链
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
# 解压到指定目录
tar -xvf gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf.tar.xz -C /opt/
# 配置环境变量(写入 ~/.bashrc)
export PATH=/opt/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/bin:$PATH
export ARCH=arm
export CROSS_COMPILE=arm-linux-gnueabihf-
# 使环境变量生效
source ~/.bashrc
# 验证安装
arm-linux-gnueabihf-gcc --version
sudo apt install lib32z1 lib32ncurses5 才解决。另外,环境变量一定要写到 ~/.bashrc 里,别只写在当前终端,否则新开窗口又得重新配。
2.3 TFTP/NFS服务搭建
这两个服务是嵌入式开发的「快递员」。TFTP负责把内核、设备树文件传给开发板,NFS则让开发板直接挂载PC上的文件系统,方便调试。
2.3.1 TFTP服务
TFTP简单粗暴,适合传小文件。配置步骤如下:
# 安装TFTP服务
sudo apt install tftpd-hpa tftp-hpa
# 创建TFTP根目录
sudo mkdir -p /tftpboot
sudo chmod 777 /tftpboot
# 修改配置文件 /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
测试方法:在 /tftpboot 下放个文件,然后在开发板uboot里执行 tftp 0x82000000 zImage,能下载成功就说明通了。
2.3.2 NFS服务
NFS比TFTP高级,开发板可以直接读写PC上的文件,调试应用程序时特别方便。我习惯把根文件系统放在NFS共享目录里,开发板启动时直接挂载。
# 安装NFS服务
sudo apt install nfs-kernel-server
# 创建共享目录
sudo mkdir -p /srv/nfs/rootfs
sudo chmod 777 /srv/nfs/rootfs
# 编辑 /etc/exports,添加共享配置
/srv/nfs/rootfs *(rw,sync,no_subtree_check,no_root_squash)
# 重启NFS服务
sudo systemctl restart nfs-kernel-server
sudo exportfs -av
no_root_squash 这个参数很重要。不加的话,开发板上的root用户会被映射成nobody,写文件时权限会出问题。我在项目里遇到过,排查了半天才发现是这儿的坑。
2.4 串口终端工具使用
串口是嵌入式开发者的「眼睛」。开发板没网口、没显示器的时候,全靠串口看启动日志、敲命令。我常用的工具有三个:
| 工具 | 特点 | 推荐场景 |
|---|---|---|
| minicom | 经典、稳定、配置稍复杂 | 日常调试,习惯命令行 |
| screen | 轻量、无需配置 | 快速连接,临时用一下 |
| MobaXterm | 图形化、支持多标签 | Windows用户,功能全面 |
这里我重点讲minicom,因为它是Linux下最正统的串口工具:
# 安装minicom
sudo apt install minicom
# 首次配置
sudo minicom -s
# 进入配置菜单后,选择 "Serial port setup"
# 关键参数设置:
# A - Serial Device: /dev/ttyUSB0 (根据实际设备修改)
# B - Lockfile Location: /var/lock
# E - Bps/Par/Bits: 115200 8N1
# F - Hardware Flow Control: No
# G - Software Flow Control: No
# 保存为默认配置
# 选择 "Save setup as dfl"
# 启动连接
sudo minicom
ls -l /dev/ttyUSB* 看设备是否存在。如果权限不够,把当前用户加到dialout组:sudo usermod -a -G dialout $USER,然后注销重新登录。我曾经忘了加组,折腾了半小时才发现是权限问题。
2.5 整体环境验证
所有服务搭好后,我习惯画一张图来理清它们之间的关系。你看下面这张图就明白了:
从这张图能看出来,整个环境是分层协作的:
- 编译阶段: 在宿主机上用交叉编译工具链生成内核、设备树、应用程序
- 传输阶段: TFTP把内核和设备树传给开发板,NFS提供文件系统
- 调试阶段: 串口终端实时查看启动日志,发现问题随时修改
- 交叉编译工具链能正常编译Hello World
- 开发板通过TFTP能下载内核镜像
- 开发板通过NFS能挂载根文件系统
- 串口终端能正常显示uboot和内核启动日志
嗯,到这里开发环境就全部就绪了。这些工具看着琐碎,但每一个都是后面章节的基础。你花半天时间把环境搭扎实,后面编译内核、移植驱动时会顺畅得多。我当年第一次搭环境时也踩了不少坑,但一旦跑通了,那种成就感还是很爽的。