TF-M 使用 Ninja 构建

本文详细介绍了使用Ninja构建ARM TrustZone-M(TF-M)Secure和Non-Secure固件的完整流程,涵盖CMake配置、NS接口导出、依赖管理、增量编译、QEMU单镜像加载启动及常见问题排查。重点解决镜像地址重叠、分区配置残留、imagesign_wrapper缺失、BL2验证失败等典型构建与运行问题,并强调MPS2 AN521平台下Secure+NS组合镜像的正确生成与加载方法。

使用 Ninja 编译和运行 BL2、TF-M Secure 与 Non-Secure

前面已经搭好 TF-M 构建环境,这里使用 Ninja 编译 Secure 和 Non-Secure 示例,再通过 QEMU 启动。

使用 Ninja 构建 Secure

配置

cd "/home/tyustli/Desktop/tyustli/study/code/qemu/trust_firmware/tfm/code/trusted-firmware-m"
source env/bin/activate
cmake -S . -B build_an521_ninja -G Ninja \
    -DTFM_PLATFORM=arm/mps2/an521 \
    -DCMAKE_BUILD_TYPE=Debug
  • -S . 指定源码目录,. 表示当前的 trusted-firmware-m 目录,从这里读取顶层 CMakeLists.txt。
  • -B build_an521_ninja 指定构建目录,用于保存构建规则、配置缓存和编译产物,目录不存在时自动创建。
  • -G Ninja 选择 Ninja 生成器,在构建目录生成 build.ninja,后续由 Ninja 执行编译。
  • -DTFM_PLATFORM=arm/mps2/an521 设置 TF-M 的目标平台,使用 MPS2 AN521 对应的平台配置。-D 表示设置 CMake 配置变量。
  • -DCMAKE_BUILD_TYPE=Debug 选择调试构建,便于使用 GDB 调试,具体调试信息和优化选项由工程与工具链配置决定。

先使用基本配置编译,遇到问题再按后面对应的小节处理。默认使用 GNU Arm 工具链并启用 BL2,不需要重复指定。

不需要手动创建 build_an521_ninja,CMake 会自动创建。需要 compile_commands.json 时,再执行下面的命令,无需修改 CMakeLists.txt。

cmake -S . -B build_an521_ninja -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
  • -S . 指定当前目录为源码目录。
  • -B build_an521_ninja 使用已有构建目录,保留其中的其他配置。
  • -DCMAKE_EXPORT_COMPILE_COMMANDS=ON 开启编译命令导出,生成 compile_commands.json,供 clangd 等工具查询源文件的编译参数。

首次配置会下载 CMSIS、MCUboot、TF-PSA-Crypto 等依赖,并放在 build_an521_ninja/lib/ext/。这一步需要网络,外层的 tf-m-extras 用于构建 NS 示例,TF-M 也可能为自己的扩展依赖单独下载一份。

编译并导出 NS 接口

cmake --build build_an521_ninja --target install --parallel
  • --build build_an521_ninja 构建已经配置好的 build_an521_ninja 目录,CMake 会调用其中对应的构建工具。
  • --target install 执行安装目标,先构建固件,再导出 NS 工程需要的文件到 build_an521_ninja/api_ns/。
  • --parallel 启用并行构建,未指定任务数时采用环境或底层构建工具的默认设置。

对应的 Ninja 原生命令如下,二选一执行即可。

ninja -C build_an521_ninja install
  • -C build_an521_ninja 让 Ninja 进入该构建目录执行。
  • install 指定安装目标,构建并导出 NS 工程需要的文件。

install 会先构建固件,再把 NS 工程需要的接口、平台文件、签名材料和配置导出到 build_an521_ninja/api_ns/,无需 sudo。

主要输出如下。

build_an521_ninja/
├── bin/
│   ├── bl2.axf
│   ├── bl2.hex
│   ├── tfm_s.axf
│   └── tfm_s.bin
├── api_ns/
│   ├── bin/
│   ├── cmake/
│   ├── config/
│   ├── image_signing/
│   ├── interface/
│   └── platform/
└── compile_commands.json    开启导出后生成

