(注意)このブログは本家のほうの文章部分のみの転載です.ソースコードの配布,画像などについては本家のほうを参照してください.文章中のリンク先は面倒なのですべて本家のほうに変換してしまっているのでご注意ください.

最近はInterfaceの記事が忙しくてKOZOSがあまりいじれていないのだけど,前からちょっと思っていたことについて.

KOZOSの方向性についてで,方向性について書いたけど,もうひとつ,こんな方向性で作ってみたいなあという前々から思っていたネタがある.

それは,デバッグ機能というものだ.

組み込み系に限らず,アプリケーションプログラムでも,いかにデバッグするかというのは永遠の課題だ.とくにメモリ系のバグ(バッファオーバーランや2重解放など)は非常に原因を特定しにくく,方法もあまり確立されていなかったりすることも多い.

個人的な考えとして,このようなデバッグ機能はOS側で持っていてもいいと思うのだな.たとえばKOZOSではkz_kmalloc()というシステムコールでメモリ獲得できる.このときに,kz_kmalloc()を呼んだ箇所(関数からのリターンアドレス.PowerPCならばLRレジスタの値)をメモリヘッダ上にメモしておくなどして,あとでメモリ領域を見たときに,その領域がどこで獲得されたのかひと目でわかるようにしておく,などだ.

他にも kz_send() によるメッセージ送信時に,やはりそれを呼んだ箇所をメッセージヘッダ上に保存しておくとか,呼ばれたときの時刻を保存しておくとか,呼んだスレッドのスレッドIDを保存しておくとかだ.あとは,システムコール呼び出しのトレースを保存しておくとか,スレッド切替えのトレースを保存しておくとか.

このようなデバッグ機能は,ライブラリで実装すべきという意見もある.まあアプリケーションプログラムだと,デバッグ性を強化したメモリライブラリなどは昔からあって,2重解放などを検知してくれたりはする.

しかし今の時代,OS側でこれくらいのデバッグ機能を持っていてもいいと思うし,OSでないとサポートできないようなデバッグ機能もある(スレッド切替えのトレースなどはその典型).そもそもデバッグ用のログなんて常にとっておいてほしいものなのだから,ライブラリを使ったときだけなんていうケチなことは言わず,OS側で常にとっておいてくれてもいいと思う.

とくに組み込みOSというと,「可能な限り小さくコンパクトに」「無駄は極力省いて」「最低限必要なもののみ実装」といったような考えが根強く,デバッグ用のログを(そのためにメモリを余分に使って)残すなんてとんでもないと,のっけから否定されてしまうことも多いと思う.しかし今の時代,メモリ使用量をキロバイト単位で節約することよりも,デバッグにかかる工数を削減することのほうがよっぽど重要であることも多いだろう.まあそうではなく相変わらずバイト単位でメモリを削ることが必要なこともあるだろうが,今となってはそちらのほうが少数派なのではなかろうか.もしくは「少しでも削らないと」という古い考えにとりつかれているだけで,もはや誰もそんなこと望んでない,ということもあったり無かったり...?

けっこう意味不明なのは,「デバッグ用のログなんてメモリを余分に使うのだから,実装すべきではない」とか言っておいて,「どうしても必要ならばライブラリで実装すべき」とか言われたりすることだ.ライブラリで実装したほうが,メモリを余分に使うことになるのだけど...?無駄を省いてOSはコンパクトにしたい,というのはわからなくもないが,そのせいでライブラリが肥大化して全体としてサイズが増えたら本末転倒では?と思うのだが.

デバッグ機能もそうなのだが,実はOSでサポートすべきで,OS側が対応すればきれいに解決するのだけど,OSに手を入れられないのでライブラリでなんとか実装する,という機能は実際に多いと思う.OSに売りものを使っていたりするとなおさらだ.

自前で独自OSを作って利用していることも多いと思うが,アプリだったらガンガン改良するのだが,ことOSとなると,なぜか手を入れるのを極端に敬遠されるということもあるように思う.「OSは極力いじらない」という考えが,根強くあるように思う.

