2. 嵌入式Linux开发环境搭建:交叉编译工具链安装、TFTP/NFS服务器配置、串口终端与minicom使用
嵌入式Linux开发与桌面开发最大的区别在于交叉编译与目标板通信。本章将系统讲解全志T113平台开发环境的三大核心组件:交叉编译工具链、TFTP/NFS网络服务、以及串口终端工具minicom的安装与配置。正确搭建这些环境是后续驱动调试与内核日志分析的基础。
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 安装步骤
- 下载工具链:从Linaro官方仓库获取arm-linux-gnueabihf版本。
- 解压到指定目录:建议统一放置在
/opt/toolchains/下。 - 配置环境变量:将工具链的bin目录加入
PATH。 - 验证安装:通过
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"
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
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
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权限,这在开发阶段是必要的,但生产环境中应禁用。
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 停止捕获
Ctrl+A 然后按 L 可以开启日志记录,所有串口输出将保存到指定文件中。这对于后续分析内核启动日志和驱动调试信息非常有用。
2.4.4 串口调试常见问题
| 问题现象 | 可能原因 | 解决方法 |
|---|---|---|
| 无任何输出 | 串口线连接错误或TX/RX接反 | 交换TX/RX线序 |
| 输出乱码 | 波特率不匹配 | 确认目标板波特率(通常115200) |
| 权限拒绝 | 用户不在dialout组 | 执行 sudo usermod -a -G dialout $USER |
| 设备不存在 | USB转串口驱动未加载 | 检查 lsusb 或安装CH340/PL2303驱动 |
2.5 环境验证综合测试
完成上述配置后,执行以下综合测试验证整个开发环境是否正常工作:
- 交叉编译测试:编译一个简单的驱动模块或应用程序。
- TFTP传输测试:在U-Boot中通过TFTP下载内核镜像。
- NFS挂载测试:目标板启动后挂载NFS根文件系统。
- 串口日志捕获:使用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