清理

cmake --build build_an521_ninja --target clean
  • --build build_an521_ninja 使用该目录中已有的构建规则。
  • --target clean 执行清理目标,删除编译产物及工程额外指定的生成文件,重新构建的步骤见后面的清理小节。

使用 Ninja 构建 Non-Secure

先完成前面 Ninja 方式的 Secure 构建和 install,再配置 NS 工程。

配置

cd /home/tyustli/Desktop/tyustli/study/code/qemu/trust_firmware/tfm/code/tf-m-extras/examples/tf-m-example-ns-app
source /home/tyustli/Desktop/tyustli/study/code/qemu/trust_firmware/tfm/code/trusted-firmware-m/env/bin/activate
cmake -S . -B build -G Ninja \
    -DCONFIG_SPE_PATH="/home/tyustli/Desktop/tyustli/study/code/qemu/trust_firmware/tfm/code/trusted-firmware-m/build_an521_ninja/api_ns" \
    -DTFM_TOOLCHAIN=GNUARM
  • -S . 指定当前的 NS 示例源码目录。
  • -B build 指定 NS 构建目录,与 Secure 的构建目录分开。
  • -G Ninja 选择 Ninja 生成器。
  • -DCONFIG_SPE_PATH=.../build_an521_ninja/api_ns 指向对应 Secure 构建导出的接口、配置和签名材料。
  • -DTFM_TOOLCHAIN=GNUARM 选择 GNU Arm 工具链。

配置报错

如果 Secure 只使用前面的基本配置,尚未启用相关安全分区,NS 配置可能在生成阶段报错。

工具链警告出现在未指定 TFM_TOOLCHAIN 时;上面的命令已经指定 GNUARM,通常不会再出现这两条警告。

1/api_ns"     -DTFM_TOOLCHAIN=GNUARM
-- The C compiler identification is GNU 14.3.1
-- The ASM compiler identification is GNU
-- Found assembler: /home/tyustli/Desktop/tools/toolchains/arm-gnu-toolchain-14.3.rel1-x86_64-arm-none-eabi/bin/arm-none-eabi-gcc
-- Found Python3: /home/tyustli/Desktop/tyustli/study/code/qemu/trust_firmware/tfm/code/trusted-firmware-m/env/bin/python3 (found version "3.12.3") found components: Interpreter
-- Configuring done (0.2s)
CMake Error at /home/tyustli/Desktop/tyustli/study/code/qemu/trust_firmware/tfm/code/trusted-firmware-m/build_an521_ninja/api_ns/CMakeLists.txt:33 (add_library):
  No SOURCES given to target: tfm_api_ns

解决方法

tfm_api_ns 的源文件由 Secure 启用的安全分区决定,相关分区全部关闭时,这个库就没有源文件。先重新配置 TF-M,启用安全分区并导出 NS 接口,再回到 NS 工程。

下面启用 Crypto、ITS、PS 和 Platform 的配置。示例调用 psa_generate_random(),需要 Crypto 及其依赖的 ITS。这里也把 MCUBOOT_IMAGE_NUMBER 改为 1,为后面的 Secure + NS 组合镜像做准备。