OSでサポートすべきなのにOSに手を入れられず(もしくは手を入れることを恐がって),ライブラリやアプリ側でがんばって対処する,というのはとてももったいないことだ.だってOS修正すれば済むことじゃん!というわけだ.OSだって普通のプログラムなのだから,手を入れるのをためらう理由はあまりない.(失敗するとシステム全体がおかしくなるので恐い,というのはわかるが,そのためにきちんと修正案を吟味して十二分にテストをすればよい.恐がってOSには一切手を出さず,ライブラリで頑張って対処してよけいに工数が増えるというのは本末転倒)

なので,そのような機能をKOZOSを使って実験・実装してみて,「OSは極力いじらない」という世の中の風潮を「OSは改造してあたりまえ」という考えに変えていければなあ...そのようなOS改造時の際のサンプルにすることができればなあ...という思いがちょっとある.とくにデバッグ機能に関しては,いろいろお試しで実装してみたい.これは,仕様がガッチリと決ってしまっているμiTRONではできないことだ.

デバッグはもはやOS側でサポートする時代だ!と個人的には思うのだ.
AD

KOZOSの方向性について

テーマ:
(注意)このブログは本家のほうの文章部分のみの転載です.ソースコードの配布,画像などについては本家のほうを参照してください.文章中のリンク先は面倒なのですべて本家のほうに変換してしまっているのでご注意ください.

えーと,移植編第1回であえて書かなかったことなのだが,実は一番言いたかったことがある.まずは移植編第1回のソースコードを見てほしい.

% ls
Makefile crtn.c kozos.h make.sh startup.s
command.c extintr.c ld.scr memory.c syscall.c
configure.h extintr.h lib.c memory.h syscall.h
crt1.c idle.c lib.h serial.c thread.c
crti.c kozos.c main.c serial.h thread.h
% cat *.[ch] | wc -l
1933
% cat thread.c | wc -l
554
%

ソースコード全体で,2000行を切っている.中核である thread.c にいたってはわずか500行程度.これだけでも,スレッド管理やメモリ管理をしてくれて,スレッド間通信も提供されている.OSってこれくらいで作れちゃうもんなんだな.

どうも,OS作るのは非常に難しいと無駄に思われている気がする.しかしOSって簡単なものならば作ることはたいして難しいことではなく,ソースコードの量的にはむしろパッと作ってしまえるようなものだ(実際,KOZOSの原型は1日程度で作っている).そりゃまあファイルシステム積んだりネットワーク機能積んだり多CPU対応したり様々なデバイスに対応したり汎用的な構造にしたりすれば,そりゃもうたいへんな時間と知識が必要だ.だけどそれらはOSの本質ではなくて,最低限の機能に抑えれば,わずか2000行程度で書けてしまうもんなのだ.

組み込みOSはとっつきにくいとか勉強が難しいとか自作はたいへんと思われている理由なのだけど,思うにはじめるまでの敷居が高いのが原因だと思うのだな.まずは動かしてみてみたいので,なんらかの組み込みOSが動作するターゲットボードを選ばなければならないのだけど,これが数万円もして,それでも頑張って購入して,ビルド環境作りに3日間,OSがビルドできるようになるまでさらに3日間,で,ようやくファームウエアが作成できて,インストールしてリセットボタン押したらウンともスンとも言わない...こんな感じで,普通はモチベーションが続かずに終ってしまう.ほんとはOSの勉強がしたいのに,それを動かして試してみるというスタートラインに立つまでだけで,いろんなハードルがあるわけだ.これは,それが本業ならばいいのだけれど,勉強のために個人でやるとか,中学生や高校生が遊びや部活動でやるとなると,作業的にも金銭的にも,ちょっと厳しいだろう.KOZOSのユーザーランド動作は,このような現状に対するひとつの回答でもある.

