第二章 开发环境搭建:交叉编译工具链配置、Linux内核裁剪、根文件系统制作、性能分析工具安装
好,咱们直接进入正题。嵌入式开发不像你在PC上写个Hello World那么简单。你写的代码,最终要跑到一个资源受限的ARM或RISC-V芯片上。这就引出了第一个核心问题——交叉编译。
2.1 交叉编译工具链配置
说白了,交叉编译就是“在A机器上编译,生成B机器能跑的程序”。我们的POS机主控通常是ARM Cortex-A系列,所以你得在x86的Ubuntu上,装一套ARM的编译工具链。
我个人习惯用Linaro提供的工具链,稳定,社区支持也好。别自己去源码编译,太折腾,除非你有特殊需求。
核心步骤:
- 下载gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf.tar.xz
- 解压到 /opt/toolchains/ 目录
- 配置环境变量 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。
好了,环境搭建这部分就这些。工具链、内核、根文件系统、性能工具,四步走完,你的开发环境就齐活了。下一章我们聊聊压力测试框架的设计,那才是真正考验系统稳定性的地方。