btcf1系のネタ - 結局KHBIOS

  • (by K, 2007.02.27)

(1) 目的

  • OSASKや「はりぼてOS」をCFからブートしたい。というかCFからブートできないとFDかCDブートになるわけだけど、FDは遅いしうるさいし信頼性がない、CDはCD-RWにライティングするのが面倒だし、かさばる。今までのbtcf0系ではOSASK以外のOSの起動をぜんぜん考えてこなかったので、もう少し汎用的にしたい。そういう意味ではKHBIOSっぽい。
  • OSC春のために「はりぼてOS」もCFブートにしたいなあと思ったのがきっかけ。習作KHBIOSはWin95との相性しか確認していないので、他のOSを使っているマシンに導入するのはちょっとためらわれる。

(2) 仕組み(最初の案)

  • 手抜きのためにFAT16フォーマット(含むSF16)のみ対応
  • 自動でPCカードスロット内のCFから1440KBのFDIMAGE0.BINというファイルを探す。もし複数のディスクイメージを入れたいのなら、適当に入れておけばいい。そして起動したいディスクイメージの名前をその都度FDIMAGE0.BINに書き換えればいいだけのことである。
  • ディスクイメージの中からシグネチャを探す。先頭64KB以内にないとダメ。シグネチャを見つけたら、そこから起動時のメモリ設定を読み取る。ディスクイメージのうちのどの部分をメモリのどこに置くか、が指定できる。
    シグネチャ8バイト 0x00 0xff 0x00 0x00 KHB0
    0x0001, 2バイトのステップ数, 対応機種ID, 2バイトの0
    0x0002, 2バイトのセクタ数, ディスクイメージ内のLBA, 物理メモリアドレス/512
    (上に同じものを必要なだけ繰り返す)
    0x0003, レジスタ番号(2バイト), 4バイトのデータ
    最後は8バイトの0
    • 0x0000はNOP
    • 0x0001はentryラベル
    • 0x0002はロードコマンド
    • 0x0003はロードレジスタ
    • 0x0004はbtcfシステム引越し
    • 0x0005は相対jmp
      • EIPへのロード命令はブートコマンドを兼ねる
      • 特別なレジスタ番号を指定すると、アドレスとデータを指定できて、データを指定したときにアドレスで指定した番地にデータを書き込める。
  • btcf1自身はワークエリアも含めて0x0010_0000〜0x0010_ffefに存在する。これを破壊しないようにするか、もしくはどこかに退避しておいてあとで元に戻せば、再起動も可能。再起動時には起動するディスクイメージ名を指定できる。