世の中にOSは星の数ほどあり,オープンソースなOSもいろいろあるのだけど,OSの勉強となると,サンプルに適切なOSがあまり無いと思う.まず思い浮かぶのはLinuxやNetBSDだけど,これらはOSの勉強には大きすぎるし,まず全貌を理解できない.

あとはμiTRON系のTOPPERSHOSなのだけど,これらも(OSの基本構造の学習用サンプルとしては)大きすぎると思う.あとμiTRON系だと,結局はμiTRONの勉強になってしまい,「OSを作る」という学習には向いていないと思うのだな.というのは,μiTRONのかなり完成された仕様がすでに存在しているので,自分でシステムコールを設計したり追加したりする,という学習に向いていないと思うのです.仕様がはじめから用意されているので,どんなシステムコールが必要なのか?そのシステムコールがなぜ必要なのか?という学習にも向いていない(そのシステムコールははじめからありき,という雰囲気になってしまう).あとわからないことあるとすぐに「μiTRONの仕様を読んで...」ということになってしまい,これってOSの勉強でなくμiTRONの(仕様の)勉強だよなあ,ということになりがちだ.

実際,μiTRON関連の書籍とかはいっぱいあるのだけど,「μiTRONの上でアプリを作って動かしてみよう」「μiTRONを使って制御実験をしよう」というような感じで,まずμiTRON系OSありきで,その上でアプリを動かす,という内容のものがほとんどであり,OSを自分で設計して作る,どのようにしたら便利な(実用的な)OSになるか考える,という方向性のものではない.

で,KOZOSの目指すところとなる.
  • PC-UNIX上で動作することで,誰でも簡単に(ボードを購入することもなく)試せる.
  • さらに実ハードウエアで動かしたいと思っても,数千円で買えるような(中学生がおこずかいで買ったり,高校のパソコン部が部費で買えるような)ボードの上で動作する.
  • ソースコードは余計なものは一切はぶいて,要点のみわかりやすくする.大規模開発やオブジェクト指向などの知識が無くても読める.プロのプログラマとしての知識が無いアマチュアにも読める.
  • 多CPU対応については,ソースコードは共通化せずに各CPUごとに専用化して,読みやすくする.
  • 多ボード対応時に,そのボードでのスタートアップガイド(まあ,このホームページですが)を充実させる.
  • ビルドのためにスクリプト実行とかは不要.動くソースコードをパッと読める.
このへんがKOZOSの目指すべきところなのではないかと思うのだな.実用性とか,多デバイス対応とか,多CPU対応とか,そのときのソースコード共通化とかは考えないわけだ.だってそのようなきちんとしたOSはすでにいっぱいあるし.まあもともとKOZOSはぼくの趣味と勉強のために作っているのだけれど,せっかく作るのならば,今までに無いものにしたいなあというわけだ.
AD

KOZOSとは?

テーマ:
(注意)このブログは本家のほうの文章部分のみの転載です.ソースコードの配布,画像などについては本家のほうを参照してください.文章中のリンク先は面倒なのですべて本家のほうに変換してしまっているのでご注意ください.

KOZOS(Kernel Over Zone Operating System)は教育用というか,勉強用,独学用,いじって遊ぶ用のOSです.

OSというと動かすのにインストールしなければならないというか,いじるにしても環境作りがまずちょっと面倒であったり,まずはターゲット機を購入する(もしくは探すところから)必要があったり,いろいろ試すにしてもフラッシュへの焼き込が必要とかで気軽に試せなかったり,デバッグが大変であったりというようなイメージがあります.まあ最近のOSはそうでもなかったりするのだけど,PC上で1アプリとして気軽に(ここ重要!)ビルドできて,組み込みOSっぽく動くようなものがあったらおもしろいかなーくらいの感覚で,自分の勉強として作ってみました.というわけで分類的にはOSというよりもスレッドライブラリのような気もするのだけれど,スレッド管理や資源管理(CPU時間も資源のひとつです)など,やってることはOSとだいたい同じなのでここではOSと呼んでいます.そもそもスレッドライブラリを作ることが目的なのではなく,勉強用のOSとして,構造は組み込みOSなのだけどPC上で動作する,という路線で作っています.設計も,スレッドライブラリではなく組み込みOSに似せること(組み込みOSならば,こーいうふうに動作するべきなんだろうなーという視点)を主眼に置いています.つまりスレッドライブラリとしての実用性とかではなく,KOZOSの動作がわかれば組み込みOSの動作もわかるようになる(んではなかろうか)という,そーいうつくりを目指しています.そーいう意味では,疑似組み込みOSというのが正しい言いかたかもしれません.

