2. 开发环境与源码获取

STM32MP1 系列(如 STM32MP157、STM32MP135)运行的是完整 Linux 系统,宿主机(通常是 x86_64 Ubuntu)无法直接编译出能在 ARM Cortex-A7 上运行的二进制。因此 BSP 移植的第一步不是改代码,而是把"能编译、能取源码、能组织构建"这三件事做扎实。本节围绕交叉编译工具链、OpenSTLinux 源码获取、repo 与构建目录配置展开,目标是得到一个可复现、可切换 SDK 版本的工程化工作区。

一、交叉编译工具链:为什么不能直接用 gcc

宿主机 gcc 生成的是 x86_64 指令,而 STM32MP1 的 A7 核需要 ARMv7-A 指令集,且用户态要链接目标板的 glibc、内核头文件与动态加载器。交叉工具链把"编译平台"和"运行平台"分离:在 x86_64 上运行 arm-ostl-linux-gnueabi-gcc,产出 ARM ELF。ST 官方推荐使用 OpenSTLinux SDK 自带的工具链,它与 Yocto 构建出的 rootfs、内核版本严格匹配,能避免 libc 版本错配导致的运行时崩溃。

SDK 安装包通常命名为 st-image-weston-openstlinux-weston-stm32mp1-x86_64-toolchain-*.sh。安装时指定一个独立目录,例如 /opt/st/stm32mp1/5.0-openstlinux-6.1-yocto-mickledore,避免污染系统路径。安装完成后必须 source 环境脚本,让 PATH、CC、CXX、SDKTARGETSYSROOT 等变量生效:

# 安装 SDK(示例路径与版本,请以实际下载包为准)
./st-image-weston-openstlinux-weston-stm32mp1-x86_64-toolchain-5.0.sh \
    -d /opt/st/stm32mp1/5.0-openstlinux-6.1-yocto-mickledore

# 激活 SDK 环境
source /opt/st/stm32mp1/5.0-openstlinux-6.1-yocto-mickledore/environment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi

# 验证:应输出 ARM 目标信息,而非 x86_64
echo $CC
$CC --version
$CC -dumpmachine   # 期望类似 arm-ostl-linux-gnueabi

判断工具链是否可用的关键不是"命令存在",而是"能产出目标架构可执行文件"。写一个最小 hello.c,用 $CC hello.c -o hello 编译,再用 file hello 检查,输出应包含 ELF 32-bit LSB executable, ARM, EABI5。若显示 x86-64,说明 CC 未生效或误用了系统 gcc。这一步是后续所有内核、U-Boot、应用编译的前提。

二、获取 OpenSTLinux 源码:repo 与 manifest

OpenSTLinux 由数百个 Yocto 层和组件组成,ST 用 Google 的 repo 工具统一管理。repo 本身是一个 Python 脚本,负责按 manifest XML 批量 clone 多个 git 仓库。先安装 repo 并配置 git 身份:

mkdir -p ~/bin
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
chmod a+x ~/bin/repo
export PATH=~/bin:$PATH

git config --global user.name  "bsp-dev"
git config --global user.email "bsp-dev@example.com"

接着用 ST 提供的 manifest 初始化工作区。manifest 决定了各组件(内核、U-Boot、TF-A、OP-TEE、meta-st 层)的版本与分支,是"源码一致性"的核心。以 STM32MP1 生态版本 v5.0(对应 Linux 6.1、Yocto mickledore)为例:

mkdir -p ~/stm32mp1-bsp && cd ~/stm32mp1-bsp
repo init -u https://github.com/STMicroelectronics/oe-manifest.git \
          -b refs/tags/openstlinux-6.1-yocto-mickledore-v5.0
repo sync -j8

repo sync 会拉取全部仓库,首次耗时较长。完成后目录中会出现 layers/、.repo/ 等结构。可用 repo manifest -r -o pinned.xml 导出当前各仓库的精确 commit,作为可复现构建的"锁文件";团队协作时把它纳入版本管理,能保证不同人构建出相同结果。

三、构建目录与 Yocto 环境配置

Yocto 的构建目录(build dir)与源码层分离,所有临时文件、镜像、SDK 都生成在这里。标准做法是在源码根目录下创建 build- 目录,再 source 初始化脚本:

cd ~/stm32mp1-bsp
DISTRO=openstlinux-weston MACHINE=stm32mp15-disco \
    source layers/meta-st/scripts/envsetup.sh

该脚本会自动创建 build-openstlinux-weston 目录并进入其中,同时生成 conf/local.conf 与 conf/bblayers.conf。MACHINE 决定目标板(如 stm32mp15-disco、stm32mp15-ev1、stm32mp13-disco),DISTRO 决定图形栈(weston 或 openstlinux-eglfs)。这两个变量一旦选错,后续镜像无法在目标板启动,因此必须在构建前确认。

常用构建命令:bitbake st-image-weston 生成完整镜像;bitbake virtual/kernel 只编译内核;bitbake meta-toolchain 生成 SDK。构建产物位于 tmp-glibc/deploy/images/stm32mp15-disco/,其中 .wic 是可直接烧录到 SD 卡的镜像,.tar.xz 是 SDK 安装包。

若网络受限,可在 local.conf 中配置 DL_DIR 与 SSTATE_DIR 指向共享缓存目录,避免重复下载与重复编译,显著缩短二次构建时间。

四、环境自检与常见问题

搭建完成后建议做一次闭环自检:工具链能编译 ARM 程序、repo 工作区完整、bitbake 能解析配方。可用 bitbake -e virtual/kernel | grep ^S= 快速确认内核源码路径是否被正确解析。常见问题包括:repo 未加入 PATH 导致 repo: command not found;manifest 分支写错导致 sync 失败;MACHINE 与目标板不匹配导致镜像无法启动;SDK 未 source 导致 CC 仍指向 x86_64。这些问题在构建前排查,远比在目标板启动失败后回溯成本低。

STM32MP1 BSP 开发环境搭建与源码获取流程 宿主机 Ubuntu x86_64 git / repo / python3 磁盘 ≥ 100GB,内存 ≥ 8GB 交叉编译工具链 (SDK) arm-ostl-linux-gnueabi-gcc source environment-setup-* OpenSTLinux 源码 repo init + repo sync oe-manifest / meta-st 层 构建目录 build-* DISTRO=openstlinux-weston MACHINE=stm32mp15-disco conf/local.conf · bblayers.conf 构建产物 st-image-weston.wic virtual/kernel · U-Boot meta-toolchain SDK 环境自检闭环 ① $CC -dumpmachine → arm-ostl-linux-gnueabi ② file hello → ELF 32-bit ARM EABI5 ③ bitbake -e virtual/kernel | grep ^S=