第二章 开发环境搭建:交叉编译工具链安装、TFTP/NFS服务器配置、串口终端与调试工具
好,咱们正式开始动手了。这一章我带你搭好开发环境。说实话,很多初学者一上来就急着写代码,结果环境没配好,折腾一整天连个Hello World都跑不起来。我当年也吃过这个亏,所以这一章咱们稳扎稳打,把地基打牢。
2.1 交叉编译工具链的安装
先说说什么是交叉编译。你想想看,咱们的PC是x86架构,而Exynos是ARM架构。在x86上编译出来的程序,ARM芯片是跑不起来的。所以我们需要一套特殊的编译器——交叉编译工具链。
我个人习惯用Linaro提供的工具链,稳定且社区支持好。以Exynos 4412为例,我推荐使用gcc-linaro-arm-linux-gnueabihf-4.9-2014.07这个版本。为什么选这个?因为我在项目中实测过,它对Exynos的NEON指令集支持最完善。
安装步骤:
- 下载工具链压缩包
- 解压到指定目录(我习惯放在
/opt/toolchains/) - 配置环境变量
# 解压
tar -xjf gcc-linaro-arm-linux-gnueabihf-4.9-2014.07.tar.bz2 -C /opt/toolchains/
# 配置环境变量(建议写入 ~/.bashrc)
export PATH=/opt/toolchains/gcc-linaro-arm-linux-gnueabihf-4.9-2014.07/bin:$PATH
export CROSS_COMPILE=arm-linux-gnueabihf-
export ARCH=arm
# 验证安装
arm-linux-gnueabihf-gcc --version
注意:我曾经遇到过一个问题——解压后直接复制到/usr/local/bin,结果权限混乱,编译时各种段错误。所以请务必保持工具链在独立目录,用PATH来引用。
验证是否安装成功,最简单的方法就是编译一个Hello World,然后看看文件类型:
# 编写测试文件
echo '#include <stdio.h>
int main() { printf("Hello Exynos!\n"); return 0; }' > test.c
# 交叉编译
arm-linux-gnueabihf-gcc test.c -o test_arm
# 查看文件信息
file test_arm
# 输出应为:ELF 32-bit LSB executable, ARM, version 1 (SYSV)
看到ARM字样,说明工具链工作正常。嗯,这里要注意,如果你的系统是64位的,可能需要安装32位兼容库:sudo apt-get install lib32z1 lib32ncurses5。我当年第一次装的时候忘了这茬,折腾了半小时才发现问题。
2.2 TFTP服务器配置
TFTP这玩意儿,说白了就是个轻量级的文件传输协议。在嵌入式开发中,我们用它来把编译好的内核镜像、设备树文件传到开发板上。为什么不用FTP?因为TFTP简单,不需要认证,适合在U-Boot阶段使用。
我建议在Ubuntu主机上安装tftpd-hpa:
# 安装TFTP服务器
sudo apt-get install tftpd-hpa
# 配置文件 /etc/default/tftpd-hpa
TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/tftpboot" # 我习惯用这个目录
TFTP_ADDRESS="0.0.0.0:69"
TFTP_OPTIONS="-l -c -s"
# 创建目录并设置权限
sudo mkdir -p /tftpboot
sudo chmod 777 /tftpboot
# 重启服务
sudo systemctl restart tftpd-hpa
小技巧:我习惯在/tftpboot里放一个README文件,内容写上当前内核版本和编译时间。这样在U-Boot里用tftp命令下载时,先看看这个文件确认一下,避免烧错镜像。这个习惯帮我避免过好几次低级错误。
测试TFTP是否正常工作:
# 在/tftpboot里放一个测试文件
echo "TFTP test" > /tftpboot/test.txt
# 在开发板的U-Boot中执行
tftp 0x41000000 test.txt
# 如果看到"Bytes transferred = 10",说明成功
2.3 NFS服务器配置
NFS(网络文件系统)是开发阶段的利器。你想想看,每次修改代码都要重新烧写根文件系统,那得多浪费时间?用NFS,开发板直接挂载主机上的目录,改完代码立刻生效。
配置NFS服务器:
# 安装NFS服务器
sudo apt-get install nfs-kernel-server
# 编辑 /etc/exports,添加共享目录
/nfsroot 192.168.1.0/24(rw,sync,no_subtree_check,no_root_squash)
# 创建目录并设置权限
sudo mkdir -p /nfsroot
sudo chmod 777 /nfsroot
# 重启服务
sudo systemctl restart nfs-kernel-server
避坑指南:我曾经因为忘了加no_root_squash选项,导致开发板上的root用户无法写入文件。这个选项的意思是:允许远程root用户拥有本地root权限。不加的话,远程root会被映射成nobody用户,权限不够。
在开发板内核启动参数中配置NFS根文件系统:
# U-Boot中设置bootargs
setenv bootargs root=/dev/nfs nfsroot=192.168.1.100:/nfsroot ip=192.168.1.10:192.168.1.100:192.168.1.1:255.255.255.0::eth0:off console=ttySAC2,115200
这里解释一下IP参数的格式:开发板IP:服务器IP:网关:子网掩码。我建议把主机的IP固定为192.168.1.100,开发板用192.168.1.10,这样不容易搞混。
2.4 串口终端与调试工具
串口是嵌入式开发中最基础的调试手段。说白了,它就是开发板的"眼睛"和"耳朵"。没有串口,你连内核启动到哪一步了都不知道。
我推荐使用minicom作为串口终端工具:
# 安装minicom
sudo apt-get install minicom
# 配置串口参数
sudo minicom -s
# 进入配置菜单后设置:
# 串口设备:/dev/ttyUSB0(根据实际情况调整)
# 波特率:115200
# 数据位:8
# 停止位:1
# 校验:无
# 硬件流控:关闭
个人经验:我习惯把minicom的配置文件保存为~/.minirc.exynos,这样下次直接用minicom exynos就能启动。另外,建议在minicom里开启日志记录,这样调试信息不会丢失。
除了minicom,我还常用这些调试工具:
| 工具名称 | 用途 | 我的使用频率 |
|---|---|---|
| minicom | 串口终端 | 每天必用 |
| screen | 备用串口工具 | 偶尔 |
| kermit | 文件传输+终端 | 很少 |
| cutecom | 图形化串口工具 | 新手推荐 |
为什么会推荐cutecom给新手?因为它有图形界面,参数设置一目了然。但我个人还是习惯minicom,毕竟在终端里操作更高效,而且远程SSH时也能用。
最后,别忘了检查串口权限:
# 将当前用户加入dialout组
sudo usermod -a -G dialout $USER
# 重新登录后生效
# 或者临时修改权限(不推荐)
sudo chmod 666 /dev/ttyUSB0
本章小结:环境搭建是嵌入式开发的第一步,也是最容易出问题的一步。交叉编译工具链、TFTP、NFS、串口终端,这四个组件缺一不可。我建议你按照顺序一步步来,每完成一个就测试一下,不要等到全部配完再调试。嗯,相信我,这样能省下不少时间。