配置 TF-M
cd /home/tyustli/Desktop/tyustli/study/code/qemu/trust_firmware/tfm/code/trusted-firmware-m
source env/bin/activate
cmake -S . -B build_an521_ninja -G Ninja \
    -DTFM_PLATFORM=arm/mps2/an521 \
    -DCMAKE_BUILD_TYPE=Debug \
    -DMCUBOOT_IMAGE_NUMBER=1 \
    -DTFM_PARTITION_CRYPTO=ON \
    -DTFM_PARTITION_INTERNAL_TRUSTED_STORAGE=ON \
    -DTFM_PARTITION_PROTECTED_STORAGE=ON \
    -DTFM_PARTITION_PLATFORM=ON
  • -S . 指定当前 TF-M 源码目录。
  • -B build_an521_ninja 更新原来的 Secure 构建目录,保留已下载的依赖。
  • -G Ninja 沿用 Ninja 生成器。
  • -DTFM_PLATFORM=arm/mps2/an521 选择 MPS2 AN521 平台。
  • -DCMAKE_BUILD_TYPE=Debug 使用调试构建。
  • -DMCUBOOT_IMAGE_NUMBER=1 将 Secure 和 NS 合并为一个镜像签名和验证,组合镜像仍然需要包含 NS 程序。
  • -DTFM_PARTITION_CRYPTO=ON 启用密码服务,包括示例使用的随机数生成。
  • -DTFM_PARTITION_INTERNAL_TRUSTED_STORAGE=ON 启用内部可信存储。
  • -DTFM_PARTITION_PROTECTED_STORAGE=ON 启用受保护存储。
  • -DTFM_PARTITION_PLATFORM=ON 启用平台相关的 PSA 服务。

配置完成的日志如下

----------- Secure Partitions ------------------------
   Non-Secure Mailbox Agent                  OFF
   Protected Storage Partition               ON
   TF-M Internal Trusted Storage Partition   ON
   TFM Crypto Partition                      ON
   TFM Platform Partition                    ON
   TFM Initial Attestation Partition         OFF
   TFM Firmware Update Partition             OFF
------------------------------------------------------
编译 TF-M
cmake --build build_an521_ninja --parallel
  • --build build_an521_ninja 根据新配置重新构建 Secure。
  • --parallel 启用并行构建。
安装 NS 接口
cmake --build build_an521_ninja --target install --parallel
  • --build build_an521_ninja 使用刚才的 Secure 构建目录。
  • --target install 更新导出的 NS 接口、平台配置和签名材料,输出到 build_an521_ninja/api_ns/。
  • --parallel 在需要补编译时启用并行构建。

install 本身会先构建再导出文件,也可以直接执行这一步,代替单独编译和安装两步。

重新配置 NS
cd /home/tyustli/Desktop/tyustli/study/code/qemu/trust_firmware/tfm/code/tf-m-extras/examples/tf-m-example-ns-app
cmake -S . -B build -G Ninja \
    -U 'TFM_PARTITION_*' \
    -DCONFIG_SPE_PATH="/home/tyustli/Desktop/tyustli/study/code/qemu/trust_firmware/tfm/code/trusted-firmware-m/build_an521_ninja/api_ns" \
    -DTFM_TOOLCHAIN=GNUARM
  • -S . 指定切换目录后的 NS 源码目录。
  • -B build 沿用原来的 NS 构建目录。
  • -G Ninja 沿用 Ninja 生成器。
  • -U 'TFM_PARTITION_*' 清除 NS 缓存中的旧分区配置,重新读取 Secure 导出的值。引号防止 Shell 展开通配符。
  • -DCONFIG_SPE_PATH=.../build_an521_ninja/api_ns 使用这次更新后的 Secure 导出接口。
  • -DTFM_TOOLCHAIN=GNUARM 继续使用 GNU Arm 工具链。

首次配置失败后,NS 缓存可能保留分区的 OFF 值。这里仅清除 NS 的这组缓存,无需删除 Secure 构建目录或重新下载依赖。

编译 NS

配置成功后,再执行编译。

cmake --build build --parallel
  • --build build 构建配置完成的 NS 工程。
  • --parallel 启用并行构建。

查看产物

tree build -L 1
  • build 指定要查看的 NS 构建目录。
  • -L 1 只显示目录下的第一层内容。

按上面的单镜像配置重新构建后,主要输出如下,其他缓存文件省略。

build/
├── bin/
├── build.ninja
├── spe/
├── tfm_s_ns_signed.bin
└── tfm_s_ns_signed.hex

bin/ 下还有 tfm_ns.axf 和 tfm_ns.bin。tfm_s_ns_signed.hex 包含 Secure 和 Non-Secure。修改 Secure 配置或代码后,先重新构建并安装 Secure,再重新配置、编译 NS,避免使用旧的导出文件。

QEMU 启动

