1. 嵌入式Linux开发环境搭建
嵌入式Linux驱动开发的第一步是构建一个稳定、可复现的宿主机开发环境。本章将系统讲解交叉编译工具链的安装、TFTP/NFS服务器的配置,以及开发板与主机的网络连接方法。这些基础环境是后续驱动编译、下载与调试的基石。
环境概览: 宿主机通常为 x86_64 架构的 Ubuntu 20.04/22.04 LTS,目标板为 ARM Cortex-A 系列(如 i.MX6ULL、STM32MP157)。所有操作均以 root 或具有 sudo 权限的用户执行。
1.1 交叉编译工具链安装
交叉编译是指在宿主机(x86)上编译生成目标板(ARM)可执行代码的过程。工具链包含编译器、链接器、库文件及头文件。
1.1.1 工具链选择与下载
常见工具链来源:
- Linaro GCC: 针对 ARM 架构优化,支持 arm-linux-gnueabihf 和 aarch64-linux-gnu。
- 芯片厂商 SDK: NXP Yocto SDK、ST SDK 等,包含板级 BSP 和专用库。
- Buildroot / Yocto: 可定制生成完整工具链和根文件系统。
| 架构 | 工具链前缀 | 典型版本 | 适用芯片 |
|---|---|---|---|
| ARM 32-bit (v7) | arm-linux-gnueabihf- | gcc-linaro-7.5.0 | i.MX6ULL, STM32MP157 |
| ARM 64-bit (v8) | aarch64-linux-gnu- | gcc-arm-10.3 | Raspberry Pi 4, RK3399 |
| RISC-V 64-bit | riscv64-linux-gnu- | gcc-riscv64-unknown-linux-gnu | K210, D1 |
1.1.2 安装步骤(以 arm-linux-gnueabihf 为例)
- 下载工具链压缩包到
/opt目录。 - 解压并确认目录结构。
- 将工具链的 bin 目录加入系统 PATH。
- 验证安装:编译一个简单的 C 程序。
# 下载 Linaro 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
# 解压到 /opt
sudo tar -xvf gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf.tar.xz -C /opt
# 添加环境变量(写入 ~/.bashrc 或 /etc/profile)
export PATH=$PATH:/opt/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/bin
# 验证
arm-linux-gnueabihf-gcc --version
# 输出应显示 gcc (Linaro GCC 7.5-2019.12) 7.5.0
# 编译测试程序
echo '#include <stdio.h>
int main() { printf("Hello ARM!\n"); return 0; }' > test.c
arm-linux-gnueabihf-gcc -o test_arm test.c
file test_arm
# 输出: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV)
关键检查点: 使用
file 命令确认生成的可执行文件是 ARM 架构,而非 x86 架构。如果显示 x86-64,说明使用了宿主机 gcc,而非交叉编译器。
1.1.3 工具链结构说明
一个完整的交叉工具链包含以下组件:
- bin/ — 编译器、汇编器、链接器(gcc, as, ld, objcopy, objdump)。
- lib/ — 运行时库(libc, libm, libpthread 等)。
- libc/ — 目标板的 C 库头文件和库文件。
- include/ — 目标板内核头文件(用于编译驱动模块)。
1.2 TFTP/NFS 服务器配置
嵌入式开发中,TFTP 用于快速下载内核和设备树到开发板内存,NFS 用于挂载远程根文件系统,实现“无盘启动”和实时调试。
1.2.1 TFTP 服务器安装与配置
TFTP(Trivial File Transfer Protocol)基于 UDP,用于 Bootloader(如 U-Boot)从宿主机下载镜像。
# 安装 TFTP 服务器和客户端
sudo apt update
sudo apt install tftpd-hpa tftp-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 下创建测试文件,从另一终端获取
echo "TFTP Test" | sudo tee /srv/tftp/test.txt
tftp localhost -c get test.txt
cat test.txt
# 应输出 "TFTP Test"
防火墙注意: TFTP 使用 UDP 端口 69。如果宿主机启用了 ufw,请执行
sudo ufw allow 69/udp。开发板侧需确保网络连通性。
1.2.2 NFS 服务器安装与配置
NFS(Network File System)允许开发板将宿主机上的目录挂载为根文件系统,避免每次修改后重新烧写。
# 安装 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
在 /etc/exports 中添加:
/srv/nfs/rootfs *(rw,sync,no_subtree_check,no_root_squash)
参数说明:
*— 允许所有主机访问(生产环境应限制为开发板 IP)。rw— 读写权限。sync— 同步写入,保证数据一致性。no_root_squash— 允许开发板 root 用户保持 root 权限。
# 导出并重启 NFS 服务
sudo exportfs -a
sudo systemctl restart nfs-kernel-server
# 验证导出
showmount -e localhost
# 输出: /srv/nfs/rootfs *
1.2.3 TFTP 与 NFS 工作流程对比
| 特性 | TFTP | NFS |
|---|---|---|
| 协议 | UDP (端口 69) | TCP/UDP (端口 2049) |
| 主要用途 | 下载内核、设备树、uboot 镜像 | 挂载根文件系统、共享应用程序 |
| 传输效率 | 低(无确认重传) | 高(有状态连接) |
| 安全性 | 无认证 | 基于 IP 和导出规则 |
| 典型使用阶段 | U-Boot 启动阶段 | Linux 内核启动后 |
1.3 开发板与主机网络连接
网络连接是 TFTP/NFS 通信的基础。推荐使用静态 IP 配置,避免 DHCP 分配导致地址变化。
1.3.1 网络拓扑与 IP 规划
| 设备 | 接口 | IP 地址 | 子网掩码 | 网关 |
|---|---|---|---|---|
| 宿主机 | eth0 (有线) | 192.168.1.100 | 255.255.255.0 | 192.168.1.1 |
| 开发板 | eth0 | 192.168.1.200 | 255.255.255.0 | 192.168.1.1 |
连接方式: 推荐使用交叉网线直连,或通过交换机/路由器连接。避免使用无线网络,以减少延迟和丢包。
1.3.2 宿主机网络配置
# 查看当前网络接口
ip addr show
# 临时设置静态 IP(以 Ubuntu 为例)
sudo ifconfig eth0 192.168.1.100 netmask 255.255.255.0 up
# 永久配置(编辑 netplan 或 /etc/network/interfaces)
# Ubuntu 18.04+ 使用 netplan
sudo vim /etc/netplan/01-netcfg.yaml
netplan 配置示例:
network:
version: 2
ethernets:
eth0:
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
1.3.3 开发板网络配置(U-Boot 与 Linux)
U-Boot 环境变量设置:
# 进入 U-Boot 命令行,设置网络参数
setenv ipaddr 192.168.1.200
setenv serverip 192.168.1.100
setenv gatewayip 192.168.1.1
setenv netmask 255.255.255.0
saveenv
# 测试网络连通性
ping 192.168.1.100
# 应返回 "host 192.168.1.100 is alive"
Linux 内核启动后网络配置:
# 临时设置 IP
ifconfig eth0 192.168.1.200 netmask 255.255.255.0 up
route add default gw 192.168.1.1
# 永久配置(根据根文件系统类型)
# 对于 Buildroot 或 Yocto,编辑 /etc/network/interfaces
echo "auto eth0" >> /etc/network/interfaces
echo "iface eth0 inet static" >> /etc/network/interfaces
echo " address 192.168.1.200" >> /etc/network/interfaces
echo " netmask 255.255.255.0" >> /etc/network/interfaces
echo " gateway 192.168.1.1" >> /etc/network/interfaces
1.3.4 连通性验证清单
- 物理层: 网口 LED 灯亮起,确认链路正常。
- IP 层: 宿主机 ping 开发板,开发板 ping 宿主机。
- TFTP 层: 开发板 U-Boot 执行
tftp 0x12000000 zImage,观察下载进度。 - NFS 层: 开发板挂载 NFS 目录:
mount -t nfs -o nolock 192.168.1.100:/srv/nfs/rootfs /mnt。
常见故障排查:
- ping 不通:检查网线、防火墙、IP 地址是否在同一网段。
- TFTP 超时:确认 TFTP 服务运行、文件路径正确、权限为 777。
- NFS 挂载失败:检查
/etc/exports语法、showmount -e输出、开发板是否安装 nfs-common。
1.4 本章小结
本章完成了嵌入式 Linux 驱动开发环境的三大核心搭建:
- 交叉编译工具链: 安装并验证了 arm-linux-gnueabihf-gcc,确保能生成 ARM 架构的可执行文件。
- TFTP/NFS 服务器: 配置了 TFTP 用于内核下载,NFS 用于根文件系统挂载,实现了无盘启动和快速迭代。
- 网络连接: 设置了静态 IP,验证了从物理层到应用层的全链路连通性。
下一步: 环境就绪后,即可进入 GPIO 驱动模块的编写与编译。请确保开发板能通过 TFTP 启动内核,并通过 NFS 挂载根文件系统,这是后续所有驱动实验的基础运行环境。