2. 嵌入式Linux开发环境搭建:交叉编译工具链安装、TFTP/NFS服务器配置、串口终端与minicom使用

嵌入式Linux开发与桌面开发最大的区别在于交叉编译与目标板通信。本章将系统讲解全志T113平台开发环境的三大核心组件:交叉编译工具链、TFTP/NFS网络服务、以及串口终端工具minicom的安装与配置。正确搭建这些环境是后续驱动调试与内核日志分析的基础。

环境概览: 主机使用 Ubuntu 22.04 LTS x86_64,目标板为全志T113-S3,内核版本 Linux 5.4.61。所有操作均在普通用户下通过 sudo 提权执行。

2.1 交叉编译工具链安装

交叉编译工具链允许我们在x86主机上编译出ARM架构的可执行文件。全志T113平台使用Cortex-A7内核,需要对应的arm-linux-gnueabihf工具链。

2.1.1 工具链选择与下载

推荐使用Linaro提供的GCC交叉编译工具链,版本选择与内核匹配的7.5.0或更高版本。

工具链组件 版本/路径 说明
gcc 7.5.0 C/C++编译器
binutils 2.30 汇编器、链接器
glibc 2.27 C标准库
linux-kernel-headers 4.14 内核头文件

2.1.2 安装步骤

  1. 下载工具链:从Linaro官方仓库获取arm-linux-gnueabihf版本。
  2. 解压到指定目录:建议统一放置在 /opt/toolchains/ 下。
  3. 配置环境变量:将工具链的bin目录加入 PATH。
  4. 验证安装:通过 arm-linux-gnueabihf-gcc --version 确认。
# 下载工具链(示例版本 gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf)
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/toolchains
sudo mkdir -p /opt/toolchains
sudo tar -xvf gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf.tar.xz -C /opt/toolchains/

# 添加环境变量(写入 ~/.bashrc)
export PATH=/opt/toolchains/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/bin:$PATH

# 使环境变量生效
source ~/.bashrc

# 验证安装
arm-linux-gnueabihf-gcc --version
# 输出应包含 "gcc (Linaro GCC 7.5-2019.12) 7.5.0"
常见错误: 如果出现 "No such file or directory" 错误,通常是因为主机缺少32位库。执行 sudo apt install lib32z1 lib32ncurses5 lib32bz2-1.0 解决。

2.1.3 交叉编译验证

编写一个简单的Hello World程序,使用交叉编译器编译,并通过 file 命令确认生成的是ARM架构的可执行文件。

# 编写测试程序
echo '#include <stdio.h>
int main() {
    printf("Hello from T113!\n");
    return 0;
}' > hello.c

# 交叉编译
arm-linux-gnueabihf-gcc -o hello hello.c

# 查看文件类型
file hello
# 输出: hello: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3
交叉编译流程示意图 x86 主机 (Ubuntu) 交叉编译工具链 T113 目标板 (ARM) 关键说明: 1. 主机上编写C/C++源代码 2. 使用 arm-linux-gnueabihf-gcc 编译,生成ARM指令集的可执行文件 3. 通过TFTP/NFS或串口将文件传输到T113目标板上运行

2.2 TFTP服务器配置

TFTP(Trivial File Transfer Protocol)用于在主机和目标板之间传输内核镜像、设备树和应用程序。它基于UDP协议,简单高效,适合嵌入式环境。

2.2.1 安装与配置

# 安装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 tee /etc/default/tftpd-hpa <<EOF
TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/srv/tftp"
TFTP_ADDRESS="0.0.0.0:69"
TFTP_OPTIONS="--secure --create"
EOF

# 重启服务
sudo systemctl restart tftpd-hpa
sudo systemctl enable tftpd-hpa

# 验证服务状态
sudo systemctl status tftpd-hpa

2.2.2 防火墙与测试

确保主机防火墙允许UDP 69端口,并使用本地回环地址测试TFTP服务。

# 配置防火墙(如果启用)
sudo ufw allow 69/udp

# 本地测试:上传文件
echo "TFTP test file" > /tmp/test.txt
tftp 127.0.0.1 <<EOF
put /tmp/test.txt test.txt
quit
EOF

# 验证文件已上传到TFTP根目录
ls -l /srv/tftp/test.txt

# 下载测试
tftp 127.0.0.1 <<EOF
get test.txt /tmp/download.txt
quit
EOF
cat /tmp/download.txt
U-Boot中使用TFTP: 在T113的U-Boot命令行中,使用 tftp 0x42000000 zImage 即可从主机下载内核镜像到内存地址0x42000000。

2.3 NFS服务器配置

NFS(Network File System)允许目标板直接挂载主机上的目录,实现文件共享。在驱动开发阶段,可以将编译好的内核模块和应用程序放在NFS共享目录中,目标板无需烧写文件系统即可运行。

2.3.1 安装与导出配置

# 安装NFS服务器
sudo apt install nfs-kernel-server

# 创建共享目录
sudo mkdir -p /srv/nfs/rootfs
sudo chmod 777 /srv/nfs/rootfs

# 配置导出文件 /etc/exports
echo "/srv/nfs/rootfs *(rw,sync,no_subtree_check,no_root_squash)" | sudo tee -a /etc/exports

# 应用配置
sudo exportfs -ra

