Trusted Firmware-M(TF-M)は、メモリをセキュア領域と非セキュア領域に分割します。このガイドでは、データインポート目的でカスタム非セキュア・フラッシュ領域を追加する方法を説明します。これは、FRDM-RW612のようなプラットフォームでTF-Mの機能をテストまたは拡張する際に役立ちます。
このガイドでは、frdmrw612/ns上のel2go_import_blobを例として使用しています。任意のTFMベースのサンプルを使用することもできます。VSCodeを使用してスタンドアロン・アプリケーションとしてインポートされています。
最初の2つの手順では、領域のオン/オフを切り替えたい場合に、コード内に簡単に#ifdef文を追加できるようマクロを追加します。TFMは従来のZephyr kConfigを使用しないため、マクロが正しく定義されるよう手順に従う必要があります。#if文なしで領域を追加したい場合は、手順1〜2をスキップします。その場合は、手順3〜5から#ifdef TFM_CUSTOM_DATA_IMPORT_REGION #endifを必ず削除してください。
確認します。 el2go_import_blob/Kconfig
config TFM_CUSTOM_DATA_IMPORT_REGION
bool "Enable custom flash area for testing"
help
Validate non-secure region in flash.
確認します。 el2go_import_blob/prj.conf
CONFIG_TFM_CUSTOM_DATA_IMPORT_REGION=y
ファイル: el2go_import_blob/CMakeLists.txt
CMakeオプションを追加します。
if(CONFIG_TFM_CUSTOM_DATA_IMPORT_REGION)
set_property(TARGET zephyr_property_target APPEND PROPERTY TFM_CMAKE_OPTIONS
-DUSE_TFM_CUSTOM_DATA_IMPORT_REGION=ON
)
endif()
ファイル: platform/ext/target/nxp/frdmrw612/config.cmake
フラグを追加します。
set(USE_TFM_CUSTOM_DATA_IMPORT_REGION OFF CACHE BOOL "")
ファイル:platform/ext/target/nxp/frdmrw612/CMakeLists.txt
コンパイル定義を追加:
if (USE_TFM_CUSTOM_DATA_IMPORT_REGION)
set(TFM_CUSTOM_DATA_IMPORT_REGION_COMPILE_DEFINITION "TFM_CUSTOM_DATA_IMPORT_REGION")
endif()
target_compile_definitions(psa_interface INTERFACE
${TFM_CUSTOM_DATA_IMPORT_REGION_COMPILE_DEFINITION}
)
ファイル:platform/ext/target/nxp/frdmrw612/partition/flash_layout.h
アドレスとサイズを定義:
#ifdef TFM_CUSTOM_DATA_IMPORT_REGION
#define TFM_CUSTOM_NS_REGION_ADDR (0x08500000)
#define TFM_CUSTOM_NS_REGION_SIZE (0x00001000) // 4KB
#endif
ファイル:platform/ext/target/nxp/frdmrw612/partition/region_defs.h
領域をマッピングします。
#ifdef TFM_CUSTOM_DATA_IMPORT_REGION
#define CUSTOM_NS_DATA_REGION_START (TFM_CUSTOM_NS_REGION_ADDR)
#define CUSTOM_NS_DATA_REGION_SIZE (TFM_CUSTOM_NS_REGION_SIZE)
#endifファイル: platform/ext/target/nxp/common/gcc/tfm_common_s.ld
リージョンベース宣言を追加:
#ifdef TFM_CUSTOM_DATA_IMPORT_REGION
Load$$LR$$LR_CUSTOM_DATA_IMPORT_REGION$$Base = CUSTOM_NS_DATA_REGION_START;
#endif
ファイル:platform/ext/target/nxp/common/target_cfg_common.h
メモリ領域構造体に追加します。
#ifdef TFM_CUSTOM_DATA_IMPORT_REGION
uint32_t custom_ns_data_region_base;
uint32_t custom_ns_data_region_limit;
#endif
ファイル: platform/ext/target/nxp/common/tfm_hal_platform.c
領域の上限・下限を初期化します。
#ifdef TFM_CUSTOM_DATA_IMPORT_REGION
REGION_DECLARE(Load$$LR$$, LR_CUSTOM_DATA_IMPORT_REGION, $$Base);
#endif // TFM_CUSTOM_DATA_IMPORT_REGION
#ifdef TFM_CUSTOM_DATA_IMPORT_REGION
.custom_ns_data_region_base =
(uint32_t)®ION_NAME(Load$$LR$$, LR_CUSTOM_DATA_IMPORT_REGION, $$Base),
.custom_ns_data_region_limit =
(uint32_t)®ION_NAME(Load$$LR$$, LR_CUSTOM_DATA_IMPORT_REGION, $$Base) + CUSTOM_NS_DATA_REGION_SIZE - 1,
#endif // TFM_CUSTOM_DATA_IMPORT_REGION
ファイル:platform/ext/target/nxp/common/tfm_hal_isolation.c
SAUを構成します。
#ifdef TFM_CUSTOM_DATA_IMPORT_REGION
SECURE_WRITE_REGISTER(&(SAU->RNR), 7U);
SAU->RBAR = (memory_regions.custom_ns_data_region_base & SAU_RBAR_BADDR_Msk);
SAU->RLAR = (memory_regions.custom_ns_data_region_limit & SAU_RLAR_LADDR_Msk) | SAU_RLAR_ENABLE_Msk;
#endif
ファイル: platform/ext/target/nxp/frdmrw612/target_cfg.c
MPCを設定:
#ifdef TFM_CUSTOM_DATA_IMPORT_REGION
enable_mem_rule_for_partition(memory_regions.custom_ns_data_region_base, memory_regions.custom_ns_data_region_limit);
#endif
ファイル:zephyr/samples/el2go_import_blob/frdm_rw612_rw612_ns.overlay
パーティションを追加:
custom_ns_data: partition@500000 {
label = "custom_ns_data";
reg = <0x500000 0x1000>;
};
1. Zephyrフラッシュを有効にする
確認します。 el2go_import_blob/prj.conf
CONFIG_FLASH=y
2. プロジェクトのメインソースファイルにテストコードを追加してください。
#include
const struct device *flash_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_flash_controller));
static int test_flash_region(void) {
uint32_t offset = 0x500000;
uint32_t test_data = 0xDEADBEEF;
uint32_t read_data;
// 1. Erase flash (required before write)
flash_erase(flash_dev, offset, 4096);
// 2. Write data
flash_write(flash_dev, offset, &test_data, sizeof(test_data));
// 3. Read data (this can use memcpy function)
memcpy(&read_data, (void *)0x08500000, sizeof(read_data));
if (read_data == test_data) {
LOG("✓ Flash test passed with memcpy: 0x%08x\n", read_data);
} else {
LOG("✗ Flash test failed\n");
}
//Flash read operation will have fix to correctly calculate address next release
/*flash_read(flash_dev, offset, &read_data, sizeof(read_data));
if (read_data == test_data) {
LOG("✓ Flash test passed with flash_read: 0x%08x\n", read_data);
} else {
LOG("✗ Flash test failed\n");
}
*/
return 0;
}
3. test_flash_region()関数をmain()から呼び出します。