TF-M 使用 make 构建

本文详细介绍了基于Make构建TF-M Secure和Non-Secure固件的完整流程,包括配置、编译、NS接口导出、清理策略;重点解析QEMU单镜像启动方案,解决BL2加载重叠报错;涵盖配置缓存管理、分区开关控制、依赖下载优化及常见构建问题(如imagesign_wrapper缺失、pip工程误判、BL2启动失败)的定位与修复方法。

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

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

使用 Make 构建 Secure

这里使用 build_an521_make 保存 Make 的构建文件和产物,NS 工程使用自己的 build_make 目录。

配置

cd "/home/tyustli/Desktop/tyustli/study/code/qemu/trust_firmware/tfm/code/trusted-firmware-m"
source env/bin/activate
cmake -S . -B build_an521_make -G "Unix Makefiles" \
    -DTFM_PLATFORM=arm/mps2/an521 \
    -DCMAKE_BUILD_TYPE=Debug
  • -S . 指定当前的 trusted-firmware-m 目录为源码目录。
  • -B build_an521_make 指定 Secure 的 Make 构建目录。
  • -G "Unix Makefiles" 选择 Make 生成器,生成 Makefile,名称中有空格,需要加引号。
  • -DTFM_PLATFORM=arm/mps2/an521 选择 MPS2 AN521 平台。
  • -DCMAKE_BUILD_TYPE=Debug 选择调试构建。

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

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

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

编译与导出 NS 接口

cmake --build build_an521_make --target install --parallel
  • --build build_an521_make 调用 Make 构建该目录中的工程。
  • --target install 构建并导出 NS 接口到 build_an521_make/api_ns/。
  • --parallel 启用并行构建。

原生 Make 命令与最后一条等效。

make -C build_an521_make -j"$(nproc)" install
  • -C build_an521_make 让 Make 进入该构建目录执行。
  • -j"$(nproc)" 设置并行任务数,$(nproc) 由 Shell 替换为当前进程可用的处理器数量。
  • install 执行安装目标,构建并导出 NS 接口。

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

主要输出如下。

build_an521_make/
├── 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_make --target clean
  • --build build_an521_make 使用该目录中已有的构建规则。
  • --target clean 执行清理目标,删除编译产物及工程额外指定的生成文件,重新构建的步骤见后面的清理小节。

使用 Make 构建 Non-Secure

先完成前面 Make 方式的 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_make -G "Unix Makefiles" \
    -DCONFIG_SPE_PATH="/home/tyustli/Desktop/tyustli/study/code/qemu/trust_firmware/tfm/code/trusted-firmware-m/build_an521_make/api_ns" \
    -DTFM_TOOLCHAIN=GNUARM
  • -S . 指定当前的 NS 示例源码目录。
  • -B build_make 指定 NS 构建目录,与 Secure 的构建目录分开。
  • -G "Unix Makefiles" 选择 Make 生成器。
  • -DCONFIG_SPE_PATH=.../build_an521_make/api_ns 指向对应 Secure 构建导出的接口、配置和签名材料。
  • -DTFM_TOOLCHAIN=GNUARM 选择 GNU Arm 工具链。

配置报错

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

No SOURCES given to target: tfm_api_ns

CMake Generate step failed.  Build files cannot be regenerated correctly.

解决方法

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_make -G "Unix Makefiles" \
    -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_make 更新原来的 Secure 构建目录,保留已下载的依赖。
  • -G "Unix Makefiles" 沿用 Make 生成器。
  • -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 服务。
编译 TF-M
cmake --build build_an521_make --parallel
  • --build build_an521_make 根据新配置重新构建 Secure。
  • --parallel 启用并行构建。
安装 NS 接口
cmake --build build_an521_make --target install --parallel
  • --build build_an521_make 使用刚才的 Secure 构建目录。
  • --target install 更新导出的 NS 接口、平台配置和签名材料,输出到 build_an521_make/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_make -G "Unix Makefiles" \
    -U 'TFM_PARTITION_*' \
    -DCONFIG_SPE_PATH="/home/tyustli/Desktop/tyustli/study/code/qemu/trust_firmware/tfm/code/trusted-firmware-m/build_an521_make/api_ns" \
    -DTFM_TOOLCHAIN=GNUARM
  • -S . 指定切换目录后的 NS 源码目录。
  • -B build_make 沿用原来的 NS 构建目录。
  • -G "Unix Makefiles" 沿用 Make 生成器。
  • -U 'TFM_PARTITION_*' 清除 NS 缓存中的旧分区配置,重新读取 Secure 导出的值。引号防止 Shell 展开通配符。
  • -DCONFIG_SPE_PATH=.../build_an521_make/api_ns 使用这次更新后的 Secure 导出接口。
  • -DTFM_TOOLCHAIN=GNUARM 继续使用 GNU Arm 工具链。

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

编译 NS

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

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

原生 Make 命令如下,二选一即可。

make -C build_make -j"$(nproc)"
  • -C build_make 让 Make 进入 NS 构建目录,执行默认目标。
  • -j"$(nproc)" 根据当前可用的处理器数量设置并行任务数。

查看产物

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

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