前面的 NS 处理步骤将 MCUBOOT_IMAGE_NUMBER 设为 1,重新构建 Secure 和 NS 后,会得到 bl2.hex 和 tfm_s_ns_signed.hex。先从加载三个镜像时遇到的问题说起。

尝试加载三个镜像

把 BL2、单独的 Secure 镜像和 Secure + NS 组合镜像一起加载,命令如下。

qemu-system-arm \
    -M mps2-an521 \
    -cpu cortex-m33 \
    -nographic \
    -device loader,file="/home/tyustli/Desktop/tyustli/study/code/qemu/trust_firmware/tfm/code/trusted-firmware-m/build_an521_ninja/bin/bl2.hex" \
    -device loader,file="/home/tyustli/Desktop/tyustli/study/code/qemu/trust_firmware/tfm/code/trusted-firmware-m/build_an521_ninja/bin/tfm_s_signed.hex" \
    -device loader,file="/home/tyustli/Desktop/tyustli/study/code/qemu/trust_firmware/tfm/code/tf-m-extras/examples/tf-m-example-ns-app/build/tfm_s_ns_signed.hex"
  • -M mps2-an521 选择 MPS2 AN521 开发板模型。
  • -cpu cortex-m33 指定 Cortex-M33 处理器。
  • -nographic 关闭图形窗口,将串口和监视器复用到当前终端。
  • -device loader,file=.../bl2.hex 加载 BL2 引导程序。
  • -device loader,file=.../tfm_s_signed.hex 加载单独的 Secure 签名镜像。
  • -device loader,file=.../tfm_s_ns_signed.hex 加载包含 Secure 和 NS 的组合签名镜像。

启动报错

同时加载这些镜像时,出现了下面的报错。

rom: requested regions overlap (rom /home/ub22/lx/qemu/tf-m-extras/examples/tf-m-example-ns-app/build/tfm_s_ns_signed.hex. free=0x0000000010090000, addr=0x0000000010080000)
qemu-system-arm: rom check and register reset failed

requested regions overlap 表示镜像要写入的内存区域发生重叠。QEMU 在检查镜像装载区域时失败,还没有运行到 BL2 验证固件的阶段。

原因分析

这条命令加载了三个 HEX 文件。

bl2.hex
tfm_s_signed.hex
tfm_s_ns_signed.hex

bl2.hex 是 BL2 引导程序,当前 AN521 构建中的起始地址为 0x10000000。

tfm_s_signed.hex 是单独的 Secure 签名镜像,当前 AN521 构建中的起始地址为 0x10080000。这个地址指镜像装载位置,固件入口还要考虑镜像头。

tfm_s_ns_signed.hex 在这里的单镜像配置下,包含 Secure 和 Non-Secure 两部分。其加载关系如下。

tfm_s_ns_signed.hex
    = Secure + Non-Secure

因此,同时加载三个文件相当于下面的关系。

bl2.hex + tfm_s_signed.hex + tfm_s_ns_signed.hex
    = BL2 + Secure +(Secure + Non-Secure)

Secure 区域被加载了两次,于是 QEMU 报地址重叠。报错中的 addr=0x0000000010080000 也对应这次冲突的装载地址。

HEX 文件本身带有装载地址,loader 会按文件中的地址放置数据,这里无需再指定 addr。

解决方法

删除加载 tfm_s_signed.hex 的那一项。

-device loader,file=.../build_an521_ninja/bin/tfm_s_signed.hex

只保留 bl2.hex 和 tfm_s_ns_signed.hex,分别加载引导程序和包含 Secure、NS 的组合签名镜像。

