第二章 开发环境搭建:交叉编译工具链安装、Linux内核与根文件系统配置、TFTP/NFS调试环境搭建
好,咱们正式开始动手了。这一章要解决一个核心问题:怎么让你的PC和POS机板子“说上话”。说白了,就是搭建一套能编译、能烧录、能调试的完整环境。
我刚开始做POS机开发时,最头疼的就是环境问题。工具链版本不对,内核起不来,调试半天发现是TFTP路径写错了……这些坑我都踩过。今天咱们一步步来,把地基打牢。
2.1 交叉编译工具链安装
为什么需要交叉编译?因为你的PC是x86架构,而POS机主控芯片通常是ARM架构。PC上编译的程序,ARM芯片跑不了。所以我们需要一套“交叉编译工具链”——在PC上运行,生成ARM可执行文件。
核心概念:交叉编译 = 在A平台上编译,在B平台上运行。A叫宿主机,B叫目标机。
2.1.1 选择工具链
我个人习惯用Linaro提供的GCC工具链,稳定且社区活跃。针对ARM Cortex-A系列,推荐:
- gcc-arm-linux-gnueabihf —— 针对ARMv7-A,支持硬浮点
- aarch64-linux-gnu-gcc —— 针对ARMv8-A 64位
嗯,这里要注意:POS机主控芯片现在主流是Cortex-A7或A53,32位居多。所以咱们选第一个。
2.1.2 安装步骤
以Ubuntu 20.04为例,直接apt安装最省事:
sudo apt update
sudo apt install gcc-arm-linux-gnueabihf
安装完后验证一下:
arm-linux-gnueabihf-gcc --version
看到版本号就对了。我曾经遇到一个问题:装完发现命令找不到,后来发现是没装g++。所以建议一起装:
sudo apt install gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf
小技巧:如果你需要特定版本(比如GCC 9.3),可以去Linaro官网下载预编译包,解压后把bin目录加入PATH即可。我个人习惯放在 /opt/toolchains/ 下。
2.1.3 测试编译
写个最简单的hello.c:
#include <stdio.h>
int main() {
printf("Hello POSIX!\n");
return 0;
}
交叉编译:
arm-linux-gnueabihf-gcc -o hello hello.c
用file命令查看生成的文件:
file hello
输出应该是:ELF 32-bit LSB executable, ARM, version 1 (SYSV)。看到ARM字样,说明工具链工作正常。
2.2 Linux内核与根文件系统配置
环境搭好了,接下来要准备两样东西:内核镜像和根文件系统。它们是POS机系统启动的“灵魂”。
2.2.1 内核编译
从芯片厂商(比如全志、瑞芯微)获取内核源码,或者用主线Linux内核。我建议用厂商提供的版本,因为驱动适配更全。
基本步骤:
- 配置内核 —— 使用厂商提供的defconfig
- 编译内核 —— 生成zImage或uImage
- 编译设备树 —— 生成.dtb文件
举个例子:
export ARCH=arm
export CROSS_COMPILE=arm-linux-gnueabihf-
make xxx_defconfig
make zImage -j4
make dtbs
这里有个坑:CROSS_COMPILE变量一定要设置正确。我见过有人忘记加最后的短横线,结果编译出来是x86的镜像,烧到板子上当然起不来。
注意:内核编译时,如果报错缺少ncurses库,安装即可:sudo apt install libncurses-dev。这是新手最容易卡住的地方。
2.2.2 根文件系统制作
根文件系统包含POS机运行所需的所有库、工具和配置文件。我推荐用Buildroot来制作,它自动化程度高,适合嵌入式场景。
基本流程:
- 下载Buildroot
- 配置目标架构(ARM)和工具链路径
- 选择需要的包(比如busybox、libc、openssl等)
- 编译生成rootfs.tar或rootfs.ext4
关键配置项:
| 配置项 | 推荐值 | 说明 |
|---|---|---|
| Target Architecture | ARM (little endian) | POS机主控基本都是小端模式 |
| Target Binary Format | ELF | 标准Linux格式 |
| Toolchain type | External toolchain | 使用我们刚才安装的Linaro工具链 |
| System configuration | Enable root login with password | 调试阶段建议开启,密码设为空或简单密码 |
编译命令:
make -j4
第一次编译会比较慢,大概10-20分钟。之后增量编译就快了。
我的经验:根文件系统里一定要包含tftp和nfs-utils这两个包。为什么?因为后面调试要用。我曾经漏掉了,结果板子起起来后没法通过网络加载应用,折腾了半天。
2.3 TFTP/NFS调试环境搭建
环境搭好了,内核和根文件系统也准备好了。但怎么把它们弄到板子上?怎么调试?这就用到TFTP和NFS了。
2.3.1 TFTP服务器搭建
TFTP用于通过网络下载内核镜像和设备树。它简单、轻量,适合U-Boot阶段使用。
安装:
sudo apt install tftpd-hpa
配置文件在 /etc/default/tftpd-hpa,我习惯这样配:
TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/srv/tftp"
TFTP_ADDRESS="0.0.0.0:69"
TFTP_OPTIONS="--secure --create"
然后创建目录,放内核和设备树:
sudo mkdir -p /srv/tftp
sudo cp arch/arm/boot/zImage /srv/tftp/
sudo cp arch/arm/boot/dts/xxx.dtb /srv/tftp/
sudo systemctl restart tftpd-hpa
测试一下:在板子的U-Boot里输入:
tftp 0x42000000 zImage
如果能下载成功,说明TFTP通了。
注意:防火墙要开放UDP 69端口。我遇到过明明配置没问题,但就是下载失败,最后发现是ufw没关。调试阶段建议直接关防火墙:sudo ufw disable。
2.3.2 NFS服务器搭建
NFS用于挂载根文件系统。这样你修改了应用代码,不用重新烧录,板子重启就能加载新文件。开发效率提升一大截。
安装:
sudo apt install nfs-kernel-server
配置 /etc/exports:
/srv/nfs/rootfs *(rw,sync,no_subtree_check,no_root_squash)
创建目录并解压根文件系统:
sudo mkdir -p /srv/nfs/rootfs
sudo tar -xf output/images/rootfs.tar -C /srv/nfs/rootfs
sudo systemctl restart nfs-kernel-server
在U-Boot中设置启动参数:
setenv bootargs 'console=ttyS0,115200 root=/dev/nfs nfsroot=192.168.1.100:/srv/nfs/rootfs ip=192.168.1.101'
setenv bootcmd 'tftp 0x42000000 zImage; tftp 0x43000000 xxx.dtb; bootz 0x42000000 - 0x43000000'
saveenv
boot
这里IP地址要改成你实际的。PC端IP是192.168.1.100,板子IP是192.168.1.101。
调试黄金组合:TFTP加载内核 + NFS挂载根文件系统。内核基本不动,改应用代码后重启板子即可。我开发POS机应用时,一天要重启几十次,全靠这个组合。
2.3.3 常见问题排查
- TFTP超时:检查网线、IP地址、防火墙。用PC端
tftp localhost测试服务器是否正常。 - NFS挂载失败:检查
/etc/exports语法,重启nfs服务。板子上用mount -t nfs -o nolock试试。 - 内核启动卡住:多半是设备树不对,或者根文件系统路径写错了。用
printenv查看启动参数。
嗯,这一章内容不少。但环境搭建就是这样,一次配置好,后面就顺畅了。我个人建议:把每一步都记录下来,写成脚本。下次换项目或者换板子,直接改几个参数就能用。
下一章,咱们开始写第一个POS机驱动程序。到时候你会感谢今天搭好的这套环境。