3. 开发环境搭建
嵌入式Linux开发与桌面应用开发最大的区别在于:代码在主机上编译,程序在目标板上运行,两者通过串口和网络协同工作。因此,开发环境不是"装个IDE"那么简单,而是一套由主机、交叉工具链、串口通道、网络通道、TFTP与NFS服务共同组成的协作体系。本章按搭建顺序逐一说明,并给出可直接复用的验证方法。
一、主机环境选择:为什么优先用Ubuntu LTS
主机(Host)承担编译、烧写、调试和服务提供四类任务。选择主机时主要看三点:软件包生态、内核与驱动支持、社区资料丰富度。综合来看,Ubuntu LTS(如20.04/22.04)是嵌入式Linux开发的首选,其次是Debian和Fedora。
- 软件包齐全:交叉编译器、QEMU、minicom、tftp-hpa、nfs-kernel-server等均可通过apt直接安装。
- 版本稳定:LTS版本维护周期长,避免因发行版升级导致工具链行为变化。
- 权限与串口友好:通过dialout组即可让普通用户访问串口,无需长期使用root。
二、交叉工具链安装与验证
交叉工具链(Cross Toolchain)是运行在x86主机上、却能生成ARM/MIPS/RISC-V目标代码的编译器集合。它通常包含gcc、g++、binutils、glibc/uClibc、gdb等。安装方式有两种:使用发行版包管理器安装,或使用芯片厂商提供的预编译工具链。
# 方式一:apt安装(以ARM 32位为例)
sudo apt update
sudo apt install gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf
# 方式二:厂商工具链(解压后加入PATH)
tar -xvf gcc-arm-10.3-2021.07-x86_64-arm-none-linux-gnueabihf.tar.xz
export PATH=$PATH:/opt/toolchain/bin
安装完成后必须验证,验证的核心是"能否正确编译并识别目标架构":
arm-linux-gnueabihf-gcc -v
# 输出中应包含 Target: arm-linux-gnueabihf
echo 'int main(){return 0;}' > test.c
arm-linux-gnueabihf-gcc test.c -o test
file test
# 期望输出:ELF 32-bit LSB executable, ARM, EABI5 ...
gcc -v看到版本号就认为工具链可用。必须用file确认生成的是ARM架构ELF,而不是x86_64。若输出x86_64,说明PATH中仍是主机gcc,交叉前缀写错了。三、串口与网络连接
串口是目标板的"生命线",用于查看U-Boot和内核启动日志、进入命令行。主机侧常用工具是minicom或picocom。连接前先用dmesg | grep tty确认设备节点,如/dev/ttyUSB0。
sudo usermod -aG dialout $USER # 加入串口组,重新登录生效
sudo chmod 666 /dev/ttyUSB0 # 临时授权
picocom -b 115200 /dev/ttyUSB0 # 常见波特率115200
网络连接方面,目标板通常通过以太网与主机相连。主机需配置与目标板同网段的静态IP,例如主机192.168.1.100,目标板192.168.1.10。验证命令为ping,方向应双向可达。
# 主机侧
sudo ip addr add 192.168.1.100/24 dev eth0
ping 192.168.1.10
# 目标板侧(串口终端中)
ifconfig eth0 192.168.1.10 netmask 255.255.255.0 up
ping 192.168.1.100
四、TFTP与NFS服务配置
TFTP用于传输单个文件,典型场景是把内核镜像zImage和设备树dtb下载到目标板内存;NFS用于挂载根文件系统,让目标板直接使用主机上的目录,避免反复烧写。两者配合,可形成"内核走TFTP、根文件系统走NFS"的高效调试模式。
# 安装服务
sudo apt install tftp-hpa tftpd-hpa nfs-kernel-server
# 配置TFTP根目录
sudo mkdir -p /srv/tftp && sudo chmod 777 /srv/tftp
# /etc/default/tftpd-hpa
TFTP_DIRECTORY="/srv/tftp"
TFTP_OPTIONS="--secure --create"
# 配置NFS导出
# /etc/exports
/srv/nfsroot 192.168.1.0/24(rw,sync,no_root_squash,no_subtree_check)
sudo systemctl restart tftpd-hpa nfs-kernel-server
sudo exportfs -ra
目标板侧通过U-Boot命令使用这两个服务:
setenv serverip 192.168.1.100
setenv ipaddr 192.168.1.10
tftp 0x80800000 zImage
tftp 0x83000000 exynos4412.dtb
setenv bootargs root=/dev/nfs nfsroot=192.168.1.100:/srv/nfsroot ip=192.168.1.10
bootz 0x80800000 - 0x83000000
下表汇总了本节各环节的关键验证点,建议逐项打勾确认:
| 环节 | 关键命令/配置 | 通过标准 |
|---|---|---|
| 工具链 | arm-linux-gnueabihf-gcc -v | Target为arm,file显示ARM ELF |
| 串口 | picocom -b 115200 /dev/ttyUSB0 | 能看到U-Boot/内核日志 |
| 网络 | ping 双向测试 | 主机与目标板互ping通 |
| TFTP | tftp 0x80800000 zImage | 显示Bytes transferred |
| NFS | showmount -e 192.168.1.100 | 列出/srv/nfsroot |
五、典型排障与复盘
环境搭建阶段的问题高度集中,掌握以下排查路径可节省大量时间:
- 串口无输出:先确认波特率、数据位、停止位(115200-8-N-1),再确认TX/RX是否交叉连接,最后检查目标板是否真的上电启动。
- TFTP超时:检查防火墙
sudo ufw status、服务是否监听69端口ss -lunp | grep 69、文件权限是否为可读。 - NFS挂载失败:确认
/etc/exports网段与目标板IP一致,执行exportfs -ra后重启服务;内核需已编译NFS客户端支持。 - 工具链找不到库:检查
--sysroot是否指向工具链自带的根目录,避免误用主机/usr/lib。
完成以上配置后,主机与目标板之间就形成了稳定的开发闭环:在主机上编译,通过TFTP快速更新内核,通过NFS实时共享根文件系统,通过串口观察运行状态。这套环境是后续所有章节实验的基础,建议在进入内核裁剪与驱动开发前,反复验证并记录每一步的输出结果。