从零开始编译 T33 嵌入式摄像头工程:一份踩坑无数的实战大纲
平台:T33 (MIPS)
内核版本:3.10.14-Zeratul-Archon
工具链:mips-gcc540-glibc222-r3.3.7.mxu2.cve
构建方式:统一入口 build.sh
适用场景:嵌入式Linux摄像头开发、OTA打包、工厂固件烧录
最近在折腾一个基于 T33 平台的摄像头项目,目录结构比较庞大(涉及 Kernel、Uboot、SDK、OTA 签名等)。官方虽然提供了 build.sh,但参数繁多,新手极易踩坑。为了不让后续接手的同学(还有未来的我自己)在环境搭建和编译上浪费太多时间,我整理了一份从手动编译到脚本化构建的完整大纲。
这篇文章不讲复杂的原理,只讲"怎么把代码跑起来"。
一、环境准备与工具链安装(手动配置)
兵马未动,粮草先行。T33 是 MIPS 架构,且工具链后缀带有 mxu2.cve(DSP/CVE加速指令集),切勿与旧版工具链混用。
1. 工具链路径
项目已经为我们准备好了专用工具链,位于:
toolchain/mips-gcc540-glibc222-r3.3.7.mxu2.cve/
2. 设置环境变量
强烈建议将其写入 ~/.bashrc,否则每次打开终端都要重新设置。
# 在 ~/.bashrc 末尾添加
export PATH=$PATH:/home/SoureCodePrj/T33/xm_cam_t33/toolchain/mips-gcc540-glibc222-r3.3.7.mxu2.cve/bin
export CROSS_COMPILE=mips-linux-gnu-
export ARCH=mips
刷新环境变量:
source ~/.bashrc
3. 验证安装
输入以下命令,如果看到 mips 相关的版本信息(特别是显示 mxu2 或 cve 字样),说明成功了一半:
mips-linux-gnu-gcc -v
二、编译核心思想构建
1. 手动编译 Linux 的编译顺序非常讲究,千万不要一上来就编译 App。正确的顺序是:
**Uboot** (引导加载)
**Kernel** (操作系统内核)
**Kernel driver** (sensor、wifi、 uvc等驱动)
**Rootfs** (根文件系统骨架)
**Camera SDK** (应用层核心)
**Output** (打包成最终固件)
提示:虽然我们有 build.sh,但理解底层逻辑有助于排查 pack 失败的问题。
2. 一键构建工程会自动构建交叉编译环境
自动构建方式,无需执行环境准备与工具链安装(手动配置) ,只需配置build/PRJ008/env_setup_zeratul.sh规则即可
echo "Setup Zeratul build environment":
JOBS="8"
#release/debug
BUILD_TYPE="release"
VERSION="V0100"
#PRJ008ZX/ZN/DN/DL
SOC_TYPE="PRJ008ZN"
FLASH_TYPE="NOR"
FLASH_SIZE="32M"
PARTITION_MODE="AB" #AB & SINGLE
#direct/un-direct
IVDC_MODE="un-direct"
SENSOR_NUM="2"
if [ "${SENSOR_NUM}" = "1" ] ; then
I2C_NUM="1"
SENSOR="sc3336p"
SENSOR1=""
else
I2C_NUM="2"
#SENSOR="gc2083"
SENSOR="sc3336p"
SENSOR1="gc2083s1"
fi
SENSOR2=""
SENSOR3=""
# KERNEL_VERSION="4.4.94"
KERNEL_VERSION="3.10.14"
TRANSFER_MODE="IIC"
TOOL_CHAIN="5.4.0"
BOARD_VERSION="V1"
#uboot kernel 配置文件
#BOARD_NORMAL_BOOT_DEFCFG="PRJ008_zl_sfcnor_hp"
BOARD_NORMAL_BOOT_DEFCFG="PRJ008_zn_sfcnor_hp"
# PRJ008_zeratul_nor_camera_defconfig PRJ008_zeratul_nor_camera_single_uvc_defconfig PRJ008_zeratul_nor_camera_dual_uvc_defconfig
BOARD_LINUX_DEFCFG="PRJ008_zeratul_nor_camera_dual_uvc_defconfig "
BOARD_LINUX_RECOVERY_DEFCFG="PRJ008_zeratul_nor_camera_recovery_V1_defconfig"
三、自行编译实战(手动版)
如果你需要修改底层配置(如内核裁剪、BusyBox 增减命令),手动编译是必须的。
Step 1: 编译 BSP (Uboot & Kernel)
BSP 代码位于 src/bsp/PRJ008/。这是最容易出现编译错误的地方。
1. 编译 Uboot
进入 Uboot 目录:
cd src/bsp/T33/uboot/
make distclean
# 注意:xxx_config 需要根据你的板级配置文件确定,通常在 configs/ 目录下
# 常见命名如:PRJ008_zn_sfcnor_hp, PRJ008_zl_sfcnor_hp 等
make PRJ008_zn_sfcnor_hp
make -j4
注:如果遇到 mkimage 找不到,记得把 uboot/tools 加入 PATH,或者直接使用顶层 build.sh。
2. 编译 Kernel
进入 Kernel 目录:
cd src/bsp/T33/kernel/
make distclean
# T33 平台通常对应的配置文件
make PRJ008_zeratul_nor_camera_defconfig
make uImage -j4
编译完成后,会在 arch/mips/boot/ 下生成 uImage.jzlzma 镜像。
Step 2: 构建 Rootfs (根文件系统)
Rootfs 是设备运行的"地基",包含了 BusyBox 和各种库。
1. 编译 BusyBox
cd src/bsp/PRJ008/busybox/
make menuconfig # 配置需要的命令
make -j4
make install
2. 生成 Rootfs 骨架
项目脚本会自动将 src/bsp/PRJ008/rootfs/ 下的内容拷贝到 out/camera/_rootfs_camera/。
你需要关注的重点config/PRJ008/目录:
├── fs-config
│ ├── app_init.sh
│ ├── clean_mtd
│ ├── inittab
│ ├── insmod_sfc
│ ├── insmod_uvc
│ ├── insmod_wifi
│ ├── passwd
│ ├── rcS.default
│ ├── rcS.recovery
│ ├── rcS_single.default
│ ├── rsachk.txt
│ ├── swap_system
│ └── swap_usbmode
├── kernel.config -> ./kernel.config_3.10.14
├── kernel.config_3.10.14
├── kernel_recovery.config
└── ota_config
└── t23_ota_config.json
编译时会自动将以上配置拷贝到以下相应的目录当中
- out/camera/_rootfs_camera/bin
- out/camera/_rootfs_camera/lib
-
out/camera/_rootfs_camera/etc (启动脚本都在这里)
Step 3: 编译 Camera SDK (应用层)
这是业务逻辑的核心,位于 src/app/libcamerasdk/。
cd src/app/libcamerasdk/
mkdir -p build
cd build
# 通常这类项目会有 makefile,直接编译即可
make clean
make -j4
编译成功后,库文件和可执行文件通常会被自动安装到 out/camera/user/ 或 _rootfs_camera/ 中。
常见坑点:
- 头文件缺失:检查 __install 目录是否生成,以及 include 路径是否正确。
- 库链接失败:确认 toolchain 的 lib 路径是否被找到。
Step 4: 编译 Factory Test (工厂测试)
工厂测试程序独立于主业务,位于 src/app/factory_test/。
cd src/app/factory_test/
make clean
make
产物会被放置于:out/camera/factory/bin/
四、一键构建:build.sh 工程编译方式
理解了手动流程后,日常开发推荐使用根目录下的 build.sh。以下是基于你提供的帮助信息整理的完整参数解析。
自动构建编译输出固件如下:
$# ./build.sh distclean
$# ./build.sh
Usb Program firmware:
./out/t33z_release_nor_32m_sc3336p_gc2083s1_5.4.0_v0100.bin
./out/t33z_release_nor_32m_sc3336p_gc2083s1_5.4.0_v0100-md5.txt
./out/t33z_sfc1_wmisc_data.bin
1. 构建选项 (Build Framework Options)
| 参数 | 说明 | 典型应用场景 |
|---|---|---|
| quick | 一键全编(最快的方式) | 日常开发,确认整体编译通过 |
| all | 构建所有组件 | 发布版本前的最终验证 |
| uboot | 仅编译 U-Boot | 修改了启动引导代码 |
| uimage | 仅编译 Kernel uImage | 修改了内核代码,无需重编 Uboot |
| menu | 启动内核图形化配置 | 裁剪内核功能、新增驱动支持 |
| busybox | 仅编译 BusyBox | 增减系统命令(如添加 curl) |
| drv | 仅编译驱动 | 修改了特定外设驱动(如 Sensor/WiFi) |
| modules | 仅编译内核模块 | 开发 .ko 模块时 |
| rootfs | 仅构建根文件系统 | 修改了 /etc 下的启动脚本或配置 |
| apps | 仅编译应用层 | 修改了 Camera SDK 或业务逻辑 |
| pack | 制作完整系统镜像包 | 编译完成后,生成可烧录的文件 |
| recovery | 编译 Recovery 模式 | 开发救砖或恢复模式 |
| tag | 构建 Tag 系统 | 版本标签管理 |
| system | 构建 system 分区 | Android 风格分区构建 |
2. 清理选项 (Clean Options)
| 参数 | 说明 |
|---|---|
| clean | 清理所有组件的编译中间文件 |
| distclean | 深度清理(慎用),移除所有构建产物 |
| uboot-clean | 仅清理 U-Boot |
| uimage-clean | 仅清理 Kernel |
| recovery-clean | 清理 Recovery 相关产物 |
| tag-clean | 清理 Tag 系统产物 |
| busybox-clean | 清理 BusyBox 产物 |
| drv-clean | 清理驱动编译产物 |
| modules-clean | 清理内核模块产物 |
| system-clean | 清理 system 分区产物 |
| rootfs-clean | 清理 Rootfs 产物 |
| apps-clean | 清理 Apps 产物 |
| pack-clean | 清理最终打包的镜像文件 |
3. 环境变量
脚本支持通过环境变量覆盖默认配置:
- CROSS_COMPILE:交叉编译器前缀(默认:mips-linux-gnu-)
- ARCH:目标架构(默认:mips)
4. 指定版本号编译
在发布版本时,通常需要指定一个版本号(格式:V+4位数字):
./build.sh V1024
这通常会影响 out 目录下的文件夹命名以及 OTA 包的版本标识。
五、日常开发编译流程(实战场景)
场景 A:首次编译
如果你是第一次拉取代码,或者需要验证整个工程的完整性:
# 方式一:推荐,速度较快
./build.sh
# 方式二:完整构建
./build.sh all
# 构建完成后打包
./build.sh pack
场景 B:内核开发与调试
假设你修改了内核源码或驱动:
# 1. 配置内核(如果需要新增驱动)
./build.sh menu (配置好将.config 拷贝到 config/PRJ008/kernel.config )
# 2. 编译内核镜像
./build.sh uimage
# 3. 如果只改了驱动
./build.sh drv
# 4. 打包测试
./build.sh pack
场景 C:应用层开发(Camera SDK)
这是最常见的开发场景,我们只想编译 src/app/ 下的代码:
# 1. 仅编译应用
./build.sh apps
# 2. 更新 rootfs 里的应用(如果需要)
./build.sh rootfs
# 3. 打包
./build.sh pack
场景 D:增量编译与清理
当编译出现奇奇怪怪的错误时:
# 清理应用层,保留内核编译结果(节省时间)
./build.sh apps-clean
# 重新编译应用
./build.sh apps
# 如果问题依旧,尝试深度清理(会删除所有 .o 和 配置文件,慎用)
./build.sh distclean
# 之后必须重新全编
./build.sh all
场景 E:Recovery 模式开发(保留)
当需要开发救砖或恢复模式时:
# 编译 Recovery
./build.sh recovery
# 清理 Recovery
./build.sh recovery-clean
六、打包与镜像生成
代码编译完了,还需要打包成能烧录的 .img 或 .bin 文件。
./tools/mark_rootfs out/
1. 标记 Rootfs
使用项目提供的工具给根文件系统打上版本标签(通常由 build.sh pack 自动调用):
./tools/mark_rootfs out/camera/_rootfs_camera/
2. 生成 OTA 包
如果你需要生成 OTA 升级包,使用 t33_otapack 工具:
./tools/t33_otapack
生成的 OTA 包会存放在 out/OTA/ 目录下(那个 PRJ008 软链接指向的地方)。
七、安全镜像签名(重要)
现在的嵌入式设备基本都有 Secure Boot,不签名无法启动。
项目提供了完善的签名工具 tools/sign_sec/。
1. 签名 Bootloader
使用 tools/sign_sec/sign_boot/ 下的脚本对 Uboot 进行签名。
- 支持 2048 位和 3072 位密钥签名
- 签名后的 Uboot 才能被硬件 BootROM 验证通过
2. 签名系统镜像
使用 tools/sign_sec/sign_sys/ 对 Kernel 和 Rootfs 进行签名。
- sign_app:对应用程序进行签名
- sign_kr_fs:对关键根文件系统进行签名
注意:如果没有对应的 sec_key(私钥),请找项目负责人索取,否则无法生成合法固件。build.sh 通常会自动调用签名流程。
八、编译产物速查表
编译完成后(build.sh pack 之后),你应该能在 out/ 目录下找到这些关键文件:
| 文件路径 | 作用 |
|---|---|
| out/camera/_rootfs_camera/ | 完整的根文件系统(用于 NFS 挂载调试) |
| out/camera/user/bin/ | 用户态应用程序 |
| out/camera/factory/ | 工厂测试程序 |
| out/OTA/T33/… | OTA 升级包(主要交付物) |
| out/camera/uImage.jzlzma | 内核镜像 |
| out/camera/boot.bin | SPL 镜像 |
| out/camera/tag.bin | tag risv、画质等镜像 |
九、常用命令速查表
| 需求 | 命令 |
|---|---|
| 快速全编 | ./build.sh |
| 完整全编 | ./build.sh all |
| 单编内核 | ./build.sh uimage |
| 内核模块 | ./build.sh modules |
| 外部驱动 | ./build.sh drv |
| busybox | ./build.sh busybox |
| 单编应用 | ./build.sh apps |
| 单编画质 | ./build.sh tag |
| 配置内核 | ./build.sh menu |
| rootfs打包 | ./build.sh rootfs |
| 打包镜像 | ./build.sh pack |
| Recovery | ./build.sh recovery |
| 清理全部 | ./build.sh distclean |
| 清理应用 | ./build.sh apps-clean |
| 指定版本 | ./build.sh V1024 |
| 查看帮助 | ./build.sh – |
十、总结与避坑指南
- 工具链陷阱:T33 的工具链后缀是 mxu2.cve,务必确认 PATH 中没有混入旧的 T23 或其他版本的 gcc。
- 权限问题:遇到 Permission denied,先 chmod +x build.sh。
- Clean 大法:如果编译莫名其妙报错,先 ./build.sh apps-clean。如果是内核报错,尝试 ./build.sh uimage-clean。实在不行再用 distclean。
- Menuconfig 失效:如果在 ./build.sh menu 后保存了配置,再次编译时请确保没有执行 distclean,否则 .config 文件会被删除。
- Quick vs All:quick 模式通常跳过了依赖检查,速度极快;all 模式则最为严谨。如果 quick 报错,尝试用 all 排查依赖问题。
- Pack 的重要性:很多时候 uimage 编译成功了,但设备起不来,是因为没有执行 ./build.sh pack 来更新最终的镜像包。
- 符号链接:out/OTA/T33 是个软链接,如果路径变了,记得重新 ln -sfn 建立链接。
- 配置差异:T33 与 T23 相比,主要是 src/bsp/ 下的板级驱动和 configs/ 下的配置文件不同,切换平台时务必确认使用的是 T33 的配置。
- Recovery 模式:如果设备变砖,检查 out 目录下是否生成了 recovery 相关镜像,可用于救砖。
- Tag 系统:tag 选项用于生成版本标识,确保 OTA 升级时能正确识别版本。
- 分区修改:、修改src/bsp/PRJ008/make_tag/tag_generator/build_tag_PRJ008.sh 进行配置即可
写在最后
记住这条黄金命令流,足以应对 90% 的开发场景:
改应用:./build.sh apps -> ./build.sh pack
改分区:./build.sh tag -> ./build.sh pack
改内核:./build.sh uimage -> ./build.sh pack
全量编:./build.sh all
快速编:./build.sh
这套框架虽然看起来复杂,但分层非常清晰。熟悉了 BSP -> Rootfs -> SDK -> OTA 这个流程后,后续的二次开发就会顺畅很多。希望这篇博客能帮你少走弯路!
如果你在编译过程中遇到了其他奇怪的问题,欢迎在评论区留言交流。
标签: #嵌入式开发 #Linux #T33 #交叉编译 #build.sh #摄像头开发 #Makefile #内核编译 #OTA
版权声明
内容来源及使用限制
欢迎访问 TomgZHE研习社(网址:https://blog.tomgzhe.com)。本网站部分文章内容源自网络,仅作学习交流与参考分享;若您发现有内容涉嫌侵权,请立即联系 tomgzhe@qq.com,我们将在接到通知后的 48 小时内核实并删除相关侵权内容。
软件资源相关规定
本网站为个人非盈利性质的站点,所有软件资源均来自网络。这些资源仅用于个人学习、研究和参考,严禁用于任何商业用途。您下载和使用本网站软件资源即表示您同意仅将其用于学习目的,若因违反此规定导致任何法律纠纷或损失,责任由您自行承担。
原创版权
本网站上的原创内容,包括但不限于文字作品、自行设计的图片、独家制作的音频视频等,其版权均归本网站所有。未经本网站书面授权,任何组织或个人不得擅自复制、转载、摘编、传播或以其他任何方式使用这些原创内容。如需使用,请提前与我们联系并获得书面许可,同时需在显著位置注明出处及作者信息。
转载与引用规范
若您需转载本网站文章,务必注明文章来源为 “[ https://blog.tomgzhe.com/index.php/2026/07/13/t33-dual-sensor-build],原文链接:[ https://blog.tomgzhe.com/index.php/2026/07/13/t33-dual-sensor-build]”;对于有明确作者署名的文章,还需完整保留作者姓名。在引用本网站内容时,请确保内容准确无误,并遵循学术及行业的引用规范。
微信扫一扫打赏
支付宝扫一扫打赏