連載
» 2011年06月14日 11時37分 UPDATE

H8マイコンボードで動作する組み込みOSを自作してみよう!(3):OSの起動に必要な「ブートローダー」を自作してみよう (1/3)

連載「H8マイコンボードで動作する組み込みOSを自作してみよう!」の第3回。今回は、OSの起動に必要な「ブートローダー」を作成し、自作の「Hello World」をブートローダーから起動させる!

[坂井弘亮,@IT MONOist]

 本連載では、学習用・ホビー用の組み込みOS「KOZOS」を使ってマイコンボード上でいろいろと実験をしつつ、フルスクラッチで組み込みOSを自作していく過程を体験していきます。最終的に、ソフトウェア完全自作のWebサーバを動かすことにチャレンジします!

 連載第1回「フルスクラッチの“Hello World”を動かしてみよう」では、「H8/3069Fマイコンボード」上でフルスクラッチの「Hello World」を動かしました。続く、連載第2回「フルスクラッチの“Hello World”の仕組みを見てみよう」では、そのソースコードの解説を行いました。

 今回は、OSの起動に必要な「ブートローダー」を作成し、自作の「Hello World」をブートローダーから起動してみます。

1.マイコンボードとソースコード

 本連載では、秋月電子通商の「H8/3069Fネット対応マイコンLANボード(完成品)」(図1)を利用します。マイコンボードの詳細については連載第1回を参照してください。ちなみにこのボードは、3750円(税込)と非常に安価で入手性も良く、個人のホビー用途にオススメです。

本連載で利用する「H8/3069Fマイコンボード」 図1 本連載で利用する「H8/3069Fマイコンボード」

 本連載で紹介するソースコードは、KOZOSのWebサイトからダウンロードできます。また、開発環境の構築方法は連載第1回で説明してありますので、興味のある方はぜひソースコードをビルドし、実機での動作を試してみてください(幾つか対応は必要となりますが、シミュレータ上でも動作させることが可能です)。

 なお、上記ソースコードは、筆者の書籍「12ステップで作る組込みOS自作入門」の各章(ステップ)に応じたものになっています。書籍の方にも詳しい説明がありますので、そちらも参考にしてみてください。

参考文献[1]

  • 「12ステップで作る組込みOS自作入門」(カットシステム/著:坂井 弘亮)



2.なぜブートローダーが必要なのか?

 OSを自作する際にまず考えなければならないことは、その起動方法です。つまり「ブートローダーをどうするか?」ということです(注1)。

※注1:「ブートローダー」はOSの“本質”ではないため、一般的に軽く見られがちですが、マイコンの動作を理解する上では非常に重要な部分(要素)だと筆者は思います。


 組み込みOSの起動方法には、大きく分けて2種類があります。

 1つは連載第1回で紹介した「Hello World」のように、ROM上にOSの実行コードを配置しておく方法です。電源ONでROM上のコードが実行されるため、そこにOS本体を置いておけば、電源ONですぐにOSを起動できます。この場合、RAMは静的変数とスタック、ヒープのみに利用されます。多くのマイコンはこのような動作を想定して、内蔵フラッシュROMの容量を内蔵RAMよりも多めに取ってあります。

 もう1つは、ROM上に「ブートローダー」と呼ばれるプログラムを配置して、(1)電源ONでブートローダーが起動し、(2)ブートローダーがOSを起動するという2段階構造にする方法です。これは一見すると無駄なようにも思えますが、この構成の方が最適なケースがあります。例えば、実行速度が必要な(OSの実行コードを高速なRAM上で動作させたい)場合や、フラッシュROMの領域節約のためにOSの実行コードを圧縮しておきたい場合、ユーザー側でのOSの更新を可能にしたい場合などです。このようなケースでは、OSのモジュールをROM上の別領域に書き込んでおき、ブートローダーはそれをRAM上に展開してOSの起動をかけます。

 また、フラッシュROMには書き込み回数に限度がありますし、開発中にいちいちフラッシュROMに書き込んで起動をかけるのは面倒です。このような場合、ブートローダーをフラッシュROMに書き込んでおき、OSのモジュールをシリアルなどでダウンロードして起動すれば、フラッシュROMへの書き込みの手間や回数を削減できます。さらに、ブートローダーに簡単なデバッグ機能などを追加しておけば、OSのデバッグも行えるため、OSの動作が安定していない開発初期段階で非常に重宝します。このようなデバッグ機能を持つブートローダーのことを一般的に「モニター」などと呼びます。

 当然ながら、OSの起動にはOSの転送が必要です(電源ONでOSが自動的に起動するわけではありません)。製品化の段階では、OSのモジュールをフラッシュROMなどに書き込む必要があります。このような作業を一般的に「ROM化」と呼びます。

 ROM化の際、前述の方法によってフラッシュROMから直接OSを起動させる(つまり、ブートローダーを介さずにOSを起動させる)方法もありますが、先に説明したように、高速性やOSモジュールの圧縮・更新の容易性などのため、ブートローダーを残し、OSのモジュールをフラッシュROM上の別領域に配置しておくケースもあります。

