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图展示了主机与开发板之间的完整交互流程,包括编译、传输、启动三个环节:

全志T113开发环境架构图 全志T113 开发环境架构图 Linux 主机 (Ubuntu 22.04) 交叉编译工具链 SDK 源码 编译产物 TFTP 服务 NFS 服务 串口终端 TFTP NFS 串口 全志T113 开发板 U-Boot Linux 内核 设备树 (DTB) 根文件系统 GPIO 驱动 / LED / 蜂鸣器 开发流程说明 ① 主机编译:交叉编译工具链编译SDK,生成zImage、dtb、rootfs ② TFTP传输:U-Boot通过TFTP从主机加载zImage和dtb到开发板内存 ③ NFS挂载:内核启动后通过NFS挂载主机上的根文件系统 ④ 驱动调试:在主机修改驱动代码 → 编译 → 重启开发板验证

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服务器上的文件,而非本地文件。