2. 开发环境搭建:Linux主机环境、交叉编译工具链安装、T113 SDK获取与编译、TFTP/NFS网络启动配置
嵌入式Linux驱动开发的第一步是构建一个稳定、可复现的开发环境。本章将指导你从零搭建全志T113的完整开发栈,涵盖主机环境配置、交叉编译工具链安装、SDK获取与编译,以及TFTP/NFS网络启动的配置。一个标准化的环境能大幅减少后续调试中的“环境问题”,让你专注于驱动逻辑本身。
环境概览: 主机使用 Ubuntu 22.04 LTS (x86_64),目标板为全志T113-S3。所有操作均在普通用户下执行,必要时使用 sudo 提权。
2.1 Linux主机环境准备
主机环境是开发的“母体”,需要安装必要的系统工具和依赖库。以下步骤在全新安装的 Ubuntu 22.04 上验证通过。
2.1.1 基础依赖安装
# 更新软件源
sudo apt update && sudo apt upgrade -y
# 安装编译工具与库
sudo apt install -y \
build-essential \
git \
vim \
curl \
wget \
unzip \
python3 \
python3-pip \
python3-dev \
libncurses5-dev \
libncursesw5-dev \
libssl-dev \
libgmp-dev \
libmpfr-dev \
libmpc-dev \
flex \
bison \
bc \
kmod \
cpio \
rsync \
u-boot-tools \
device-tree-compiler \
tftp-hpa \
tftpd-hpa \
nfs-kernel-server \
net-tools
关键说明: libncurses5-dev 用于内核 menuconfig 图形配置;device-tree-compiler (dtc) 用于编译设备树;tftp-hpa 和 nfs-kernel-server 用于网络启动。
2.1.2 主机网络与TFTP/NFS目录规划
为后续网络启动做准备,建议在主机上建立统一的共享目录结构:
# 创建 TFTP 根目录(用于存放内核、设备树)
sudo mkdir -p /srv/tftp
sudo chmod 777 /srv/tftp
# 创建 NFS 根目录(用于存放根文件系统)
sudo mkdir -p /srv/nfs/rootfs
sudo chmod 777 /srv/nfs/rootfs
权限注意: 开发阶段将目录权限设为 777 可避免权限问题,生产环境应使用更严格的权限控制。
2.2 交叉编译工具链安装
T113 基于 ARM Cortex-A7 内核,需要使用 ARM 交叉编译工具链。全志官方 SDK 通常自带工具链,但为了灵活性和版本可控,推荐单独安装 Linaro 或 ARM 官方工具链。
2.2.1 工具链选择与下载
| 工具链名称 | 架构 | GCC版本 | 适用场景 |
|---|---|---|---|
| arm-linux-gnueabihf | ARMv7-A (硬浮点) | 12.3 | Linux 内核、驱动、应用 |
| arm-none-linux-gnueabihf | ARMv7-A (硬浮点) | 13.2 | 裸机、U-Boot、Trusted Firmware |
推荐使用 ARM 官方提供的预编译工具链:
# 下载 arm-linux-gnueabihf 工具链(以12.3版本为例)
wget https://developer.arm.com/-/media/Files/downloads/gnu/12.3.rel1/binrel/arm-gnu-toolchain-12.3.rel1-x86_64-arm-none-linux-gnueabihf.tar.xz
# 解压到 /opt 目录
sudo tar -xf arm-gnu-toolchain-12.3.rel1-x86_64-arm-none-linux-gnueabihf.tar.xz -C /opt/
sudo mv /opt/arm-gnu-toolchain-12.3.rel1-x86_64-arm-none-linux-gnueabihf /opt/arm-gnu-toolchain
# 添加环境变量(写入 ~/.bashrc)
echo 'export PATH=$PATH:/opt/arm-gnu-toolchain/bin' >> ~/.bashrc
source ~/.bashrc
# 验证安装
arm-none-linux-gnueabihf-gcc --version
验证输出示例: arm-none-linux-gnueabihf-gcc (GNU Toolchain for the Arm Architecture) 12.3.rel1
2.2.2 工具链架构验证
编译一个简单的测试程序,确认工具链能正确生成 ARM 可执行文件:
# 编写测试代码
echo '#include <stdio.h>
int main() { printf("Hello T113!\n"); return 0; }' > test.c
# 交叉编译
arm-none-linux-gnueabihf-gcc -o test_arm test.c
# 查看文件类型
file test_arm
# 输出应为:ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3
架构确认: 输出中必须包含 “ARM” 和 “ARM EABI5”,且 interpreter 路径指向 armhf 动态链接器,表明工具链正确。
2.3 T113 SDK获取与编译
全志T113的官方SDK通常包含U-Boot、Linux内核、设备树、根文件系统构建脚本。SDK可从全志官方Git仓库或合作伙伴渠道获取。
2.3.1 SDK获取
以全志官方发布的 t113-s3_linux_sdk_v1.0 为例:
# 克隆SDK仓库(假设已获得访问权限)
git clone https://github.com/allwinner-zh/t113-s3_linux_sdk.git
cd t113-s3_linux_sdk
# 查看SDK目录结构
ls -la
# 典型结构:
# ├── build/ # 构建脚本
# ├── kernel/ # Linux内核源码
# ├── u-boot/ # U-Boot源码
# ├── device/ # 设备树与板级配置
# ├── tools/ # 打包工具
# └── rootfs/ # 根文件系统构建
2.3.2 SDK编译流程
SDK编译分为三个主要阶段:U-Boot、内核、根文件系统。以下为完整编译命令:
# 1. 设置环境变量(指定工具链路径)
export CROSS_COMPILE=arm-none-linux-gnueabihf-
export ARCH=arm
# 2. 编译U-Boot
cd u-boot
make t113_s3_defconfig
make -j$(nproc)
# 生成文件:u-boot-sunxi-with-spl.bin
# 3. 编译Linux内核
cd ../kernel
make t113_s3_defconfig
make -j$(nproc)
# 生成文件:arch/arm/boot/zImage
# 设备树:arch/arm/boot/dts/sun8i-t113-s3.dtb
# 4. 构建根文件系统(使用buildroot)
cd ../build
make t113_s3_defconfig
make -j$(nproc)
# 生成文件:output/images/rootfs.ext4
编译常见问题: 若编译过程中出现 “/bin/sh: 1: bison: not found” 等错误,请返回 2.1.1 节检查依赖是否完整安装。建议使用
make -j$(nproc) 2>&1 | tee build.log 记录日志以便排查。
2.3.3 编译产物清单
| 产物文件 | 路径 | 用途 |
|---|---|---|
| u-boot-sunxi-with-spl.bin | u-boot/ | 启动引导程序(含SPL) |
| zImage | kernel/arch/arm/boot/ | 压缩后的Linux内核镜像 |
| sun8i-t113-s3.dtb | kernel/arch/arm/boot/dts/ | 设备树二进制文件 |
| rootfs.ext4 | build/output/images/ | 根文件系统镜像(ext4格式) |
2.4 TFTP/NFS网络启动配置
网络启动是嵌入式开发中最常用的调试方式,通过TFTP加载内核和设备树,通过NFS挂载根文件系统,实现“修改-编译-重启”的快速迭代。
2.4.1 TFTP服务器配置
# 编辑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"
# 重启TFTP服务
sudo systemctl restart tftpd-hpa
sudo systemctl enable tftpd-hpa
# 将编译产物复制到TFTP目录
sudo cp kernel/arch/arm/boot/zImage /srv/tftp/
sudo cp kernel/arch/arm/boot/dts/sun8i-t113-s3.dtb /srv/tftp/
2.4.2 NFS服务器配置
# 编辑NFS导出文件
sudo vim /etc/exports
# 添加以下行(允许开发板所在网段访问)
/srv/nfs/rootfs 192.168.1.0/24(rw,sync,no_subtree_check,no_root_squash)
# 重启NFS服务
sudo systemctl restart nfs-kernel-server
sudo systemctl enable nfs-kernel-server
# 将根文件系统解压到NFS目录
sudo tar -xf build/output/images/rootfs.ext4 -C /srv/nfs/rootfs/
# 或挂载ext4镜像后复制
sudo mount -o loop build/output/images/rootfs.ext4 /mnt
sudo cp -a /mnt/* /srv/nfs/rootfs/
sudo umount /mnt
网络规划建议: 主机IP建议固定为 192.168.1.100,开发板IP建议固定为 192.168.1.200。使用网线直连或同一交换机,避免WiFi干扰。
2.4.3 U-Boot网络启动参数设置
在开发板串口终端中,进入U-Boot命令行,设置以下环境变量:
# 设置IP地址
setenv ipaddr 192.168.1.200
setenv serverip 192.168.1.100
# 设置TFTP加载地址与文件
setenv loadaddr 0x42000000
setenv fdtaddr 0x43000000
setenv bootfile zImage
setenv fdtfile sun8i-t113-s3.dtb
# 设置NFS根文件系统参数
setenv rootpath /srv/nfs/rootfs
setenv nfsargs 'setenv bootargs console=ttyS0,115200 root=/dev/nfs nfsroot=${serverip}:${rootpath},v3,tcp ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:t113:eth0:off'
# 组合启动命令
setenv bootcmd 'tftp ${loadaddr} ${bootfile}; tftp ${fdtaddr} ${fdtfile}; run nfsargs; bootz ${loadaddr} - ${fdtaddr}'
# 保存环境变量
saveenv
# 执行启动
boot
启动流程说明: U-Boot先通过TFTP从主机下载zImage和dtb文件到内存,然后设置内核启动参数(bootargs)指定NFS根文件系统,最后执行bootz命令启动内核。
2.5 开发环境架构总览
以下SVG图展示了主机与开发板之间的完整交互流程,包括编译、传输、启动三个环节:
2.6 环境验证清单
完成上述配置后,建议按以下清单逐项验证,确保环境可用:
| 验证项 | 验证方法 | 预期结果 |
|---|---|---|
| 交叉编译工具链 | arm-none-linux-gnueabihf-gcc --version |
显示版本号,无错误 |
| SDK编译 | 执行完整编译流程 | 生成zImage、dtb、rootfs.ext4 |
| TFTP服务 | 开发板ping通主机后,执行 tftp 192.168.1.100 -g -r zImage |
成功下载文件 |
| NFS服务 | 开发板执行 mount -t nfs -o nfsvers=3 192.168.1.100:/srv/nfs/rootfs /mnt |
挂载成功,/mnt下可见文件 |
| 网络启动 | U-Boot执行boot命令 | 内核启动,进入shell |
快速验证脚本: 建议将上述验证步骤写入一个shell脚本,每次环境变更后自动执行,确保环境一致性。
2.7 常见问题与避坑指南
- TFTP超时: 检查主机防火墙是否开放UDP 69端口,使用
sudo ufw allow 69/udp放行。 - NFS挂载失败: 确认主机NFS服务已启动,且
/etc/exports中路径与权限正确。使用showmount -e 192.168.1.100在开发板端验证。 - U-Boot无法识别网卡: 检查设备树中以太网节点是否使能,部分T113开发板需额外配置PHY地址。
- 内核崩溃: 确认zImage与dtb版本匹配,使用同一SDK编译。不匹配的设备树会导致内核无法识别硬件。
- 串口无输出: 检查串口线序(T113通常使用UART0,TX/RX/GND三线),波特率设置为115200。
重要提醒: 每次修改SDK配置(如内核menuconfig)后,务必重新编译并更新TFTP目录中的文件。开发板启动时加载的是TFTP服务器上的文件,而非本地文件。