実は Toppers ではそのようなことができて,Linux とかのOS上で動くスレッドライブラリとしても使えたりするのだけど,まあKOZOSは PC-UNIX 上での動作のみに限定して,とっつきやすさ,わかりやすさ,読みやすさ,いじりやすさをテーマにしてみようかな,と.そういう意味で,組み込みOSやスレッドライブラリは既にいろんなものがあるけど,こんなような勉強用の疑似OSって今まで無かったような気もする.(あったら筆者の無知です.ゴメン)

とくに,気軽にビルドして試せるということは非常に重要.社会人になると学生とは違い,まとまった時間でどっしりと構えてじっくり勉強できることってそうそう無くて,皆無ではないし,そういう時間を自分で作ろうとすることも大切だけど,やっぱしあいた時間とかでちょこちょこマメに勉強する,とか,通勤電車の中や家に帰ってからヒマを見つけて,あした(明日,ではなく,未来という意味ね)のためにちょっと勉強しておく,という技術が必要になってくる.なので,まずはターゲットマシンの確保とビルド環境の整備に3日,実機で動作するようになるまで苦戦してさらに3日,ソースコードの読破に1週間なーんてのはそれが本業ならばいいのだけれど,自分の勉強としてはなかなか難しい(モチベーションを保つのも難しい)ので,こーいう単純なサンプルコードで暇な時間(通勤電車の中とかね)にパッと勉強できる,コード量が少ないので紙に印刷して持ち歩いて暇な空き時間に読める,規模が小さいので簡単に手が入れられて,いろいろ試しながら楽しく勉強できるというのは,とっかかりとしてとても大切だと思う.とっかかりさえできれば,あとはそれなりに巨大なソースコードを見てもなんとなく何やってるかくらいはわかるようになるものです.

組み込みOSの勉強をしていると,「再入」「プリエンプティブ」「リアルタイム性」「排他」「同期」なーーんて言葉というか概念がいっぱい出てくる.そして,それらを説明している資料もいっぱいあるのだけど,やはり理論的な説明だけではわかりにくい.しかしこれらのことを実際に試してみるとすれば,きちんとした組み込みOSを用意して,ターゲットボードにインストールして,お試しアプリを作成して動かしてみる,ということになる.もちろんコンパイル環境作りから必要だし,どんなふうに動いているのかを確認することすら,場合によってはたいへんだ(printf()が使えなかったりね!).しかしこれでは初心者はとってもとっつきにくい.なので,気が向いたときにPC上でパッと試せる,実際に何が起きているのか,動作させてみて見てみることができるというのは,とてもとっつきやすくていいと思う.PC上での動作ならば,printf()とかでログを出させるのも自由自在で融通が効く.そーいうためのサンプルOSとしたい,という考えもある.

あとはGDBによるリモートデバッグに対応させたいというのもある.リモートデバッグに関する雑誌記事とか国産の資料とかってとっても少ない(ていうかほとんど無い)のだけれど,無いからにはちゃんと書かないとなーという思いもある.組み込みやるならば必須の機能だと思うし,ということで実はKOZOSはリモートデバッグのGDBスタブ実装のためのサンプルOSとして作ったというのもあるので,とくにリモートデバッグのスレッド対応に関して,きちんと実装させてみたい.KOZOSでリモートデバッグが実装できれば,実際の組み込みOSでも原理的には同じように実装できるはず.なので,このようなサンプルコードはどこかで必要とされているはずだ!

