第二章 开发环境搭建:交叉编译工具链配置、Linux内核裁剪、根文件系统制作、性能分析工具安装

好,咱们直接进入正题。嵌入式开发不像你在PC上写个Hello World那么简单。你写的代码,最终要跑到一个资源受限的ARM或RISC-V芯片上。这就引出了第一个核心问题——交叉编译

2.1 交叉编译工具链配置

说白了,交叉编译就是“在A机器上编译,生成B机器能跑的程序”。我们的POS机主控通常是ARM Cortex-A系列,所以你得在x86的Ubuntu上,装一套ARM的编译工具链。

我个人习惯用Linaro提供的工具链,稳定,社区支持也好。别自己去源码编译,太折腾,除非你有特殊需求。

核心步骤:

  1. 下载gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf.tar.xz
  2. 解压到 /opt/toolchains/ 目录
  3. 配置环境变量 PATH
# 解压
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
export CROSS_COMPILE=arm-linux-gnueabihf-
export ARCH=arm

# 验证
arm-linux-gnueabihf-gcc --version

我曾经踩过一个坑: 32位库缺失。在64位Ubuntu上运行32位交叉编译器,会报“No such file or directory”。别慌,装个 sudo apt install lib32z1 lib32ncurses5 就好。

嗯,这里要注意。你可能会问:“为什么不用最新的gcc 12?” 我的经验是,嵌入式Linux内核版本往往滞后。比如你的内核是4.19,用gcc 7.5就非常稳。太新的编译器反而可能引入奇怪的链接错误。

2.2 Linux内核裁剪

POS机不需要桌面系统,也不需要蓝牙、Wi-Fi(除非是无线POS)。所以内核必须裁剪。你想想看,一个完整的内核镜像可能20MB,裁剪后能压到3MB以内。这对启动速度和内存占用都是质的提升。

我的裁剪原则:

  • 只保留目标硬件平台(如i.MX6ULL)的驱动
  • 去掉所有不必要的文件系统支持(如XFS、Btrfs)
  • 关闭调试选项(CONFIG_DEBUG_INFO、CONFIG_DYNAMIC_DEBUG)
  • 网络协议栈只保留TCP/IP,去掉IPv6、AX.25等
# 进入内核源码目录
cd linux-4.19.94

# 使用默认配置(基于你的开发板)
make ARCH=arm imx_v7_defconfig

# 进入菜单配置界面
make ARCH=arm menuconfig

# 裁剪示例:去掉蓝牙
# Device Drivers → Network device support → Bluetooth subsystem device drivers → [ ] 取消勾选

# 编译
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j4 zImage

小技巧:make savedefconfig 生成精简的defconfig文件。下次直接 make defconfig 就能复现,不用再手动点一遍菜单。

我在项目中遇到过一个问题:裁剪太狠,把串口驱动给去掉了。结果系统启动后,控制台没有任何输出。排查了半天才发现是 CONFIG_SERIAL_IMX 没选。所以,核心外设的驱动一定要保留

2.3 根文件系统制作

内核跑起来后,需要根文件系统来加载应用程序、库文件和配置文件。POS机场景下,我推荐使用Buildroot来制作。它比Yocto轻量,比手动BusyBox更自动化。

Buildroot的关键配置项:

配置项 推荐值 说明
Target Architecture ARM (little endian) 匹配你的CPU
Target Binary Format ELF 标准格式
Toolchain type External toolchain 使用我们刚才装的Linaro工具链
Filesystem images ext4 / squashfs POS机建议用squashfs,只读更安全
Package selection 去掉alsa-utils、X11等 只保留libc、libpthread、sqlite等
# 下载Buildroot
git clone https://git.buildroot.net/buildroot
cd buildroot

# 配置
make menuconfig

# 选择外部工具链路径
# Toolchain → Toolchain path → /opt/toolchains/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf

# 编译(第一次会比较慢)
make -j4

避坑指南: 我曾经在制作根文件系统时,忘了添加 libstdc++。结果POS机的支付应用死活跑不起来,报“cannot open shared object file”。检查一下Buildroot的“C++ support”选项是否开启。

嗯,还有一点。POS机通常需要只读根文件系统,防止意外篡改。用squashfs格式,启动时挂载为只读。运行时数据(如交易日志)放在可写的tmpfs或单独的data分区。

2.4 性能分析工具安装

环境搭好了,怎么知道系统跑得怎么样?你得装几把“尺子”。

我必装的工具清单:

  • perf:Linux内核自带的性能剖析工具。看CPU热点、缓存命中率、上下文切换。
  • ftrace:跟踪内核函数调用。排查调度延迟、中断响应时间。
  • strace:跟踪系统调用。看应用在干什么,是不是在频繁open/close文件。
  • top / htop:实时查看CPU、内存占用。htop更直观,但体积大一点。
  • iostat:监控I/O性能。POS机频繁读写闪存,这个很有用。
# 在Buildroot中启用perf
# Target packages → Debugging → [*] perf

# 手动交叉编译strace(如果Buildroot没有)
git clone https://github.com/strace/strace.git
cd strace
./bootstrap
./configure --host=arm-linux-gnueabihf --prefix=/opt/strace_arm
make
make install

# 将编译好的二进制拷贝到根文件系统的 /usr/bin/ 目录

个人经验: 对于资源紧张的POS机(比如只有64MB RAM),别装htop。用busybox自带的top就够了。perf的overhead也不小,生产环境慎用,调试时开一下就好。

你可能会问:“这些工具在开发板上怎么用?” 很简单。通过NFS挂载根文件系统,或者用scp把编译好的二进制传过去。然后ssh登录开发板,直接敲命令就行。

举个例子,用perf分析POS机应用的CPU热点:

# 在开发板上
perf record -g -F 99 ./pos_app
# 运行一段时间后,Ctrl+C停止
perf report

它会告诉你哪个函数占CPU最多。我曾经用这个方法,发现POS机的UI刷新函数里有个不必要的循环,优化后帧率从15fps提升到了30fps。

好了,环境搭建这部分就这些。工具链、内核、根文件系统、性能工具,四步走完,你的开发环境就齐活了。下一章我们聊聊压力测试框架的设计,那才是真正考验系统稳定性的地方。