wolfBoot クイックスタート
このドキュメントは wolfBoot を使⽤して安全なファームウェア更新を実現するための基本的な準備について説明します。

1. wolfBoot のダウンロードと基本ツールの準備
wolfBoot の商⽤版または GPLv2 オープンソース版をダウンロード、適当なディレクトリー下に解凍し、wolfBoot のルートディレクトリに移動します。
$ cd wol2oot-*$ ls
必要なファイルが解凍されていることを簡単に確認します。主なディレクトリーと内容は以下の通りです。

ディレクトリーMakeﬁle説明

ツール、wolfBoot など必要なファイルをビルドするためのMakeﬁleconﬁg

wolfBoot のコンフィグレーション定義ファイル
examples 下に各種ターゲット向けサンプル
wolfBoot ルート直下の”.conﬁg”にコピーして使⽤

docs

各種ドキュメント

halHardware AbstracFon Layer: 主にフラッシュアクセス API

includewolfBoot 本体のソースとヘッダーファイル

src

アプリケーションが wolfBoot 機能を呼び出すための API ライブラリー(libwol2oot.c)lib

wolfBoot で使⽤するライブラリー(wolfSSL, wolfTPM)

tools

wolfBoot で使⽤するツール
keytools の下にファームウェアイメージへの署名鍵⽣成(keygen)、署名(sign)
wolfBoot のファイル構成
Page 1 of 13
Copyright © wolfSSL Inc.

念の為、wolfSSL ライブラリーが正しくダウンロードされていることを確認します。
$ cd lib/wolfssl$ ls$ more wolfssl/version.h…
#deﬁne LIBWOLFSSL_VERSION_STRING "5.7.0"…
$ cd ../..
ファームウェアイメージへの署名鍵⽣成、署名のためのツールをビルドします。
$ make keytools
Keygen, sign の実⾏ファイルができていることを確認します。
$ ls -l tools/keytools/

Page 2 of 13
Copyright © wolfSSL Inc.

2. ファームウェア更新の概略
wolfBoot のファーウェア更新は概ね以下の⼿順で⾏います。

wolfBoot の準備-

Keygen ツールにて公開鍵とプライベート鍵を⽣成します
公開鍵は kyestore.c にソースファイルの形で⽣成されます。プライベート鍵は DER形式のファイルとして⽣成されます。

-Flash 上の構成を定義します。
Flash 上には図のように wolfBoot 本体、プライマリーパーティションにカレントバージョンのファームウェア、アップデートパーティションに次のバージョンのファームウェアを格納します。また、更新する際に安全な更新を実現するための１ブロック分のスワップセクターを確保します。
構成定義は”.conﬁg” ファイルに格納します。パーティションに関しては以下のような定数を定義します。

WOLFBOOT_PARTITION_SIZE?=0x…
WOLFBOOT_SECTOR_SIZE?=0x…
WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x…
WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x…
WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x…

-

wolfBoot をビルド、ダウンロード必要なコンフィグレーション定義、HAL の準備などの後、wolfBoot ルートディレク
トリで”make wol2oot.bin” のような形で make コマンドでビルドします。
⽣成したバイナリイメージをターゲットに転送します。

Page 3 of 13
Copyright © wolfSSL Inc.

wolfBoot の構成-

アプリケーションはファームウェア更新に関して下の図のような状態を遷移することを想定しています。
初期状態では、wolfBoot はプライマリーパーティションの状態と署名をチェックし正常であればアプリケーションに制御をわたします。アプリケーションは正常に処理を開始できたら wolfBoot に正常に起動したことを知らせます(wolfBoot_success)。wolfBoot はアップデートが必要となるまでは、この状態でプライマリーパーティションのアプリケーションを起動します。
アップデートパーティションの準備ができたら、アプリケーションは次のブートタイミングでのイメージの更新を wolfBoot に要求します(wolfBoot_update_trigger)。
次のブートタイミングで wolfBoot が上記トリガーを検知したら、更新フェーズに⼊ります。パーティションの内容の更新が正常に終了したら、再びプライマリーパーティションのアプリケーション（次のバージョンのアプリケーション）を起動します。
アプリケーションは wolfBoot に正常起動を知らせ(wolfBoot_success)、wolfBoot は新バージョンの起動を繰り返します。

Page 4 of 13
Copyright © wolfSSL Inc.

-

アプリケーションのビルド
アプリケーションにファームウェア更新の状態遷移に関する API 呼び出しを追加します。アプリケーションの状態を wolfBoot に知らせたり、wolfBoot に(次のブートタイミングでの)イメージの更新を要求したりする API のソースコードはsrc/libwol2oot.c にあるので、アプリケーションをビルドする際には libwol2oot.c もコンパイル、リンクします。libwol2oot.c の API は Flash 上のイメージパーティションのヘッダー部分の特定の領域を使って wolfBoot と通信します。したがって、libwol2oot.c は wolfBoot の本体とリンクする必要はありません。