ちなみにOSの作成,i386のリモートデバッグ化,リモートデバッグのスレッド対応とも,ぼくはKOZOSが初体験となります.どんなものになることやら!
  • わかりやすさ,いじりやすさを優先する.(実用性はあんまり考えない)
  • すっきりした,見通しのよいシンプルな実装にする.
  • 余計な機能は積まない.わかりやすく,単純にするためにエラー処理なども省略.良い意味での手抜きコードにする.
  • GDBによるリモートデバッグに対応する.(スレッド対応もする)
  • へーこれっておもしろーい,と思えるような連載にしたい...なあ...
対象は FreeBSD-6.x 以降です.FreeBSD-4.x では getcontext() が使えないため動きません.Linux は...試してないのでちょっとわからないですが,シグナルハンドラ入った後のディスパッチ処理がどうなるか不明.まあ動くかもしれないし,動かないかもしれないというくらいです.スレッドのディスパッチにsetjmp()使っている初期のコードでは,なにかしらの対応は必要でしょう.まあOS依存がある部分は,そのように説明します.なぜ Linux でなく FreeBSD なのか! 単にぼくがメインOSとして FreeBSD を使っているからですな!

組み込みOSでもスレッド化でもそうなのだけど,実際にアプリ作成をやってみると,非常に新しいパラダイムというか,あーこんなプログラミング手法もあるんだなーと思う.たとえば telnet によるコマンド受付と http サーバと定期的な時計表示とデモ画面のリアルタイム動画をひとつのアプリでぜんぶいっぺんにやろうとしたらどうするか?いちばん単純なのは,signal()でSIGALRMのハンドラ登録してalarm()でタイマかけてselect()で待つ,という実装でしょう.でもたとえば telnet でのコマンド実行処理で数秒に渡ってCPUを占有してしまうような重い計算処理とか,httpサーバで処理途中に応答待ち合わせとかしたい場合とかあったらどうするのか?alarm()でタイマかけて定期的に呼んでもらうか?うまくやらないと時計は固まるしリアルタイム動画はカクカクになるし,あーめんどくせー.

でもこーいうのはもう時代遅れ!スレッド化の手法を勉強すると,プログラミングとデバッグに新しい道が見えてきます.その道が常に正しい,というわけではないけれど,ひとつの手法として,勉強する価値はおおいにありますよ!
AD

独自OSを作ってみよう!

テーマ:
(注意)このブログは本家のほうの文章部分のみの転載です.ソースコードの配布,画像などについては本家のほうを参照してください.文章中のリンク先は面倒なのですべて本家のほうに変換してしまっているのでご注意ください.

えーと,いちおう書いておきますが,ここで説明していることはすべて無保証です.サンプルのソースコードやその他プログラム,各種情報などは,個人の責任の上で利用してください.

ちょっと思いついて自作OS(とは呼べないような単純なシロモノではあるが,とりあえずここではそう言っておく)というものを作成してみました.まあすでにあらかた作っちゃったので,作ったものをそのまま公開してもいいのだけれど,勉強用のOSなので,自作していく過程と言うか,発展していく過程と言うか,どんなふうに作っていったかを書いてみるのもいいかなーと思い,連載という形で思うままに書いてみます.優先度とかプリエンプティブとか再入とか排他とか,組み込みOSの基本的な動作について,KOZOSを使って試してみる(そーいうためのサンプルOSにする)という目的もあります.そんなようなことについても書いてみたい.

KOZOS(Kernel Over Zone Operating System)は教育用というか,勉強用のOSです.日本語では小僧's OS と書きます(なんだそりゃ).実体はOSというよりもスレッドライブラリのような気もするのですが,やってることはOSとだいたい同じなのでここではOSと呼んでいます.ほんとは疑似組込みOSというのが正しいでしょうか.ちなみにPC上のプロセスとして動くためリアルタイム性は無いですが,頑張れば,(構造的には)リアルタイムっぽい作りにすることもできるかも...

ご意見,要望などあれば,ぜひメールください!