启动命令
qemu-system-arm \
    -M mps2-an521 \
    -cpu cortex-m33 \
    -nographic \
    -device loader,file="/home/tyustli/Desktop/tyustli/study/code/qemu/trust_firmware/tfm/code/trusted-firmware-m/build_an521_ninja/bin/bl2.hex" \
    -device loader,file="/home/tyustli/Desktop/tyustli/study/code/qemu/trust_firmware/tfm/code/tf-m-extras/examples/tf-m-example-ns-app/build/tfm_s_ns_signed.hex"
  • -M mps2-an521 选择 AN521 开发板模型。
  • -cpu cortex-m33 指定 Cortex-M33 处理器。
  • -nographic 在当前终端显示串口输出。
  • 第一个 -device loader,file=... 加载 Ninja 构建的 build_an521_ninja/bin/bl2.hex。
  • 第二个 -device loader,file=... 加载 NS 工程 build/tfm_s_ns_signed.hex,其中已经包含 Secure。

镜像来自同一套配置时,启动后可以看到 BL2、TF-M 和 Hello TF-M world 的输出,完整日志保留在文末。

调试与退出

需要 GDB 调试时,在启动命令末尾追加 -S -s。

  • -S 启动时暂停处理器,等待调试器连接后继续执行。
  • -s 开启 GDB 调试端口,等价于 -gdb tcp::1234。

退出 QEMU 使用 Ctrl+A,松开后按 X。

日常修改与重新构建

只修改源码

直接增量编译即可,不必先 clean。以 Ninja 为例。

cd "/home/tyustli/Desktop/tyustli/study/code/qemu/trust_firmware/tfm/code/trusted-firmware-m"
cmake --build build_an521_ninja --target install --parallel
cd "/home/tyustli/Desktop/tyustli/study/code/qemu/trust_firmware/tfm/code/tf-m-extras/examples/tf-m-example-ns-app"
cmake -S . -B build
cmake --build build --parallel
  • --build build_an521_ninja 增量构建 Secure,只重新处理受修改影响的目标。
  • --target install 更新导出的 NS 接口及相关文件。
  • -S . 指定切换目录后的 NS 工程为源码目录。
  • -B build 使用 NS 已有的构建目录,重新读取 Secure 导出的配置。
  • --build build 增量构建 NS。
  • --parallel 启用并行构建,分别用于两次构建。

修改配置

在原构建目录上重新运行 CMake,修改需要改变的 -D 参数,然后重新编译。已有缓存会保留其余配置和依赖路径。

cd "/home/tyustli/Desktop/tyustli/study/code/qemu/trust_firmware/tfm/code/trusted-firmware-m"
cmake -S . -B build_an521_ninja -DCMAKE_BUILD_TYPE=Debug
cmake --build build_an521_ninja --target install --parallel
  • -S . 指定当前 TF-M 源码目录。
  • -B build_an521_ninja 在原构建目录上更新配置,保留未修改的缓存项。
  • -DCMAKE_BUILD_TYPE=Debug 将构建类型设置为 Debug。
  • --build build_an521_ninja 按更新后的配置构建。
  • --target install 更新固件和导出的 NS 接口。
  • --parallel 启用并行构建。

通常不需要删除 CMakeCache.txt。删缓存会丢失原先的配置与本地依赖路径,恢复配置时还需要重新提供完整参数。

重新配置后分区仍显示 ON

之前通过 -DTFM_PARTITION_CRYPTO=ON 等参数启用分区后,再执行基本配置命令,分区仍可能显示 ON。

cd /home/tyustli/Desktop/tyustli/study/code/qemu/trust_firmware/tfm/code/trusted-firmware-m
cmake -S . -B build_an521_ninja -G Ninja \
    -DTFM_PLATFORM=arm/mps2/an521 \
    -DCMAKE_BUILD_TYPE=Debug
  • -S . 指定当前 TF-M 源码目录。
  • -B build_an521_ninja 复用已有的构建目录和配置缓存。
  • -G Ninja 沿用 Ninja 生成器。
  • -DTFM_PLATFORM=arm/mps2/an521 指定目标平台。
  • -DCMAKE_BUILD_TYPE=Debug 设置调试构建,其他未指定的缓存项继续保留。
----------- Secure Partitions ------------------------
   Non-Secure Mailbox Agent                  OFF
   Protected Storage Partition               ON
   TF-M Internal Trusted Storage Partition   ON
   TFM Crypto Partition                      ON
   TFM Platform Partition                    ON
   TFM Initial Attestation Partition         OFF
   TFM Firmware Update Partition             OFF
