Linux基础与环境搭建:发行版选择、交叉编译工具链安装、TFTP/NFS服务配置
嵌入式开发的第一步,说白了就是搭环境。很多人觉得这事简单,不就是装个系统嘛。但我见过太多项目在环境上栽跟头——工具链版本不对、文件系统挂不上、调试半天发现是网络服务没配好。嗯,咱们这一章就把这些基础打扎实。
2.1 Linux发行版怎么选?
做嵌入式开发,我个人的习惯是优先选 Ubuntu LTS 或 Debian。为什么?社区活跃、包管理成熟、遇到问题搜一下就有答案。
| 发行版 | 适用场景 | 我的建议 |
|---|---|---|
| Ubuntu 20.04/22.04 LTS | 通用嵌入式开发、ARM平台 | 新手首选,资料最多 |
| Debian 11/12 | 服务器、长期稳定项目 | 比Ubuntu更稳,但包略旧 |
| Fedora | 尝鲜、RHEL系开发 | 内核新,但社区支持弱一些 |
| Arch Linux | 极简、定制化需求 | 不推荐新手,滚动更新容易出问题 |
我的经验:如果你用的是国产芯片(全志、瑞芯微、海思),厂商SDK通常基于Ubuntu 18.04或20.04验证。别盲目追新,跟厂商对齐能省很多麻烦。
2.2 交叉编译工具链安装
交叉编译,说白了就是在PC上编译出能在ARM板子上跑的程序。你想想看,板子那么弱,跑个gcc都费劲,怎么可能在上面编译大项目?
2.2.1 工具链的选择
我遇到过三种情况:
- 官方预编译包:ARM官网的gcc-arm-none-eabi,适合裸机或RTOS
- 芯片厂商提供:比如NXP的Linaro GCC、TI的CGT
- 自己用crosstool-NG编译:适合特殊架构或定制需求
我个人最常用的是 Linaro GCC,稳定、更新及时。安装步骤很简单:
# 下载ARM 32位工具链
wget https://releases.linaro.org/components/toolchain/binaries/latest-7/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/
# 添加环境变量
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
避坑指南:我曾经在64位系统上装了32位工具链,结果死活跑不起来。后来发现缺了32位库:
sudo apt install lib32z1 lib32ncurses5。嗯,这个坑我替你们踩过了。
2.2.2 工具链命名规则
你可能会看到一堆名字:arm-linux-gnueabihf、aarch64-linux-gnu、arm-none-eabi……它们到底啥区别?
| 前缀 | 架构 | 操作系统 | ABI | 典型用途 |
|---|---|---|---|---|
| arm-linux-gnueabihf | ARM 32位 | Linux | 硬浮点 | 树莓派、全志H3 |
| aarch64-linux-gnu | ARM 64位 | Linux | 标准 | 树莓派4B、RK3399 |
| arm-none-eabi | ARM 32位 | 无OS | 嵌入式ABI | STM32裸机、FreeRTOS |
| arm-linux-androideabi | ARM 32位 | Android | 嵌入式ABI | Android NDK开发 |
2.3 TFTP服务配置
TFTP这玩意儿,说白了就是个简化版的FTP。嵌入式开发中,它最常用的场景是:通过网络把内核镜像、设备树文件传给U-Boot。你想想看,总不能每次烧写都插拔SD卡吧?
2.3.1 安装与配置
# 安装TFTP服务器
sudo apt install tftpd-hpa
# 创建TFTP根目录
sudo mkdir -p /srv/tftp
sudo chmod 777 /srv/tftp
# 修改配置文件
sudo vim /etc/default/tftpd-hpa
配置文件内容:
TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/srv/tftp"
TFTP_ADDRESS="0.0.0.0:69"
TFTP_OPTIONS="--secure --create"
注意:加上
--create 选项,这样U-Boot就能通过TFTP往服务器写文件了。我在调试内核时经常用这个功能保存日志。
# 重启服务
sudo systemctl restart tftpd-hpa
sudo systemctl enable tftpd-hpa
# 测试:放一个文件进去
echo "hello tftp" > /srv/tftp/test.txt
# 从本机测试下载
tftp localhost -c get test.txt
2.4 NFS服务配置
NFS(网络文件系统)是嵌入式开发中最常用的调试手段。说白了,就是把PC上的一个目录挂载到板子上,板子启动时直接从这个目录加载根文件系统。这样你改代码、编译、重启板子就能看到效果,不用反复烧写。
2.4.1 服务端配置
# 安装NFS服务器
sudo apt install nfs-kernel-server
# 创建共享目录
sudo mkdir -p /srv/nfs/rootfs
sudo chmod 777 /srv/nfs/rootfs
# 编辑导出文件
sudo vim /etc/exports
添加一行:
/srv/nfs/rootfs *(rw,sync,no_subtree_check,no_root_squash)
我曾经踩过的坑:
no_root_squash 这个选项一定要加。不加的话,板子上的root用户会被映射成nobody,很多系统服务就跑不起来了。我当时调试一个udev问题,查了两天才发现是权限映射搞的鬼。
# 重启服务
sudo systemctl restart nfs-kernel-server
# 验证
showmount -e localhost
2.4.2 内核配置支持NFS启动
要让板子从NFS启动,内核必须开启以下选项:
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
CONFIG_NFS_V4=y
CONFIG_ROOT_NFS=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
U-Boot启动参数示例:
setenv bootargs 'console=ttyS0,115200 root=/dev/nfs nfsroot=192.168.1.100:/srv/nfs/rootfs,v3,tcp ip=dhcp'
setenv bootcmd 'tftp 0x42000000 zImage; tftp 0x43000000 imx6ull.dtb; bootz 0x42000000 - 0x43000000'
boot
2.5 整体环境架构
下面这张图,是我做项目时常用的开发环境拓扑。你看一眼就能明白各个服务怎么配合:
2.6 环境验证清单
每次搭建完环境,我都会跑一遍这个清单,确保所有环节都通:
- 工具链验证:编译一个hello world,用
file命令确认是ARM架构 - TFTP验证:从U-Boot用
tftp 0x42000000 zImage下载文件,看速度是否正常 - NFS验证:板子启动后执行
mount,确认根文件系统来自NFS - 串口验证:用Minicom或Putty连接,看内核启动日志是否完整
核心要点:
- 发行版选Ubuntu LTS,跟厂商SDK对齐
- 工具链用Linaro GCC,注意架构和ABI匹配
- TFTP传内核,NFS挂根文件系统,串口看日志
- 每次改环境都要跑一遍验证清单