2. 开发环境搭建
嵌入式Linux驱动开发的第一步是构建一个稳定、可复现的开发环境。本章将指导你从零开始配置全志T113的完整开发栈,包括主机环境、交叉编译工具链、SDK获取与编译,以及用于快速迭代的TFTP/NFS网络启动环境。一个配置正确的开发环境能显著减少后续调试中的“环境问题”干扰,让你专注于驱动逻辑本身。
2.1 Linux开发主机配置
开发主机是驱动开发的“工作台”,需要安装必要的软件包和工具。以下步骤在 Ubuntu 22.04 上验证通过,其他发行版请使用对应的包管理器。
2.1.1 基础软件包安装
# 更新软件源
sudo apt update
# 安装基础开发工具
sudo apt install -y build-essential git vim curl wget \
libncurses5-dev libssl-dev flex bison \
u-boot-tools device-tree-compiler \
python3 python3-pip python3-dev
# 安装网络启动相关服务
sudo apt install -y tftpd-hpa nfs-kernel-server net-tools
# 安装串口调试工具
sudo apt install -y minicom picocom lrzsz
- build-essential:包含 gcc、g++、make 等编译核心工具。
- libncurses5-dev:提供内核 menuconfig 配置界面的依赖。
- device-tree-compiler:用于编译设备树文件(.dts → .dtb)。
- tftpd-hpa / nfs-kernel-server:用于搭建网络启动环境,实现内核与根文件系统的远程加载。
2.1.2 主机网络与串口配置
开发主机通常通过以太网与T113目标板连接,同时通过USB转串口线连接目标板的调试串口。建议将主机以太网口配置为静态IP,方便TFTP/NFS服务稳定工作。
# 查看网卡名称(通常为 eth0 或 enpXsY)
ip link show
# 临时配置静态IP(示例:192.168.1.100/24)
sudo ip addr add 192.168.1.100/24 dev eth0
sudo ip link set eth0 up
# 永久配置(编辑 /etc/netplan/ 下的配置文件,以 01-netcfg.yaml 为例)
sudo vim /etc/netplan/01-netcfg.yaml
串口工具推荐使用 picocom,轻量且支持硬件流控关闭(T113调试串口通常无流控):
# 查看串口设备(通常为 /dev/ttyUSB0)
ls -l /dev/ttyUSB*
# 使用 picocom 连接(波特率 115200,8N1,无流控)
sudo picocom -b 115200 -d 8 -p n -s 1 /dev/ttyUSB0
# 退出 picocom:Ctrl+A 然后 Ctrl+X
sudo usermod -aG dialout $USER,然后重新登录生效。
2.2 交叉编译工具链安装
T113 处理器基于 ARM Cortex-A7 架构,需要在 x86 主机上使用交叉编译工具链生成 ARM 目标代码。全志官方 SDK 通常自带工具链,但为了灵活性和版本可控,我们单独安装 Linaro 提供的通用工具链。
2.2.1 工具链选择与下载
| 工具链名称 | 目标架构 | C库 | 适用场景 |
|---|---|---|---|
| arm-linux-gnueabihf- | ARM Cortex-A7 | glibc (硬浮点) | Linux用户态应用、内核模块 |
| arm-linux-gnueabi- | ARM Cortex-A7 | glibc (软浮点) | 兼容旧版工具链 |
| arm-none-linux-gnueabihf- | ARM Cortex-A7 | glibc (硬浮点) | 裸机或u-boot早期阶段 |
本课程选用 gcc-arm-10.3-2021.07-x86_64-arm-linux-gnueabihf 版本,支持 C11/C++17 标准,与 Linux 5.4 内核兼容性良好。
# 下载工具链(约 200MB)
wget https://developer.arm.com/-/media/Files/downloads/gnu-a/10.3-2021.07/binrel/gcc-arm-10.3-2021.07-x86_64-arm-linux-gnueabihf.tar.xz
# 解压到 /opt 目录
sudo tar -xvf gcc-arm-10.3-2021.07-x86_64-arm-linux-gnueabihf.tar.xz -C /opt/
# 添加环境变量(写入 ~/.bashrc 或 ~/.zshrc)
echo 'export PATH=$PATH:/opt/gcc-arm-10.3-2021.07-x86_64-arm-linux-gnueabihf/bin' >> ~/.bashrc
source ~/.bashrc
# 验证安装
arm-linux-gnueabihf-gcc --version
2.2.2 工具链验证与测试
编写一个简单的 C 程序,交叉编译后在主机上检查文件类型,确认生成了 ARM 架构的可执行文件。
# 创建测试文件
echo '#include <stdio.h>
int main() { printf("Hello T113!\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)
arm-linux-gnueabihf-gcc 在 PATH 中,或者通过 SDK 的 build/envsetup.sh 脚本自动设置交叉编译环境。
2.3 T113 SDK获取与编译
全志T113官方SDK基于 Linux 5.4 内核,集成了U-Boot、内核、设备树及基础文件系统。SDK通常通过全志官方客户渠道或合作伙伴获取,本课程假设你已获得 t113-sdk-v1.0.tar.gz 压缩包。
2.3.1 SDK目录结构
解压后,SDK的典型目录结构如下:
t113-sdk/
├── build/ # 编译脚本与配置文件
│ ├── envsetup.sh # 环境设置脚本
│ ├── mkernel.sh # 内核编译脚本
│ └── target/ # 板级配置
├── kernel/ # Linux 5.4 内核源码
│ ├── arch/arm/ # ARM 架构相关代码
│ ├── drivers/ # 驱动源码(UART、DMA等)
│ └── ...
├── u-boot/ # U-Boot 引导程序
├── device/ # 设备树源文件(.dts)
│ └── config/ # 板级配置
├── out/ # 编译输出目录
└── toolchain/ # 内置交叉工具链(可选)
2.3.2 SDK编译流程
编译SDK分为三个主要阶段:环境初始化、内核配置、全量编译。以下步骤以默认配置为例:
# 1. 解压SDK
tar -xzf t113-sdk-v1.0.tar.gz
cd t113-sdk
# 2. 设置编译环境
source build/envsetup.sh
# 选择板级配置(通常为 t113_evb1_config)
lunch
# 3. 配置内核(可选,默认配置已包含UART和DMA支持)
make kernel_menuconfig
# 进入 Device Drivers → Character devices → Serial drivers
# 确认 CONFIG_SERIAL_8250 和 CONFIG_SERIAL_8250_DMA 已开启
# 4. 全量编译(内核、U-Boot、设备树、文件系统)
make -j$(nproc)
# 5. 编译输出位于 out/ 目录
ls out/
# 输出包含:boot.img、rootfs.ext4、u-boot-sunxi-with-spl.bin 等
- 使用
make -j$(nproc)并行编译,充分利用多核CPU。 - 首次编译后,后续仅修改驱动时可单独编译内核模块:
make modules -j$(nproc)。 - 如果修改了设备树,只需重新编译设备树:
make dtbs。
2.3.3 编译输出产物说明
| 产物文件 | 说明 | 启动阶段 |
|---|---|---|
| u-boot-sunxi-with-spl.bin | U-Boot引导程序(含SPL) | 第一阶段引导 |
| boot.img | 内核镜像 + 设备树 + ramdisk | 内核启动 |
| rootfs.ext4 | 根文件系统镜像(ext4格式) | 文件系统挂载 |
| *.dtb | 编译后的设备树二进制文件 | 内核解析硬件信息 |
| *.ko | 内核模块(驱动) | 动态加载 |
2.4 TFTP/NFS网络启动环境配置
在驱动开发阶段,频繁烧写Flash会严重拖慢迭代速度。通过TFTP/NFS网络启动,可以让T113目标板从网络加载内核和设备树(TFTP),并将根文件系统挂载到主机共享目录(NFS),实现“修改主机文件 → 重启目标板 → 立即生效”的高效工作流。
2.4.1 网络启动架构
下图展示了TFTP/NFS网络启动的整体数据流:
2.4.2 TFTP服务配置
TFTP用于传输内核镜像(zImage)和设备树文件(.dtb)。配置步骤如下:
# 1. 创建TFTP根目录
sudo mkdir -p /srv/tftp
sudo chmod 777 /srv/tftp
# 2. 复制编译产物到TFTP目录
sudo cp out/boot.img /srv/tftp/
sudo cp out/*.dtb /srv/tftp/
# 3. 配置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"
# 4. 重启TFTP服务
sudo systemctl restart tftpd-hpa
sudo systemctl enable tftpd-hpa
# 5. 验证TFTP服务(本机测试)
echo "test" > /srv/tftp/test.txt
tftp 127.0.0.1 -c get test.txt
cat test.txt
2.4.3 NFS服务配置
NFS用于共享根文件系统,使目标板启动后直接使用主机上的文件系统目录。
# 1. 创建NFS共享目录
sudo mkdir -p /srv/nfs/rootfs
sudo chmod 777 /srv/nfs/rootfs
# 2. 解压或复制根文件系统到共享目录
# 如果SDK编译生成了rootfs.ext4,可挂载后复制内容
sudo mount -o loop out/rootfs.ext4 /mnt
sudo cp -a /mnt/* /srv/nfs/rootfs/
sudo umount /mnt
# 3. 配置NFS导出(编辑 /etc/exports)
sudo vim /etc/exports
在 /etc/exports 中添加:
/srv/nfs/rootfs 192.168.1.0/24(rw,sync,no_subtree_check,no_root_squash)
# 4. 重启NFS服务
sudo systemctl restart nfs-kernel-server
sudo exportfs -av
# 5. 验证NFS挂载(本机测试)
sudo mount -t nfs 127.0.0.1:/srv/nfs/rootfs /mnt
ls /mnt
sudo umount /mnt
no_root_squash 选项允许目标板以 root 权限访问共享目录,在开发环境中方便调试,但生产环境应禁用此选项。
2.4.4 U-Boot网络启动参数设置
在T113目标板的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
# 设置TFTP加载命令
setenv loadkernel 'tftp 0x42000000 boot.img'
setenv loaddtb 'tftp 0x43000000 sun8i-t113-evboard.dtb'
# 设置NFS根文件系统启动参数
setenv bootargs 'console=ttyS0,115200 root=/dev/nfs nfsroot=192.168.1.100:/srv/nfs/rootfs,vers=3 rw ip=192.168.1.200:192.168.1.100:192.168.1.1:255.255.255.0::eth0:off'
# 设置完整启动命令
setenv bootcmd 'run loadkernel; run loaddtb; bootm 0x42000000 - 0x43000000'
# 保存环境变量
saveenv
# 执行网络启动
boot
ping 192.168.1.100 测试网络连通性。如果ping不通,检查网线连接、主机防火墙(sudo ufw disable)以及TFTP/NFS服务状态。
2.5 环境验证清单
完成上述配置后,使用以下清单逐项验证环境是否就绪:
| 验证项 | 验证方法 | 预期结果 |
|---|---|---|
| 交叉编译工具链 | arm-linux-gnueabihf-gcc --version |
显示版本号(如 10.3.1) |
| SDK编译 | make -j$(nproc) |
编译成功,out/ 目录生成镜像文件 |
| TFTP服务 | 本机 tftp 127.0.0.1 -c get boot.img |
成功下载文件 |
| NFS服务 | 本机 mount -t nfs 127.0.0.1:/srv/nfs/rootfs /mnt |
挂载成功,可看到根文件系统内容 |
| 串口通信 | picocom -b 115200 /dev/ttyUSB0 |
目标板上电后看到U-Boot启动日志 |
| 网络启动 | 目标板执行 boot 命令 |
内核启动,最终进入shell提示符 |