build_make/
├── bin/
├── Makefile
├── 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_make/bin/bl2.hex" \
    -device loader,file="/home/tyustli/Desktop/tyustli/study/code/qemu/trust_firmware/tfm/code/trusted-firmware-m/build_an521_make/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_make/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_make/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_make/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_make/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_make/tfm_s_ns_signed.hex"
  • -M mps2-an521 选择 AN521 开发板模型。
  • -cpu cortex-m33 指定 Cortex-M33 处理器。
  • -nographic 在当前终端显示串口输出。
  • 第一个 -device loader,file=... 加载 Make 构建的 build_an521_make/bin/bl2.hex。
  • 第二个 -device loader,file=... 加载 NS 工程 build_make/tfm_s_ns_signed.hex。

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

调试与退出

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

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

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

日常修改与重新构建

只修改源码

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

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

修改配置

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

cd "/home/tyustli/Desktop/tyustli/study/code/qemu/trust_firmware/tfm/code/trusted-firmware-m"
cmake -S . -B build_an521_make -DCMAKE_BUILD_TYPE=Debug
cmake --build build_an521_make --target install --parallel
  • -S . 指定当前 TF-M 源码目录。
  • -B build_an521_make 在原构建目录上更新配置,保留未修改的缓存项。
  • -DCMAKE_BUILD_TYPE=Debug 将构建类型设置为 Debug。
  • --build build_an521_make 按更新后的配置构建。
  • --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_make -G "Unix Makefiles" \
    -DTFM_PLATFORM=arm/mps2/an521 \
    -DCMAKE_BUILD_TYPE=Debug
  • -S . 指定当前 TF-M 源码目录。
  • -B build_an521_make 复用已有的构建目录和配置缓存。
  • -G "Unix Makefiles" 沿用 Make 生成器。
  • -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_make/CMakeCache.txt。再次配置同一个构建目录时,CMake 会读取这些缓存。命令中省略之前的分区参数,只表示这次不修改它们,已经保存的 ON 会继续生效。

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

查看缓存
grep 'TFM_PARTITION' build_an521_make/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_make -G "Unix Makefiles" \
    -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_make 更新已有构建目录,保留其他缓存和已下载的依赖。
  • -G "Unix Makefiles" 沿用 Make 生成器。
  • -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_make
cmake -S . -B build_an521_make -G "Unix Makefiles" \
    -DTFM_PLATFORM=arm/mps2/an521 \
    -DCMAKE_BUILD_TYPE=Debug
  • rm -rf build_an521_make 删除整个构建目录,包括缓存、编译产物和目录内下载的依赖源码。
  • -S . 指定 TF-M 源码目录。
  • -B build_an521_make 创建新的构建目录。
  • -G "Unix Makefiles" 重新生成 Make 构建规则。
  • -DTFM_PLATFORM=arm/mps2/an521 重新指定平台。
  • -DCMAKE_BUILD_TYPE=Debug 重新指定构建类型。

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

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

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

FETCHCONTENT_FULLY_DISCONNECTED=ON

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

需要清理产物时

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

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

原生 Make 清理和重新构建命令如下。

cd "/home/tyustli/Desktop/tyustli/study/code/qemu/trust_firmware/tfm/code/trusted-firmware-m"
make -C build_an521_make clean
cmake -S . -B build_an521_make
make -C build_an521_make -j"$(nproc)" install
  • -C build_an521_make 让 Make 在该构建目录执行。
  • clean 执行 Make 的清理目标。
  • -S . 指定 TF-M 源码目录。
  • -B build_an521_make 重新配置原来的 Make 构建目录,补齐生成文件。
  • -j"$(nproc)" 根据当前可用的处理器数量设置并行任务数。
  • install 重新构建并导出 NS 接口。

cmake --build build_an521_make --target clean 与这里的 Make clean 等效,换成 CMake 包装命令不会改变清理规则。

  • --build build_an521_make 指定 Make 构建目录。
  • --target 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_make --target install --parallel
  • --build build_an521_make 在安装 Python 工具后继续构建原来的 Secure 工程。
  • --target install 构建固件并更新导出的 NS 接口。
  • --parallel 启用并行构建。

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

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

NS 工程遇到相同问题时,在 NS 目录执行 cmake -S . -B build_make 并追加同一个 -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_make -DMCUBOOT_IMAGE_NUMBER=1
cmake --build build_an521_make --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_make
cmake --build build_make --parallel
  • -S . 分别指定 cd 后的 Secure 或 NS 源码目录。
  • -B build_an521_make 更新 Secure 原有构建目录中的配置。
  • -DMCUBOOT_IMAGE_NUMBER=1 将 Secure 和 NS 合并为一个镜像签名,由 BL2 按单镜像方式验证。
  • --build build_an521_make 重新构建 Secure。
  • --target install 更新 NS 所需的导出文件和镜像配置。
  • -B build_make 重新配置 NS,使其读取新的 Secure 导出配置。
  • --build build_make 重新构建 NS,生成组合签名镜像。
  • --parallel 启用并行构建。

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

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

构建目录或生成器不匹配

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

该构建目录使用 Unix Makefiles,构建规则保存在 Makefile。遇到生成器不匹配时,应使用原来的 Make 生成器,或另建构建目录。

完整启动日志

构建时间和随机数每次可能不同,程序最后停留在循环中,需要手动退出 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 表示使用了演示密钥。它不影响这里的功能学习,不能作为生产设备的安全配置。

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")
评论
成就一亿技术人!
拼手气红包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、付费专栏及课程。

余额充值