3. i.MX Yocto源码获取与Repo管理

NXP 的 i.MX Yocto BSP 发布包并不是一个单独的 Git 仓库,而是由 BSP 层、内核、U-Boot、Yocto/OE 核心、meta-freescale 系列层以及若干第三方组件共同组成的多仓库集合。NXP 通过 repo 工具和一份 manifest 清单把这些分散的仓库“绑定”为一个可复现的发布版本。因此,本节的核心不是简单地“下载源码”,而是理解 manifest 如何描述版本、分支与远程仓库,并用 repo 完成初始化、同步和目录结构检查。

一、Repo 与 Manifest 的关系

repo 是 Google 为 Android 开发的 Git 仓库管理工具,NXP 将其用于 i.MX BSP 的多仓库协同。它本身不存储源码,只负责按 manifest 中的描述去 clone、checkout 和同步各个 Git 仓库。manifest 是一个 XML 文件,通常位于 .repo/manifests/ 目录下,其中每个 <project> 节点描述一个仓库的远程地址、目标路径和版本。

NXP 的 manifest 命名通常形如 imx-6.6.23-2.0.0.xml,其中 6.6.23 是内核版本,2.0.0 是 BSP 发布版本。manifest 中还会通过 <default> 节点指定默认 remote 和 revision,通过 <include> 引入其他清单片段。理解这一点后,就能明白为什么切换 BSP 版本只需要切换 manifest 分支或指定不同的 XML 文件。

i.MX Yocto BSP 的 Repo / Manifest 多仓库结构 repo 工具 init / sync / manifest manifest XML(版本绑定清单) <default remote="origin" revision="imx-6.6.23-2.0.0"/> <project name="uboot-imx" path="sources/uboot-imx"/> 读取 远程 Git 仓库(NXP / Yocto / 第三方) poky Yocto/OE 核心 sources/poky meta-freescale i.MX BSP 层 sources/meta-freescale linux-imx NXP 内核 sources/linux-imx uboot-imx NXP U-Boot sources/uboot-imx meta-* 其他依赖层 sources/... 按 project 节点 clone/checkout 本地工作区(repo sync 后) .repo/ manifests / projects repo 元数据 sources/ poky / meta-freescale linux-imx / uboot-imx setup-environment 构建环境初始化脚本 由 BSP 层提供 build/ 构建输出目录 (后续生成) 同步到本地目录

二、初始化:repo init 的关键参数

初始化阶段决定后续同步的“版本基线”。典型命令如下:

mkdir imx-yocto-bsp && cd imx-yocto-bsp
repo init -u https://github.com/nxp-imx/imx-manifest \
          -b imx-linux-scarthgap \
          -m imx-6.6.23-2.0.0.xml

其中 -u 指定 manifest 仓库地址,-b 指定 manifest 仓库的分支(对应 Yocto 版本代号,如 scarthgap、kirkstone),-m 指定具体使用的 XML 文件。三者共同锁定 BSP 版本。若省略 -m,repo 会使用该分支下的默认 manifest,可能不是期望的发布版本,因此生产环境中建议显式指定。

执行成功后,当前目录会出现隐藏目录 .repo/,其中 .repo/manifests/ 保存 manifest 仓库,.repo/manifest.xml 是指向实际使用 XML 的符号链接。可以用 repo manifest -o manifest-snapshot.xml -r 导出当前实际生效的清单快照,便于版本归档和问题复现。

三、同步:repo sync 的行为与常用选项

repo sync 会遍历 manifest 中所有 project,逐个执行 fetch 和 checkout。首次同步数据量较大,i.MX BSP 完整源码通常在 10 GB 以上,建议使用 -j 控制并发数:

repo sync -j8 --no-tags --no-clone-bundle

-j8 表示同时同步 8 个仓库,可根据网络和 CPU 调整;--no-tags 跳过标签下载,减少数据量;--no-clone-bundle 避免使用 clone bundle 加速包,在网络受限时更稳定。若中途失败,直接重新执行 repo sync 即可续传,repo 会跳过已完成的仓库。

同步完成后,可用 repo status 查看各仓库是否有本地修改,用 repo forall -c 'git log -1 --oneline' 快速确认每个仓库当前所处的提交。这一步在排查“为什么构建结果与预期不一致”时非常关键,因为 manifest 只保证版本基线,本地改动仍可能引入偏差。

四、目录结构检查

同步结束后,应检查目录结构是否符合 BSP 预期。典型 i.MX Yocto 工作区包含:sources/ 下存放 poky、meta-freescale、meta-freescale-distro、meta-imx 等层,以及 linux-imx、uboot-imx 等源码仓库;setup-environment 脚本由 meta-imx 层提供,用于初始化构建环境;.repo/ 保存 repo 元数据。若 sources/ 下缺少某个层,通常说明 manifest 中对应 project 未同步成功,应回到 repo sync 日志中定位。

建议在首次同步完成后执行一次 repo manifest -r -o manifest-snapshot.xml,把实际提交号固化下来。后续若需要复现同一版本,可直接用该快照文件初始化,避免上游分支更新导致版本漂移。

五、分支切换与远程仓库管理

当需要从 scarthgap 切换到 kirkstone 时,不能只改 -b 后重新 init,因为 .repo/manifests 已存在。正确做法是:

repo init -u https://github.com/nxp-imx/imx-manifest \
          -b imx-linux-kirkstone \
          -m imx-6.1.55-2.2.0.xml
repo sync -j8

repo 会更新 manifest 仓库并重新解析 project 列表,随后 sync 会把各仓库切换到新版本。若某些仓库存在本地未提交修改,sync 可能失败,此时应先用 repo forall -c 'git stash' 暂存,或确认修改不再需要后清理。

远程仓库地址由 manifest 中的 remote 节点定义,默认指向 NXP 的 GitHub 镜像。若企业内网需要走私有镜像,可在 manifest 中替换 remote 的 fetch 地址,或使用 repo init 的 --repo-url 与 --no-repo-verify 等参数配合内部镜像。修改 remote 后必须重新 sync,否则各仓库仍指向旧地址。

六、常见问题与判断依据

同步过程中最常见的问题是网络超时和 manifest 解析失败。若 repo init 报 “manifest not found”,应检查 -b 分支与 -m 文件名是否匹配,可先在浏览器中访问 manifest 仓库确认文件存在。若 repo sync 在某个仓库反复失败,可单独进入该仓库目录执行 git fetch 观察具体错误,再决定是否更换 remote 或调整并发数。

判断同步是否真正完成,不能只看命令是否返回 0,还应检查 sources/ 下各层目录是否非空、repo status 是否干净、以及 repo forall -c 'git rev-parse HEAD' 是否都能输出提交号。只有这三项都正常,才说明源码获取与 repo 管理阶段真正完成,可以进入后续的环境初始化与构建阶段。