
2025/12/29 6:25
**GDBでARM Cortex‑M の現在のセキュリティ状態を判断する方法**
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
記事では、Arm Cortex‑MマイクロコントローラでArmv8‑Mをサポートし、任意のTrustZone機能が有効な場合に、GDB を使用して現在のセキュリティコンテキストを迅速に判定する方法を説明しています。スタックポインタ(SP)と CONTROL レジスタの SPSEL ビットを調べることで、コアが Secure モードか Non‑Secure モードで動作しているかを判断できます。TrustZone が有効な場合、各スタックポインタには Secure (_S) と Non‑Secure (_NS) のバリアント(MSP_S, MSP_NS, PSP_S, PSP_NS)が存在します。
GDB では次のコマンドで現在の SP とその _S/_NS 対応を表示できます。
(gdb) i r sp psp_ns msp_ns psp_s msp_s
SP が PSP_NS または MSP_NS と等しい場合、プロセッサは Non‑Secure 状態にあります。PSP_S や MSP_S と一致すれば Secure です。CONTROL レジスタの第2ビット(SPSEL)は次で確認できます。
(gdb) print $control & 0x2
非ゼロの結果は SPSEL = 1 を示し、アクティブなスタックポインタが PSP であることを意味します。
例として、TrustZone が有効な Cortex‑M33 のリセット時にはコアは Thread モードと Secure 状態(SP = MSP_S)で開始します。Zephyr RTOS アプリケーションでは
main でブレークすると SP = PSP_NS が表示されます。これはプロセッサが Thread / Non‑Secure モードに切り替わったことを示しています。
この方法は、Armv8‑M コアの現在のセキュリティ状態を迅速に判断する複数の手段の一つであり、エンジニアがコードの実行コンテキストを検証し、デバッグ時間を短縮するのに役立ちます。
本文
2025年12月24日 – 3分読了
私の本業と自由時間では、Arm Cortex‑M マイクロコントローラ(MCU)を頻繁にデバッグしています。
近年、この種の MCU が Armv8‑M を実装するケースが増えており、その中でも Cortex‑M33 は非常に人気があります。
Armv8‑M にはオプションのセキュリティ拡張機能(Cortex‑M Security Extension、略して CMSE)があり、マーケティング名では TrustZone と呼ばれています。
このセキュリティ拡張により、コア―または Arm 公式マニュアルでいう Processing Element(PE)がメモリを Secure 区域と Non‑Secure 区域に分割できます。Secure 区域内で命令を実行している場合は PE が Secure 状態にあると言い、Non‑Secure 区域では Non‑Secure 状態になります。
スタックポインタ(SP)の挙動
Armv8‑M の PE で現在使用されているスタックポインタ(SP / R13)は、実行モード(Handler モードか Thread モード)と
CONTROL 特殊レジスタの SPSEL フィールドに応じて Main Stack Pointer(MSP)または Process Stack Pointer(PSP)を参照します。
- Handler モードでは、SP は常に MSP と一致します。
- Thread モードの場合、
が 0 のときは MSP、1 のときは PSP を指します。SPSEL
セキュリティ拡張が実装されていると、多くのレジスタには
_S(Secure)と _NS(Non‑Secure)の両方が用意されています(例:MSP_S, MSP_NS, PSP_S, PSP_NS)。これにより、デバッグ時に現在のセキュリティ状態を素早く確認できるようになります。
GDB で簡単チェック
実行:
(gdb) i r sp psp_ns msp_ns psp_s msp_s
- SP が
またはPSP_NS
と一致すれば、PE は Non‑Secure 状態です。MSP_NS
やPSP_S
と一致すれば、PE は Secure 状態です。MSP_S
例 – セキュリティ拡張付き Cortex‑M33 のリセット時
プロセッサは Thread モードで Secure 状態から開始し、SP は
MSP_S に一致します。
sp 0x20004000 0x20004000 psp_ns 0x2001ad40 0x2001ad40 <z_main_stack+4048> msp_ns 0x0 0x0 <_vector_table> psp_s 0x0 0x0 <_vector_table> msp_s 0x20004000 0x20004000
これは Zephyr RTOS アプリケーション(
z_main_stack シンボルが示すように)です。main でブレークし、再度確認すると SP は PSP_NS と一致します。プロセッサは Thread モードかつ Non‑Secure 状態になり、CONTROL.SPSEL が 1 に設定されているためです。
sp 0x2001ad40 0x2001ad40 <z_main_stack+4048> psp_ns 0x2001ad40 0x2001ad40 <z_main_stack+4048> msp_ns 0x20019c30 0x20019c30 <z_idle_stacks> psp_s 0x20001eb8 0x20001eb8 <z_main_stack-97976> msp_s 0x20000bf8 0x20000bf8 <sector_buffers+1688>
SPSEL フィールドを確認するには、CONTROL レジスタの第2ビットだけをマスクして表示します。
(gdb) print $control & 0x2 $0 = 2 # 非ゼロなら SPSEL が 1
Armv8‑M コアで現在のセキュリティ状態を判断する方法は他にもありますが、デバッグ時に即座かつ確実に確認できる便利な手段です。