原因

-D 设置的配置会写入 build_an521_ninja/CMakeCache.txt。再次配置同一个构建目录时,CMake 会读取这些缓存。命令中省略之前的分区参数,只表示这次不修改它们,已经保存的 ON 会继续生效。

这里显示的是之前保存的配置。当前基本配置中这些分区的初始值为 OFF,重新运行 CMake 不会自动恢复初始值,普通 clean 也不会重置配置缓存。

查看缓存
grep 'TFM_PARTITION' build_an521_ninja/CMakeCache.txt

之前启用过这四个分区时,可以看到类似内容。

TFM_PARTITION_CRYPTO:BOOL=ON
TFM_PARTITION_INTERNAL_TRUSTED_STORAGE:BOOL=ON
TFM_PARTITION_PLATFORM:BOOL=ON
TFM_PARTITION_PROTECTED_STORAGE:BOOL=ON
显式改回 OFF

只想关闭这些分区时,直接覆盖缓存,不需要删除构建目录。

cmake -S . -B build_an521_ninja -G Ninja \
    -DTFM_PLATFORM=arm/mps2/an521 \
    -DCMAKE_BUILD_TYPE=Debug \
    -DTFM_PARTITION_CRYPTO=OFF \
    -DTFM_PARTITION_INTERNAL_TRUSTED_STORAGE=OFF \
    -DTFM_PARTITION_PLATFORM=OFF \
    -DTFM_PARTITION_PROTECTED_STORAGE=OFF
  • -S . 指定 TF-M 源码目录。
  • -B build_an521_ninja 更新已有构建目录,保留其他缓存和已下载的依赖。
  • -G Ninja 沿用 Ninja 生成器。
  • -DTFM_PLATFORM=arm/mps2/an521 保持 AN521 平台。
  • -DCMAKE_BUILD_TYPE=Debug 保持调试构建。
  • -DTFM_PARTITION_CRYPTO=OFF 关闭 Crypto 分区。
  • -DTFM_PARTITION_INTERNAL_TRUSTED_STORAGE=OFF 关闭 ITS 分区。
  • -DTFM_PARTITION_PLATFORM=OFF 关闭 Platform 分区。
  • -DTFM_PARTITION_PROTECTED_STORAGE=OFF 关闭 PS 分区。

重新配置后,上面四项会显示 OFF。配置命令只更新构建规则,实际固件还要重新编译。后续运行前面的 NS 随机数示例时,需要按 NS 章节重新启用所需分区,并重新构建、导出接口。

删除整个构建目录后重新配置

需要从头配置时,可以删除整个构建目录,再执行基本配置命令。

cd /home/tyustli/Desktop/tyustli/study/code/qemu/trust_firmware/tfm/code/trusted-firmware-m
rm -rf build_an521_ninja
cmake -S . -B build_an521_ninja -G Ninja \
    -DTFM_PLATFORM=arm/mps2/an521 \
    -DCMAKE_BUILD_TYPE=Debug
  • rm -rf build_an521_ninja 删除整个构建目录,包括缓存、编译产物和目录内下载的依赖源码。
  • -S . 指定 TF-M 源码目录。
  • -B build_an521_ninja 创建新的构建目录。
  • -G Ninja 重新生成 Ninja 构建规则。
  • -DTFM_PLATFORM=arm/mps2/an521 重新指定平台。
  • -DCMAKE_BUILD_TYPE=Debug 重新指定构建类型。

这会清除该目录保存的全部配置。自动下载的依赖通常位于 build_an521_ninja/lib/ext/,删除整个目录后,下次配置需要重新下载;使用构建目录外的本地依赖时,需要重新提供对应的路径配置。只改分区开关时,优先使用前面的显式覆盖方法。

删除构建目录,但是保留外部下载的代码

将构建目录除了 build_an521_ninja/lib/ext 目录下的所有文件夹都删除,只保留这个文件夹,重新构建的时候加入下面的编译选项,