ファームウェア更新の状態遷移

Page 5 of 13
Copyright © wolfSSL Inc.

2. wolfBoot 使⽤のためのステップ-

ターゲット構成の決定（docs/Targets.md を参照）-

HAL の準備このドキュメントの “3. ハードウェア抽象化レイヤー” を参照してください。

-

Flash パーティションの決定(docs/ﬂash_parFFons.md を参照)-

ファームウェアイメージのエントリーポイント bootloader が存在している分を考慮して変更してください(wolfBoot の構成を参照)。

-

アプリケーションに libwol2oot.c をリンクしてください。
このドキュメントの”4.ブートローダーと対話するための API”を参照-

イメージに署名します(docs/Signing.md を参照)-

Measured Boot (docs/measured_boot.md を参照)

Page 6 of 13
Copyright © wolfSSL Inc.

3. ハードウェア抽象化レイヤー
ターゲット マイクロコントローラーで wolfBoot を実⾏するには、ターゲット環境のための HAL の実装を準備します。HAL の⽬的は、ブートローダーと、アプリケーション ライブラリを通じてファームウェア アップグレードを開始するアプリケーションからの書き込み/消去操作を許可し、ブート中に MCU がフルスピードで実⾏されるようにすることです (署名の検証を最適化するため)。
各プラットフォームのハードウェア固有の呼び出しの実装例が、hal ディレクトリ下のそれぞれの c ファイルに格納されています。このディレクトリには、サポートされている各 MCU のプラットフォーム固有のリンカー スクリプトも含まれています。
同じ名前と .ld 拡張⼦を持つ。 これは、ブートローダーのファームウェアを特定のハードウェアにリンクするために使⽤され、フラッシュと RAM の境界に必要なすべてのシンボルをエクスポートします。

-

サポートされているプラットフォーム

現在のバージョンでは次のプラットフォームがサポートされています。
STM32F4、STM32L5、STM32L0、STM32F7、STM32H7、STM32G0
nRF52
アトメルサム R21
TI cc26x2
キネティス
SiFive HiFive1 RISC-V-API 仕様

ハードウェア抽象化レイヤー (HAL) は、サポートされているターゲットごとに実装される 6 つの関数呼び出しで構成されます。
void hal_init(void)
Page 7 of 13
Copyright © wolfSSL Inc.

この関数は、実⾏の最初にブートローダーによって呼び出されます。 ターゲット マ
イクロコントローラーのクロック設定を構成し、暗号化プリミティブがファームウェ
ア イメージを検証するのに妥当な速度でマイクロコントローラーが実⾏されるようにクロックレジスターなどを設定します。
void hal_ﬂash_unlock(void)
この関数は、フラッシュへの書き込みアクセスのロックを解除するために、すべての書き込みおよび消去操作の前に呼び出されます。 ⼀部のターゲットでは、この関数が空の場合があります。
int hal_ﬂash_write(uint32_t アドレス, const uint8_t *データ, int len)
この関数は、ターゲットの API を使⽤して、フラッシュ書き込み関数の実装を提供します。 address はフラッシュ領域の先頭からのオフセット、data は本 API を使⽤してフラッシュに保存されるペイロード、len はペイロードのサイズです。 hal_ﬂash_write
は、成功すると 0 を返し、失敗した場合は負の値を返します。
void hal_ﬂash_lock(void)
フラッシュメモリのロック/ロック解除が必要な場合、書き込みアクセスを除外してフラッシュ書き込み保護を回復します。 この関数は、すべての書き込み操作と消去操作の最後にブートローダーによって呼び出されます。
int hal_ﬂash_erase(uint32_t アドレス、int len)
ブートローダーによって呼び出され、フラッシュ メモリの⼀部を消去して後続のブートを可能にします。 消去操作は、ターゲット マイクロコントローラーの特定の APIを介して実⾏する必要があります。 address はブートローダーが消去する領域の開始をマークし、len は消去する領域のサイズを指定します。 この関数はフラッシュ セクターの形状を考慮し、その間にあるすべてのセクターを消去する必要があります。
Page 8 of 13
Copyright © wolfSSL Inc.

void hal_prepare_boot(void)
この関数は、次の段階でファームウェアをチェーンロードする前の、⾮常に遅い段階でブートローダーによって呼び出されます。 これを使⽤すると、クロック設定に加えられたすべての変更を元に戻し、マイクロコントローラーの状態を元の設定に確実に戻すことができます。