3.「KOZOS」のブートローダー

 筆者が開発しているKOZOSでは、ブートローダーも作成しています。

 ブートローダーは、オープンソース・ソフトウェアとして配布されているものも幾つか存在し(注2)、中には高機能で魅力的なものもあります。しかし、“ソフトウェアを完全自作で開発する”というのがKOZOSのポリシーですので、ブートローダーも“自作”しています!

※注2:「U-Boot」などが有名ですね。


 今回使用するマイコンボードのフラッシュROMにあらかじめブートローダーを書き込んでおきます。(1)電源ONすると、まずブートローダーが起動し、シリアル上にプロンプトが出力されます。(2)OSのモジュールはシリアル経由で転送され、起動をかけることでOSを立ち上げます。

 今回、この2段階構成にした理由の1つは、フラッシュROMの書き込み寿命を節約するためです。もう1つは、ブートローダーから自作した方が本格的な組み込みシステムの動作を模倣できて、良い学習用のサンプルになるからです。完全自作のKOZOSでは、電源ON直後のブートローダーの動作から学習することができます。ブートローダーの学習用のシンプルな実装はあまりないため、これは貴重なものだと思います。

4.ブートローダーを動作させる

 それでは、KOZOSのブートローダーを実際に動作させてみましょう。

 KOZOSのWebサイトから「osbook_03.zip」をダウンロードしてください。「osbook_03.zip」を解凍すると、「osbook_03」以下に「06」というフォルダがあり、直下に「bootload」「os」という2種類のソースコードがあります。これが今回の対象です。

 「bootload」がブートローダー、「os」がブートローダーから起動して動作させるプログラムになります。フォルダ名は「os」ですが、これは“この後OSの形に仕上げていく”ためにこのような名前になっているだけで、ここでは単なる「Hello World」を表示するだけのプログラムになっています。

 連載第1回では、マイコンボードの電源ONで「Hello World」をシリアル出力するプログラムを作成しましたが、今回は電源ONでブートローダーを起動し、シリアル経由で「Hello World」のプログラムを転送、起動するという手順になります。

 まずは、これらをビルドしてみましょう。「bootload」のフォルダに入って「make」「make image」コマンドを実行し、ブートローダーの実行モジュールを作成します(リスト1)。