(3) 仕様調整

  • こんな柔軟な仕組みなら、1440KBに限定する必要はないな。もっと少なくてもいいし、多くてもいい。
  • ロードレジスタのレジスタ番号
    • 0x0100:EAX
    • 0x0101:ECX
    • 0x0103:EBX
    • 0x0107:EDI (EBP〜EDIは指定しても無視するかもしれない)
    • 0x0140:seg0
    • 0x0145:seg5 つまり GS
    • 0x0180:EIP(ブートもする)
    • 0x0200:汎用アドレスimm
    • 0x0201:汎用データimm
    • 0x0202:レジスタ間MOV?(主に汎用データ→汎用アドレス)
    • 0x0210:リード1バイト(汎用データへ入る)
    • 0x0211:リード2バイト
    • 0x0212:リード4バイト
    • 0x0214:符号拡張リード1バイト
    • 0x0218:ライト1バイト
    • 0x021c:汎用データ&ライト1バイト(アドレスは汎用アドレスを使う
    • 0x021d:汎用データ&ライト2バイト
    • 0x021e:汎用データ&ライト4バイト
    • 0x0220:スペシャルデータロード
    • 0x0221:スペシャルデータライト
    • 0xf000:ファイル名の最初の4バイト
    • 0xf003:ファイル名の12〜15バイト
    • 0xf004:ファイル名長
    • 0xf005:ファイル名格納先アドレス
    • 0xf010:ブートデバイスサーチ0
    • 0xf017:ブートデバイスサーチ7
    • 0xf018:ブートデバイスサーチ構造体長
    • 0xf019:ブートデバイスサーチ構造体アドレス
    • 0xf01a:今回のブートデバイス(read-only)
  • スペシャルデータをレジスタに読ませる方法はない。それをやるとbtcfが複雑になりすぎる。とりあえずメモリに書いておいて、起動直後にOSがやれば済むこと。
  • デバイスをCFだけにする必要もない。FDDやCDでもいいと思う。もはやKHBIOSのサブセットといえそうだ。
  • 最初に探すディスクイメージファイル名は、STARTUP.KHBのほうがいいかもしれない。で、ここにはメニューOSを入れておく、と。そのままbtcf1系対応のOSASKを入れておいてもいいけど。
  • FAT16だけ対応というのはなんともさみしい。FAT12やFAT32やNTFSにも対応したいし、CD-ROMのフォーマット(ISOなんちゃら)や、Linux系のフォーマットにだって対応したい。
    • しかしこれら全てのフォーマットをbtcf1が理解できるようにするというのはいかにも現実的ではない。そんな機能をつけていたら64KBを超えてしまい、メモリの問題や起動時間が長くなるという問題を抱えてしまう。
    • ということでbtcf1は独自の寄生型ファイルシステムを持つことにする。
      構造体全体の長さファイルサイズファイル位置ファイル名の長さファイル名オプションフィールド
    • ファイル名は純粋なファイル名である必要はなく、とにかくファイルIDとして一致すべきデータのかたまり
    • このリストもデバイスのどこかにおく。各フォーマットに対応したツールで、この構造体をもつファイルを自動生成する。シグネチャをつけておくのでbtcf1が探せる。
  • btcf1が起動のたびに毎回探すのは効率が悪いし、遠くまでは探しきれないので、絶対jmpもつける。
    • 0x0008 絶対jmp(セクタ番号ではなくバイト単位で) -- ファイル名構造体のありかを示す
    • 0x0009 絶対jmp(QW単位) -- 上記ブートコード列へのjmp
    • 0x000b 絶対jmpのプリフィクス 上位6バイトを指定 シフトして連結するので、多重使用も可能
  • 細部は違うがますますKHBIOSに似てきた。
  • こういう汎用性を意識すると、512バイト/セクタ固定なのはちょっといやだな。

(4) 旧KHBIOSとの差異

  • btcf1は単に手抜きという理由で旧KHBIOSに予定していた次のような機能を考えていない。
    • 起動させたOSに対して、FDD/HDD/CD-ROM/CFなどを読み書きするための32bit-BIOSの提供
    • 複数のOSを起動して切り替える機能

(5) やっぱりKHBIOSに

  • 考えが変わった。KHBIOS化することにする。方針を改めて、頻繁にリアルモードに行くことにする。
    • 仮想86ではUSB-FDDやUSB-HDDやUSB-CFのサポートがうまくいかないことがある。というかうまくいったことがない。
  • キーボードやマウスもKHBIOSの管理下におく。必要に応じてリアルモード上のBIOSからデータを取ってくる。これでUSBキーボードやUSBマウスもサポートできる?!
  • タイマをのっとるのは、定期的にスキャンする必要があるかもしれないため。
  • デバイス全体もイメージとみなす。その中にあるファイルもイメージ。どのデバイスにも読み書き可能。デバイスの指定はパーティション名で行うので、つなぎかえてもIDは変わらない。
  • メモリも大雑把にはKHBIOSで管理する。対応OSは、ほしいメモリを自分から指定するか、もしくはサイズだけ指定してアドレスをもらうこともできる。デバッグのため、他のOSのメモリへのアクセスも許すし、必要な情報は提供する。
    • HLTする代わりに、他のOSへCPU時間だけを渡すこともできる。
  • 表示デバイスについて:
    • VESA非対応でもVGAまでは簡単に表示できる。矩形を指定してflushすると、KHBIOSが転送してくれる。
    • 色をRGBで指定すると(8-8-8か10-10-10)、4つの色情報を返す。1つはいいとして、残りの3つはディザをやりたいときに使う。4bit型、8bit型、16bit型、32bit型。一応逆もある。
    • VESA2.0未満でもこの方法ならいける。
    • エミュレーションなのかそれともリアルなのかは、KHBIOSに聞けば教えてもらえる。
  • これで、メモリ・タイマ・キーボード・マウス・画面・ストレージは抽象化できたことになる。他にやるとすれば、RTC、ROMフォント、ゲームパッド、サウンド、シリアル、パラレル、LANくらいだろうか。
  • ここまでできれば「はりぼてxen」といえそうな気がする。はりぼて用だといえるし、仕様的にも本家と比べればはりぼて。
  • なんかすごくやる気が出てきた原因は、新しくメインマシンになったsizkaにPS/2キーボードがつけられないことや(USBキーボードのみ)、頻繁にリアルモードに帰ればいいじゃないかという「ひどく効率が悪いが実装は簡単そう」な方法を思いついたせい。

  • うまくやれば、ひとつの画面上に複数のOSが共存するようなこともできる。
  • KHBIOS上で動くOSは果たしてOSといえるのか?ハードウェアの直接管理をやっているとは言いがたいのに?
    • そういう意味ではKHBIOSが真のOSになってしまっているのかもしれない。
    • でもKHBIOSはハードウェアを抽象化しているだけで、操作体系やファイルシステムについては干渉していない。
    • というか、こういうレイアの分割が必要になったんだ、むしろ。それはxenが証明しているといえるのではないか?(うーん、微妙)
    • 非常に落ちにくい環境が必要なんだ。いつも全部作ることになると落ちて落ちてしょうがない。(それなら落ちないOSの雛型を使うのはどうか?)
    • KHBIOSの仕組みのうち、使えるものは使い、じゃまなものはオーバーライドすればいい。
    • 新OSを作らなければいけないとする。雛型OSから出発するとして、その雛型部分をDLLにしたと思えばいい?つまり開発初期の踏み台になればいい?
    • というかいまさら何を。VESAを使うのはOSを作らないことになるのか?違うだろ?BIOSが真の地位に戻るという話なんだと思う。
    • BIOSはいわばファームウェアの延長みたいなもの。KHBIOSはOSとBIOSの境界をちょっと調節するだけの存在。
  • ディスクイメージ管理ツールは、バックアップツールとしてもいけそうだな。

(6) eh4を前提にブートスクリプト改変

  • シグネチャは6バイト。IPLの隙間に押し込めるようにコンパクト化。
  • unifiedタイプ 00 F0 KHB0
    • ヘッダがある。長さ(4bit単位)とフラグ。
    • 0:NOP
    • 1:ターミネータ
    • 2:リマークフィールド
    • 3:自己ボリューム名定義
    • 4:ブートスクリプトスタート
    • 5:パーティションリストスタート
      • ここで長さ0にすると拡張モード。外部の場合、検索範囲を指定する。範囲0だと先頭から2バイトアラインで128KB以内。最初にアドレス指定単位(LSBは3や4のコマンドについてEXTかIMMか)がある。
  • ノーインフォメーションタイプ 00 F1 KHB0
  • ブートスクリプトオンリー 00 F2 KHB0
    • ヘッダがある。長さとフラグ。
    • 0:NOP
    • 1:ターミネータ
    • 2:リマークフィールド
    • 3:エントリラベル
      • フラグ、対応機種コード、第一区画最低メモリ量、第二区画最低メモリ量、第三区画最低メモリ量
      • フラグ:
      • 第1区画メモリアドレス指定するか、メモリアドレスをブート情報テーブルにストアするか
      • 初期画面モードの指定(許容メモリモデル、最低解像度、最高解像度)
    • 4:内部モジュールロード
    • 5:ロードレジスタ等
      • GDTの設定もこれで行う
    • 6:スクリプトの相対ジャンプ
    • 7:リザーブ
    • 8:外部モジュールロード
  • パーティションは入れ子だが、原則としてはパスではない。
    • .で始まる相対パス、それ以外は絶対パス、/で始まるデバイス名
    • 長い名前を付けることになりそうだが、ニックネームがほしければ、ブロックを一つしか持たない複合ブロックを定義すればいい。

  • 想定:
    • IPLがそのままOSみたいな感じ(ファイルシステムがない):
    • イメージ内にファイルシステムがあり、OSのファイルはひとつのブロック:
    • イメージ内にファイルシステムがあり、OSのファイルはひとつだけど、内部がブロック化:
    • イメージ内にファイルシステムがあり、OSのファイルも複数:
    • OSASKの場合:
      • FDIMAGE0.BINにパーティションイメージがあってOSASK.EXEを指定。ルート指定しないフラグがあり。そしてデフォルトブートフラグをON。
      • OSASK.EXEの中にもパーティションイメージがあって、ルート登録しないフラグがあって、init.binやwinman0.binなどがある。その中のinit.binにのみデフォルトブートフラグがある。
      • init.bin内のスクリプトにより、init.binやwinman0.binはメモリに配置される。
      • いや違う。OSASK.EXEの中にパーティションテーブルなんか必要ない。FDIMAGE0.BINがOSASK.EXEをパーティションとしたのは、中身が分からないからだ。しかしOSASK.EXEは当然のことながら中身が分かる・・・が、結局アーカイブだから、OSASK.EXEに限ればやっぱりパーティションテーブルでもいいのか。つまり本来は不要だけど、兼用ということだな。・・・うーん、でも微妙だなあ。
      • リマークフィールドを入れたので、ブートスクリプトで名前や属性を入れればいい。
  • パーティションリスト内にブータブルマークがある。・・・いやブータブルなんかいらないか。デフォルトブートがどれであるか分かればよい。ブータブルかどうかはすべてたどれば分かる。

  • 起動時間が延びるのはいやなので、最初に全てのデバイスをチェックするわけではない。設定もしくはOSからの指示がなければデバイステストはしない。

(7) 実装開始

  • 最初は何を目標にしようか。FDDのみ対応。最初からプロテクトモード。はりぼてOSをダウングレードしたものを使用(5日目くらい?)。これがブートスクリプトでブートできればよし。
    • ビデオflushなし、キーボードドライバもなし。というか、プロテクトモード側のエントリが最初は省略。メモリ管理はあり。AT版のみ。
    • 次に画面モード切替をサポート。
    • 次にキーボードをサポート。
    • ストレージデバイスも増やしたい。

  • 5月中旬の目標:
    • プロテクトモードでもSTIできるようにする(割り込みブリッジを作る)。割り込みのネストは禁止。
    • とりあえず、えせブート。
    • (いくつかの割り込みルーチンについて、プロテクトモードのまま処理できるハンドラを書く。リアルモード時にその割り込みが起きた場合は、プロテクトモードに戻って処理。)

こめんと欄

  • また忙しくなってきたので、本格開発は4月からになりそう。 -- K 2007-03-02 (金) 23:14:04
  • 3/29くらいからフライングで作りはじめられる可能性もでてきた!体調との相談だけど。 -- K 2007-03-27 (火) 13:11:53
  • ひさしぶりにASKAでがんばり中。やっぱりASKAはいいのうー。 -- K 2007-03-31 (土) 14:06:53
  • またちょっと忙しくなって停滞中、もうやだー。でもとにかく数日中に何とかしたい。とりあえず最初のへぼバージョンのリリース目標日を設定しよう。5月の中旬。 -- K 2007-04-05 (木) 16:39:20
  • 地道に開発中〜。 -- K 2007-04-09 (月) 20:59:49
  • リアルモードBIOSがどんなハードウェア割り込みを使っているのか少し調べてみた。といってもQEMU上なのでちょっとうさんくさいけど。具体的にはPICのIMRを読んでみただけ。マスタは0xb8。スレーブは0x8f。うーん、IRQ13ってなんだ? -- K 2007-04-10 (火) 21:40:33
  • 今のところ超できの悪いDOSエクステンダ状態。 -- K 2007-04-10 (火) 22:24:55
  • 現在ハードウェア割り込みをどうするか検討しながらいじっているところ(リアルモードで処理するものとプロテクトモードで処理するものに分ける)。 -- K 2007-04-13 (金) 23:27:26
  • 今週は忙しい上に体調が悪くて進みません・・・うわーん。 -- K 2007-04-19 (木) 17:48:40
  • やっと体調回復・・・なんだけど雑用がたまってしまった・・・。でも5月中旬に途中までの状態をリリースする目標はまだあきらめていない。 -- K 2007-05-02 (水) 01:40:53
  • プロテクトモードでのSTIに関してはできるようになったっぽい。あとはえせブートだ。これができればリリースできる。 -- K 2007-05-05 (土) 23:52:53

コメントお名前NameLink

リロード   新規 編集 差分 添付   トップ 一覧 検索 最終更新 バックアップ   ヘルプ   最終更新のRSS
Last-modified: 2007-05-05 (土) 23:53:01 (5531d)