オプションで外部フラッシュメモリをサポート
WolfBoot は、makeﬁle オプション EXT_FLASH=1 を使⽤してコンパイルできます。 外部フラッシュのサポートが有効な場合、更新およびスワップ パーティションを外部メモリに関連付けることができ、読み取り/書き込み/消去アクセスに代替 HAL 機能が使⽤されます。 アップデートまたはスワップ パーティションを外部メモリに関連付けるには、それぞれ PART_UPDATE_EXT および/または PART_SWAP_EXT を定義します。
次の関数は外部メモリにアクセスするために使⽤され、EXT¥_FLASH がオンの場合に定義する必要があります。
int ext_ﬂash_write(uintptr_t アドレス, const uint8_t *データ, int len)
この関数は、外部メモリの特定のインターフェイスを使⽤して、フラッシュ書き込み関数の実装を提供します。 address はデバイス内のアドレス指定可能な空間の先頭からのオフセット、data は保存されるペイロード、len はペイロードのサイズです。
ext_ﬂash_write は、成功すると 0 を返し、失敗した場合は負の値を返します。
int ext_ﬂash_read(uintptr_t アドレス、uint8_t *データ、int len)
この関数は、ドライバー固有のインターフェイスを使⽤して、外部メモリの間接的な読み取りを提供します。 address はデバイス内のアドレス指定可能な空間の先頭からのオフセット、data は呼び出し成功時にペイロードが格納されるポインタ、len はペイロードに許可される最⼤サイズです。 ext_ﬂash_read は、成功すると 0 を返し、失敗した場合は負の値を返します。
Page 9 of 13
Copyright © wolfSSL Inc.

int ext_ﬂash_erase(uintptr_t アドレス、int len)
外部メモリの⼀部を消去するためにブートローダーによって呼び出されます。 消去操作は、ターゲット ドライバーの特定のインターフェイス (SPI フラッシュなど) を介して実⾏する必要があります。 address は、ブートローダーが消去したいデバイスに相対的な領域の開始をマークし、len は消去する領域のサイズを指定します。 この関数はセクターの形状を考慮し、すべてのセクターを消去する必要があります。

Page 10 of 13
Copyright © wolfSSL Inc.

4. ブートローダーと対話するための API
wolfBoot は、パーティションに保存されているイメージを操作し、更新を明⽰的に開始し、スケジュールされた更新の成功を確認するための API を提供します。

-libwol2oot を使⽤したコンパイルとリンク

wolfBoot との対話を必要とするアプリケーションには、ヘッダー ファイルを含める必要があります。

#include <wol2oot/wol2oot.h>
これにより、API 関数の宣⾔と、ファームウェア イメージとともに 2 つのパーティションに保存されているフラグとタグの事前定義値がエクスポートされます。フラッシュ パーティション、フラグ、および状態の詳細については、「フラッシュ パーティション」を参照してください。

-API

libwol2oot は、フラッシュ パーティションの状態への低レベルのアクセス インターフェイスを提供します。 各パーティションの状態は、アプリケーションによって取得および変更できます。アプリケーションからの基本的な対話は、次の関数呼び出しを通じて提供されます。

uint32_t wolfBoot_get_image_version(uint8_t 部分)
void wolfBoot_update_trigger(void)
Page 11 of 13
Copyright © wolfSSL Inc.

void wolfBoot_success(void)-

ファームウェアのバージョン

現在の (ブート) ファームウェアと更新ファームウェアのバージョンは、以下を使⽤してアプリケーションから取得できます。
uint32_t wolfBoot_get_image_version(uint8_t 部分)

または、ショートカット マクロを使⽤します。
wolfBoot_current_ﬁrmware_version()
wolfBoot_update_ﬁrmware_version()-

アップデートをトリガーする

wolfBoot_update_trigger() は、次回の再起動時にアップデートをトリガーするために使⽤されます。これは通常、実⾏中のファームウェアの新しいバージョンを取得し、それをフラッシュ上の UPDATE パーティションに保存したアップデート アプリケーシ
ョンによって使⽤されます。 この関数は、UPDATE パーティションの状態をSTATE_UPDATING に設定し、次回の実⾏時 (再起動後) に更新を実⾏するようにブートローダーに指⽰します。
wolfBoot 更新プロセスは、⼀時的な単⼀ブロック SWAP スペースを使⽤して、UPDATE パーティションと BOOT パーティションの内容を交換します。

-

現在のイメージを確認する
Page 12 of 13
Copyright © wolfSSL Inc.

wolfBoot_success() は、新しいファームウェアの起動が成功したことを⽰します。 これはアプリケーションによっていつでも呼び出すことができますが、有効となるのは、現在のファームウェア (BOOT パーティション内) に状態 STATE_SUCCESS をマー
クし、ロールバックが必要ないことを⽰す場合のみです。 通常、アプリケーションは、次のアップグレード⽤に新しいファームウェアを取得する可能性を含め、基本的なシステム機能が稼働していることを確認した後にのみ wolfBoot_success() を呼び出す必要があります。
アップグレードして再起動した後、wolfBoot がアクティブなファームウェアがまだSTATE_TESTING 状態であることを検出した場合、アプリケーションの起動の成功が確認されていないことを意味し、2 つのイメージを再度交換して更新を元に戻そうとします。

以上

Page 13 of 13
Copyright © wolfSSL Inc.