# 重启NFS服务
sudo systemctl restart nfs-kernel-server

# 验证导出
showmount -e localhost

2.3.2 目标板挂载NFS

在T113的U-Boot中设置内核启动参数,使内核挂载NFS作为根文件系统。

# U-Boot环境变量设置示例
setenv serverip 192.168.1.100    # 主机IP
setenv ipaddr 192.168.1.50       # 目标板IP
setenv nfsroot /srv/nfs/rootfs   # NFS共享路径
setenv bootargs console=ttyS0,115200 root=/dev/nfs nfsroot=${serverip}:${nfsroot},v3,tcp ip=${ipaddr}:::255.255.255.0::eth0:off
saveenv
boot
权限注意: no_root_squash 选项允许目标板的root用户拥有主机上的root权限,这在开发阶段是必要的,但生产环境中应禁用。
TFTP/NFS 网络服务架构图 开发主机 TFTP: /srv/tftp NFS: /srv/nfs/rootfs 以太网 T113 目标板 U-Boot: tftp 下载 内核: NFS 根文件系统 传输内容: TFTP:传输 zImage、dtb、u-boot.bin 等启动文件(UDP 69端口) NFS:挂载完整的根文件系统,包含库、工具和驱动模块(TCP 2049端口)

2.4 串口终端与minicom使用

串口是嵌入式开发中最基本的调试接口。全志T113通常通过UART0输出控制台信息,使用minicom作为终端工具。

2.4.1 硬件连接与识别

T113开发板通常提供3.3V TTL电平的串口接口,使用USB转串口模块连接主机。

T113 串口引脚 USB转串口模块 说明
TX (发送) RX (接收) 交叉连接
RX (接收) TX (发送) 交叉连接
GND (地) GND (地) 共地

2.4.2 minicom安装与配置

# 安装minicom
sudo apt install minicom

# 查看串口设备
ls -l /dev/ttyUSB*
# 通常为 /dev/ttyUSB0

# 将用户加入dialout组(避免每次使用sudo)
sudo usermod -a -G dialout $USER
# 重新登录生效

# 配置minicom
sudo minicom -s

在minicom配置菜单中,选择 "Serial port setup",设置以下参数:

  • A - Serial Device:/dev/ttyUSB0
  • B - Lockfile Location:/var/lock
  • E - Bps/Par/Bits:115200 8N1
  • F - Hardware Flow Control:No
  • G - Software Flow Control:No

配置完成后选择 "Save setup as dfl" 保存为默认配置。

2.4.3 minicom常用操作

# 启动minicom(默认配置)
minicom

# 启动时指定波特率和设备
minicom -b 115200 -D /dev/ttyUSB0

# 退出minicom:先按 Ctrl+A,再按 X,选择 Yes

# 捕获串口日志到文件
# 在minicom中按 Ctrl+A,再按 L,输入文件名开始捕获
# 再次按 Ctrl+A,再按 L 停止捕获
日志捕获技巧: 在minicom中按 Ctrl+A 然后按 L 可以开启日志记录,所有串口输出将保存到指定文件中。这对于后续分析内核启动日志和驱动调试信息非常有用。

2.4.4 串口调试常见问题

问题现象 可能原因 解决方法
无任何输出 串口线连接错误或TX/RX接反 交换TX/RX线序
输出乱码 波特率不匹配 确认目标板波特率(通常115200)
权限拒绝 用户不在dialout组 执行 sudo usermod -a -G dialout $USER
设备不存在 USB转串口驱动未加载 检查 lsusb 或安装CH340/PL2303驱动
串口调试连接拓扑 开发主机 minicom USB转串口 /dev/ttyUSB0 T113 目标板 UART0 (115200 8N1) 串口参数: 波特率 115200,数据位 8,停止位 1,无校验(8N1),无硬件流控

2.5 环境验证综合测试

完成上述配置后,执行以下综合测试验证整个开发环境是否正常工作:

  1. 交叉编译测试:编译一个简单的驱动模块或应用程序。
  2. TFTP传输测试:在U-Boot中通过TFTP下载内核镜像。
  3. NFS挂载测试:目标板启动后挂载NFS根文件系统。
  4. 串口日志捕获:使用minicom捕获完整的启动日志。
# 交叉编译一个简单的内核模块
cat > hello_module.c <<EOF
#include <linux/module.h>
#include <linux/kernel.h>

static int __init hello_init(void) {
    printk(KERN_INFO "Hello from T113 driver module!\n");
    return 0;
}

static void __exit hello_exit(void) {
    printk(KERN_INFO "Goodbye from T113 driver module!\n");
}

module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");
EOF

# 使用交叉编译器编译(需要内核源码树)
make -C /path/to/t113-kernel M=$(pwd) ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- modules

# 将生成的 .ko 文件复制到TFTP目录
cp hello_module.ko /srv/tftp/

# 在目标板串口终端中执行
# tftp -g -r hello_module.ko 192.168.1.100
# insmod hello_module.ko
# dmesg | tail -5
开发效率建议: 将TFTP和NFS结合使用:TFTP用于快速传输内核和dtb文件,NFS用于挂载完整的开发文件系统。这样每次修改驱动或应用后,只需在主机端重新编译,目标板重启即可生效,无需反复烧写存储介质。