FETCHCONTENT_FULLY_DISCONNECTED=ON

这个编译选项的作用是强制离线,禁止自动下载

需要清理产物时

Ninja 清理后,先重新配置,再构建。TF-M 的 clean 会删除 generated/ 等生成文件,重新配置可以补齐这些文件。

cd "/home/tyustli/Desktop/tyustli/study/code/qemu/trust_firmware/tfm/code/trusted-firmware-m"
cmake --build build_an521_ninja --target clean
cmake -S . -B build_an521_ninja
cmake --build build_an521_ninja --target install --parallel
  • --build build_an521_ninja 使用 Secure 的构建目录执行指定目标。
  • --target clean 清理编译产物及额外生成文件。
  • -S . 指定 TF-M 源码目录,重新运行配置。
  • -B build_an521_ninja 沿用已有构建目录和缓存,重新生成被 clean 删除的配置产物。
  • --target install 重新构建并导出 NS 接口。
  • --parallel 启用并行构建。

原生清理命令为 ninja -C build_an521_ninja clean。

  • -C build_an521_ninja 指定 Ninja 执行清理的构建目录。
  • clean 执行清理目标。

遇到的问题

pip 提示不是 Python 工程

ERROR: file:///home/tyustli/Desktop/tyustli/study/code/qemu does not appear to be a Python project: neither 'setup.py' nor 'pyproject.toml' found.

这是在外层 qemu 目录执行 python -m pip install -e . 导致的。切换到 TF-M 源码目录,再使用已有的 env 安装。

cd /home/tyustli/Desktop/tyustli/study/code/qemu/trust_firmware/tfm/code/trusted-firmware-m
source env/bin/activate
python -m pip install -e .

找不到 imagesign_wrapper

/bin/sh: 1: mcuboot_imagesign_wrapper: not found

先激活环境并安装 TF-M 自己的 Python 包,再继续原来的构建。

cd "/home/tyustli/Desktop/tyustli/study/code/qemu/trust_firmware/tfm/code/trusted-firmware-m"
source env/bin/activate
python -m pip install -e .
command -v mcuboot_imagesign_wrapper
command -v mcuboot_imagesign_assemble
cmake --build build_an521_ninja --target install --parallel
  • --build build_an521_ninja 在安装 Python 工具后继续构建原来的 Secure 工程。
  • --target install 构建固件并更新导出的 NS 接口。
  • --parallel 启用并行构建。

如果激活 env 后仍使用系统 Python,再指定虚拟环境中的解释器。

cmake -S . -B build_an521_ninja \
    -DPython3_EXECUTABLE="/home/tyustli/Desktop/tyustli/study/code/qemu/trust_firmware/tfm/code/trusted-firmware-m/env/bin/python"
cmake --build build_an521_ninja --target install --parallel
  • -S . 指定当前 TF-M 源码目录。
  • -B build_an521_ninja 更新原构建目录中的 Python 配置。
  • -DPython3_EXECUTABLE=.../env/bin/python 指定 CMake 使用 env 中的 Python 解释器运行相关脚本。
  • --build build_an521_ninja 按更新后的配置继续构建。
  • --target install 构建并导出 NS 接口。
  • --parallel 启用并行构建。

NS 工程遇到相同问题时,在 NS 目录执行 cmake -S . -B build 并追加同一个 -DPython3_EXECUTABLE 参数。签名命令本身还需要能从 PATH 找到,所以构建时也要保持 env 已激活。

BL2 找不到可启动镜像

[INF] Starting bootloader
[INF] Beginning BL2 provisioning
[WRN] TFM_DUMMY_PROVISIONING is not suitable for production! This device is NOT SECURE
[INF] PSA Crypto init done, sig_type: EC-P256, using builtin keys
[INF] Image index: 1, Swap type: none
[ERR] Image in the primary slot is not valid!
[ERR] Unable to find bootable image

MCUBOOT_IMAGE_NUMBER=2 时,BL2 分别验证 Secure 和 Non-Secure。只加载 Secure,没有有效的 NS 镜像,就可能在 Image index: 1 报错。

