嵌入式固件 .pkg 打包流程
.pkg 打包
- 一、pkg 包技术扫盲
- 1.1 什么是 pkg 包?
- 1.2 pkg 包的核心作用
- 1.3 固件 .pkg 包的特殊性
- 1.4 pkg 包的基本结构
- 二、固件打包完整流程
- 2.1 第一阶段:构建仓库编译准备
- 2.2 第二阶段:替换 Conan Server 文件
- 2.3 第三阶段:版本信息更新
- 2.4 第四阶段:相机仓库文件替换
- 2.5 第五阶段:仓库重新构建
- 2.6 第六阶段:生成最终 .pkg 包
- 三、常见疑惑解答
- 3.1 子模块管理的区别
- 3.2 构建仓发版 vs pkg打包
- 3.3 Docker 步骤
- 3.4 build.sh 参数差异
- 四、工程实践建议
- 5.1 版本管理最佳实践
- 质量保证
- 安全考虑
- 故障排除
一、pkg 包技术扫盲
1.1 什么是 pkg 包?
pkg 是 Package(包) 的缩写,是一种软件分发和安装的标准格式。不同系统和平台有不同的 pkg 格式:
- macOS:
.pkg
文件,苹果官方安装包格式 - FreeBSD/OpenBSD:
.pkg
文件,系统软件包管理 - 嵌入式设备:
.pkg
文件,固件升级包(相机,物联网,传感器) - Linux:
.deb
(Debian/Ubuntu)、.rpm
(RedHat/CentOS)、.tar.xz
(Arch Linux)等
1.2 pkg 包的核心作用
- 软件分发:将软件、库、配置文件等打包成单一文件,便于传输和分发。
- 版本管理:包含版本信息、依赖关系、安装脚本等元数据。
- 自动安装:用户或系统可自动解析并安装包内容。
- 完整性校验:通过校验和、数字签名等确保包的完整性和安全性。
1.3 固件 .pkg 包的特殊性
固件 .pkg 是专门为嵌入式设备(相机)设计的固件升级包,具有以下特点:
- 自包含:包含完整的固件、驱动、配置文件、升级脚本等
- 自动升级:设备检测到 SD 卡中的 .pkg 文件后自动升级
- 安全机制:通常包含版本检查、电量检查、校验码验证等安全措施
- 回滚机制:升级失败时能回滚到原版本,防止设备变砖
1.4 pkg 包的基本结构
一般的 pkg 包内部结构类似:
firmware.pkg
├── meta/
│ ├── version.txt # 版本信息
│ ├── checksum.md5 # 校验和
│ └── install.sh # 安装脚本
├── firmware/
│ ├── bootloader.bin # 引导程序
│ ├── kernel.img # 内核镜像
│ ├── rootfs.tar.gz # 根文件系统
│ └── app.elf # 应用程序
└── config/
├── default.conf # 默认配置
└── device.cfg # 设备配置
二、固件打包完整流程
2.1 第一阶段:构建仓库编译准备
# 1. 克隆主仓库代码
git clone git@xxxxxxxxxx# 2. 进入项目目录
cd xxx# 3. 创建并切换到指定分支
git checkout -b xxx xxxxxxxx/xxxxxx
# 解释:创建本地分支xxx,基于远程分支xxxxxxxx/xxxxxx# 4. 拉取最新代码(重要补充步骤)
git pull origin xxxxxxxx/xxxxxx
# 确保本地代码是最新的,避免版本冲突# 5. 初始化并更新所有子模块(关键步骤)
git submodule update --init --recursive -f
# 解释:
# --init: 初始化子模块配置
# --recursive: 递归处理嵌套的子模块
# -f: 强制执行,覆盖本地修改# 6. 设置编译环境
source build/envsetup.sh
# 解释:加载编译环境变量、工具链路径、编译函数等# 7. 选择编译目标
lunch xx
# 解释:选择特定的产品配置(如相机型号、硬件平台)# 8. 清理之前的编译产物
m clean_all
# 解释:删除所有编译生成的中间文件和目标文件# 9. 开始完整编译
m all
# 解释:编译整个项目,生成固件、驱动、应用等所有组件
2.2 第二阶段:替换 Conan Server 文件
# 1. 从 Conan Server 下载压缩包并解压
# Conan Server:二进制制品管理服务器,存储预编译的库和组件
# 下载后解压找到4个 xxxxoutput 文件夹# 2. 替换构建仓库的 output 文件夹
cp -r /path/to/conan/xxxxoutput1 ./output/
cp -r /path/to/conan/xxxxoutput2 ./output/
cp -r /path/to/conan/xxxxoutput3 ./output/
cp -r /path/to/conan/xxxxoutput4 ./output/
# 注意:这会直接覆盖原有编译输出,用预编译的稳定版本替换
为什么要替换?
- 稳定性:Conan Server 上的是经过测试的稳定版本
- 一致性:确保不同开发者打包的固件使用相同的核心组件
- 效率:避免重复编译耗时的核心模块
2.3 第三阶段:版本信息更新
# 修改构建仓库的版本文件
vi build/version.txt
# 将版本号修改为 Conan Server 压缩包对应的版本
# 例如:从 "1.0.0-dev" 改为 "1.2.3-release"
版本号的重要性:
- 追溯性:出现问题时能快速定位具体版本
- 升级控制:设备可根据版本号判断是否需要升级
- 测试管理:测试团队能明确测试的是哪个版本
2.4 第四阶段:相机仓库文件替换
# 进入相机仓库目录
cd xxxcamera# 替换4个关键固件文件:
# 1. xxx/xxx/xxxbuild1/ 下的 .bin 和 .elf 文件
# 2. xxx/xxx/xxxbuild1/out/ 下的 .elf 和 .map 文件cp /path/to/conan/camera_firmware.bin xxx/xxx/xxxbuild1/
cp /path/to/conan/camera_app.elf xxx/xxx/xxxbuild1/
cp /path/to/conan/camera_driver.elf xxx/xxx/xxxbuild1/out/
cp /path/to/conan/debug_symbols.map xxx/xxx/xxxbuild1/out/
文件类型说明:
- .bin:二进制固件文件,直接烧录到设备
- .elf:可执行文件格式,包含程序代码和调试信息
- .map:内存映射文件,用于调试和问题定位
2.5 第五阶段:仓库重新构建
# 在相机仓库目录下执行
m r
# 解释:重新构建相机相关的模块,整合新的固件文件
# 此时会看到大量 [xxx Build] 和 make 命令输出
为什么要重新构建?
- 整合性:将新的固件文件整合到完整的系统中
- 依赖检查:确保所有组件间的依赖关系正确
- 最终验证:生成最终的可安装固件包
2.6 第六阶段:生成最终 .pkg 包
# 回到构建仓库根目录
cd /path/to/build/repo# 执行打包脚本
./build.sh -p
# 解释:-p 参数表示生成 pkg 包
# 脚本会自动压缩、校验、签名,最终生成 .pkg 文件
build.sh -p 内部做了什么?
- 收集文件:将所有固件、配置、脚本文件收集到临时目录
- 生成元数据:创建版本信息、校验和、安装脚本等
- 压缩打包:将所有文件压缩成单一的 .pkg 文件
- 数字签名:对包进行签名,确保完整性和来源可信
- 最终验证:检查生成的包是否符合格式要求
三、常见疑惑解答
3.1 子模块管理的区别
操作类型 | 命令 | 用途 | 使用场景 |
---|---|---|---|
pkg打包 | git submodule update --init --recursive | 获取当前版本对应的子模块代码 | 基于稳定版本打包固件 |
构建仓发版 | git submodule update --remote | 拉取所有子仓库的最新代码 | 准备新版本发布 |
3.2 构建仓发版 vs pkg打包
操作类型 | 构建仓发版 | pkg打包 |
---|---|---|
目的 | 准备新版本的代码基线 | 基于现有代码生成可安装的固件包 |
版本控制 | 包含 git push 等操作 | 不包含 git push 等操作 |
输出 | 新的代码版本标签 | 可安装的 .pkg 文件 |
频率 | 较少(版本发布时) | 较多(测试、调试时) |
3.3 Docker 步骤
指导中的 Docker 主要用于:
- 环境标准化:提供统一的编译环境,避免"在我电脑上能编译"的问题
- 依赖管理:自动安装所需的编译工具和库
- 隔离性:避免污染主机环境
结论:如果你的环境已经配置好且能正常编译,可以跳过 Docker 步骤。
3.4 build.sh 参数差异
./build.sh -m all
:编译所有模块(make all)./build.sh -p
:生成 pkg 包(package)./build.sh --help
:查看所有可用参数
四、工程实践建议
5.1 版本管理最佳实践
- 语义化版本:使用
主版本.次版本.修订版本
格式 - 分支策略:main/master(稳定)、develop(开发)、feature/*(功能)
- 标签管理:每个发布版本都应有对应的 git tag
- 变更日志:维护 CHANGELOG.md 记录版本变更
质量保证
- 编译检查:确保所有警告都被处理
- 静态分析:使用工具检查代码质量
- 单元测试:核心模块要有测试覆盖
- 集成测试:在真实设备上验证固件功能
- 回归测试:确保新版本不会破坏现有功能
安全考虑
- 代码签名:对固件包进行数字签名
- 校验机制:包含 MD5/SHA256 校验和
- 版本验证:防止降级攻击
- 权限控制:限制安装包的执行权限
- 安全传输:使用 HTTPS 分发固件包
故障排除
# 常见问题诊断命令
# 1. 检查磁盘空间
df -h# 2. 检查编译环境
echo $PATH
which gcc# 3. 检查子模块状态
git submodule status# 4. 检查编译日志
tail -f build.log# 5. 验证生成的包
file firmware.pkg
md5sum firmware.pkg