組み込みデバイスとU-Boot

組み込みデバイスでは、初期レベルの起動処理にU-Bootが使われることも多い。U-BootはもともとPowerPC向けに開発されたもので、以前はPPCBootと呼ばれていたブートローダだ。フラッシュなどの永続的デバイスに焼き付けられ、初期レベルの起動処理に活用される。すでに多くの組み込みデバイスで採用されているほか、U-Boot自体がGPLv2で公開されているという特徴がある。いわば組み込みデバイスにおける汎用ブートローダとしてはデファクトスタンダードだ。対応しているアーキテクチャもPowerPC以外にARM、MIPS、SH、NIOS、AVR32、ColdFire、MicroBlazem、BlackFinなど多岐に渡り、起動できるOSの種類も多い。

U-Bootはフラッシュメディアからのシステム起動はもちろん、ハードディスクからの起動、ネットワーク経由からの起動、ディスクイメージからの起動、ファイルシステムからの起動などさまざまな方法をサポートし、さらに診断機能や自動イメージアップデート機能など、初期レベルのブートローダとしては高機能という特徴もある。

組み込み向けにU-Boot機能の統合

最近、FreeBSDにこのU-Bootにネイティブ対応する機能が追加された。従来の方法と違い、FreeBSDの方から直接U-Bootを活用するものだ。これに合わせてU-Bootの方にも変更が加えられている。同機能によって組み込み開発における起動処理実装の負担が軽減され、さらに統一された起動UIが実現されることになる。BSDCan2008では、開発を担当したRafal Jaworowski氏から説明が行われた。

FreeBSDの起動プロセスは大枠でまとめると次のとおりだ。

  1. ハードウェアレベルでの起動処理 (BIOS、EFI、OpenFireware、OpenBoot、RedBoot、U-Boot)
  2. FreeBSD初期起動処理 (MBR、boot*)
  3. FreeBSD最終起動処理 (loader(8))
  4. FreeBSDカーネル

FreeBSDでは、loader(8)の時点で読み込むカーネルモジュールを指定したり、カーネル内で使う環境変数kenv(9)値の設定、起動パラメータの指定などを行っている。アーキテクチャが違う場合でも、loader(8)のインタフェースに統合することで統一された起動UIを実現している。しかし、loader(8)で使っているH/Wの機能は、i386/amd64のようなアーキテクチャではBIOSで用意されているが、組み込みデバイスではそもそも用意されていないことも多い。この仕組みのまま組み込みデバイスにFreeBSDを追加するとなると、アーキテクチャ/ボードごとに起動処理を開発する必要がでてくる。

After relocation to RAM - BSDCan2008 Rafal Jaworowski氏発表資料より抜粋

U-Boot memory layout - BSDCan2008 Rafal Jaworowski氏発表資料より抜粋

U-Bootで実装されている機能をloader(8)から使うというアイディア

FreeBSDとU-Bootを組み合わせて使う場合、基本的に次の3つの方法が考えられる。

  • 直接FreeBSDカーネルを実行する
  • ネイティブU-Bootを採用する
  • ネイティブFreeBSDで対応する

1つめの方法で直接カーネルを呼ぶこともできるし、2つめのようにdevel/u-bootを使ってFreeBSDカーネルにヘッダを追加して起動できるようにする方法もあるが、これら方法ではloader(8)で実施している処理ができなくなるという問題がある。また、アーキテクチャ/ボードごとに起動処理を記述することになり、開発が手間という問題もある。そこで、BIOSの代わりにU-Bootの機能を使ってloader(8)を動作させようというのが、今回の開発のアイディアだ。上記3つめの方法がこれにあたる。

組み込みデバイスにおける起動処理開発の軽減

loader(8)からBIOSを叩くのではなく、U-Bootを叩いて処理を行えば、組み込みデバイスでi386/amd64と同じように起動処理を実現できるようになる。最新のU-Bootはすでにこの機能に対応している。アーキテクチャ/ボードごとにU-Bootの特定の機能をコールするファイルを作成するだけで良いため、最低限の労力で多くのボードに対応できるという利点がある。

Standalone applications in U-Boot - BSDCan2008 Rafal Jaworowski氏発表資料より抜粋

すでにFreeBSDにU-Bootをサポートするコードが追加されている(sys/boot/uboot)。執筆現在のところ、U-Bootサポートが追加されているのはPowerPCアーキテクチャだが、今後MIPSやARMも必要に応じてコネクションコードが追加されるとみられる。

今回このアプローチについて発表したRafal Jaworowski氏はU-Bootの開発者であり、FreeBSDの開発者でもある。今回のアプローチは、do_bootm()ルーチンを使ったり、mkimageを使ったりする従来のアプローチとは異なるもので、FreeBSD loader(8)でネイティブに実装されたものだが、仕組みはシンプルで汎用性が高く、loader(8)の実装向けに整備されたAPIはFreeBSDのみならず他のOSでも活用できるとされている。今後はFreeBSD以外のOSにも同アプローチが実装されていくものとみられる。

FreeBSD/mipsの開発が一定の成果を納めつつあり、組み込み開発に勢いがあることから、これから特にMIPSやARM、PowerPCを中心に対応するボードが随時追加されることになるとみられる。loader(8)からU-Bootを使う機能が追加されたことで、起動処理の開発負荷が軽減され、対応ボード増加を支援することになるだろう。