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 文件。
二、初始化: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 管理阶段真正完成,可以进入后续的环境初始化与构建阶段。