这里改用 MCUBOOT_IMAGE_NUMBER=1,将 Secure 与 Non-Secure 合并后作为一个镜像签名和验证。

在原构建目录上修改配置,然后重新构建、安装 Secure,再编译 NS。

cd /home/tyustli/Desktop/tyustli/study/code/qemu/trust_firmware/tfm/code/trusted-firmware-m
cmake -S . -B build_an521_ninja -DMCUBOOT_IMAGE_NUMBER=1
cmake --build build_an521_ninja --target install --parallel
cd /home/tyustli/Desktop/tyustli/study/code/qemu/trust_firmware/tfm/code/tf-m-extras/examples/tf-m-example-ns-app
cmake -S . -B build
cmake --build build --parallel
  • -S . 分别指定 cd 后的 Secure 或 NS 源码目录。
  • -B build_an521_ninja 更新 Secure 原有构建目录中的配置。
  • -DMCUBOOT_IMAGE_NUMBER=1 将 Secure 和 NS 合并为一个镜像签名,由 BL2 按单镜像方式验证。
  • --build build_an521_ninja 重新构建 Secure。
  • --target install 更新 NS 所需的导出文件和镜像配置。
  • -B build 重新配置 NS,使其读取新的 Secure 导出配置。
  • --build build 重新构建 NS,生成组合签名镜像。
  • --parallel 启用并行构建。

这时生成新的 tfm_s_ns_signed.hex,再用前面的 QEMU 命令启动。只修改成 1,再加载一个旧的或仅含 Secure 的镜像,不能代替完整的 S + NS 镜像。

同时检查 QEMU 加载的是签名镜像,而不是未经签名的 tfm_s.bin / tfm_ns.bin,并确保 BL2 与镜像使用相同配置。

构建目录或生成器不匹配

进入源码目录后,使用 cmake --build build_an521_ninja。只有当前目录就是构建目录时,才能使用 cmake --build .。

该构建目录使用 Ninja,构建规则保存在 build.ninja。遇到生成器不匹配时,应使用原来的 Ninja 生成器,或另建构建目录。

完整启动日志

构建时间和随机数每次可能不同,程序最后停留在循环中,需要手动退出 QEMU。

[INF] Starting bootloader
[INF] Beginning BL2 provisioning
[WRN] TFM_DUMMY_PROVISIONING is not suitable for production! This device is NOT SECURE
[INF] PSA Crypto init done, sig_type: EC-P256, using builtin keys
[INF] Image index: 0, Swap type: none
[INF] Bootloader chainload address offset: 0x80000
[INF] Image version: v2.3.0
[INF] Jumping to the first image slot
[NOT] Booting TF-M v2.3.0
[NOT] Built Fri 12 Jun 2026 11:16:33 UTC
[INF] Beginning TF-M provisioning
[WRN] TFM_DUMMY_PROVISIONING is not suitable for production! This device is NOT SECURE
[WRN] This device was provisioned with dummy keys. This device is NOT SECURE
[VER] Isolation level is: 1
Creating an empty ITS flash layout.
Creating an empty PS flash layout.
[INF] [Crypto] Provision entropy seed...
[INF] [Crypto] Provision entropy seed... complete.
[VER] [Crypto] Init TF-PSA-Crypto 1.1.0...
[VER] [Crypto] Internal heap size is 12288 bytes
[VER] [Crypto] Init TF-PSA-Crypto 1.1.0... complete.
[INF] [PS] Encryption alg: 0x5500200
Non-Secure system starting...
Hello TF-M world
PSA Framework Version = 1.1
Testing psa get random number...
1: psa_generate_random() = 108
2: psa_generate_random() = 53
3: psa_generate_random() = 110
4: psa_generate_random() = 151
5: psa_generate_random() = 54
End of TF-M example App

日志中的 dummy provisioning / dummy keys 表示使用了演示密钥。它不影响这里的功能学习,不能作为生产设备的安全配置。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

tyustli

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值