% cd osbook_03/06/bootload
% make
/usr/local/bin/h8300-elf-gcc -c -Wall -mh -nostdinc -nostdlib -fno-builtin -I. -Os -DKZLOAD vector.c
/usr/local/bin/h8300-elf-gcc -c -Wall -mh -nostdinc -nostdlib -fno-builtin -I. -Os -DKZLOAD startup.s
/usr/local/bin/h8300-elf-gcc -c -Wall -mh -nostdinc -nostdlib -fno-builtin -I. -Os -DKZLOAD main.c
/usr/local/bin/h8300-elf-gcc -c -Wall -mh -nostdinc -nostdlib -fno-builtin -I. -Os -DKZLOAD lib.c
/usr/local/bin/h8300-elf-gcc -c -Wall -mh -nostdinc -nostdlib -fno-builtin -I. -Os -DKZLOAD serial.c
/usr/local/bin/h8300-elf-gcc -c -Wall -mh -nostdinc -nostdlib -fno-builtin -I. -Os -DKZLOAD xmodem.c
/usr/local/bin/h8300-elf-gcc -c -Wall -mh -nostdinc -nostdlib -fno-builtin -I. -Os -DKZLOAD elf.c
/usr/local/bin/h8300-elf-gcc vector.o startup.o main.o lib.o serial.o xmodem.o elf.o -o kzload -Wall -mh -nostdinc -nostdlib -fno-builtin -I. -Os -DKZLOAD -static -T ld.scr -L.
cp kzload kzload.elf
/usr/local/bin/h8300-elf-strip kzload
% make image
/usr/local/bin/h8300-elf-objcopy -O srec kzload kzload.mot
% ls kzload*
kzload          kzload.elf      kzload.mot
% 
リスト1 ブートローダーのビルド結果

 ここで作成された「kzload」というファイルがブートローダーの実行モジュールです。「kzload.mot」は、実行モジュールをマイコンボードへ転送するためのファイル形式(注3)に変換したものです。

※注3:ここで利用しているのは「モトローラSレコードフォーマット」と呼ばれる形式です。


 さらに「os」のフォルダに入り、「make」コマンドを実行することで、「Hello World」の実行モジュールを作成します(リスト2)。

% cd osbook_03/06/os
% make
/usr/local/bin/h8300-elf-gcc -c -Wall -mh -nostdinc -nostdlib -fno-builtin -I. -Os -DKOZOS startup.s
/usr/local/bin/h8300-elf-gcc -c -Wall -mh -nostdinc -nostdlib -fno-builtin -I. -Os -DKOZOS main.c
/usr/local/bin/h8300-elf-gcc -c -Wall -mh -nostdinc -nostdlib -fno-builtin -I. -Os -DKOZOS lib.c
/usr/local/bin/h8300-elf-gcc -c -Wall -mh -nostdinc -nostdlib -fno-builtin -I. -Os -DKOZOS serial.c
/usr/local/bin/h8300-elf-gcc startup.o main.o lib.o serial.o -o kozos -Wall -mh -nostdinc -nostdlib -fno-builtin -I. -Os -DKOZOS -static -T ld.scr -L.
cp kozos kozos.elf
/usr/local/bin/h8300-elf-strip kozos
% ls kozos*
kozos           kozos.elf
% 
リスト2 Hello Worldのビルド結果

 「kozos」というファイルが「Hello World」の実行モジュールです。

 では、実際に動作させてみます。まずは連載第1回と同じ要領で、ブートローダーをマイコンボードのフラッシュROMに書き込みます。

 PCとマイコンボードをシリアルケーブルで接続し、マイコンボードのディップスイッチを左から「ON、ON、OFF、ON(上、上、下、上)」にした状態(フラッシュROM書き込みモード)で、電源アダプターを接続して電源をONにします。

 「bootload」のフォルダに入って「make write」コマンドを実行することで、マイコンボードのフラッシュROMにブートローダーを書き込みます。

 書き込み方法については、連載第1回で説明してありますので、詳しくはそちらを参照してください。さらに、本稿執筆時点で「h8write」の幾つかの不具合を修正し、新たに実装しなおされた「kz_h8write」がshintaさんによって作成されています(原稿執筆の現時点ではLinux版とWindows版があるようです)。フラッシュROMへの書き込みがうまくいかない場合には、こちらも利用してみてください。


       1|2|3 次のページへ

Copyright© 2017 ITmedia, Inc. All Rights Reserved.