第二章 开发环境搭建:交叉编译工具链安装、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内核。我建议用厂商提供的版本,因为驱动适配更全。

基本步骤:

  1. 配置内核 —— 使用厂商提供的defconfig
  2. 编译内核 —— 生成zImage或uImage
  3. 编译设备树 —— 生成.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来制作,它自动化程度高,适合嵌入式场景。

基本流程:

  1. 下载Buildroot
  2. 配置目标架构(ARM)和工具链路径
  3. 选择需要的包(比如busybox、libc、openssl等)
  4. 编译生成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分钟。之后增量编译就快了。

我的经验:根文件系统里一定要包含tftpnfs-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机驱动程序。到时候你会感谢今天搭好的这套环境。