おがさわらなるひこのオープンソースとかプログラミングとか印刷技術とか

おがさわらなるひこ @naru0ga が技術系で興味を持ったりなんだりしたことをたまーに書くブログです。最近はてなダイアリー放置しすぎて記事書くたびにはてな記法忘れるのではてなブログに移行しました。

クリエイティブ・コモンズ・ライセンス
特に断りがない場合は、本ブログの筆者によるコンテンツは クリエイティブ・コモンズ 表示 - 継承 4.0 国際 ライセンスの下に提供されています。

第92会 カーネル読書会 「ブートローダとOSの親密な関係」

お馴染み (といってオイラは参加するの二回目だけど) id:hyoshiok さん主催のカーネル読書会
今回はブートローダ GRUB の開発者奥地さんのお話。
資料は YLUG の資料ページ に上がってるので見よう。

あ、奥地さんのプレゼンの前に FixStars さんから Cell/B.E. (ご存知のとおり、PowerPC ベースの PS3 の CPU です) の話とかあったんだけど、オイラ的にはイマイチ興味外だったので省略。でもいくらなんでも Qosmio に積むのはやりすぎじゃないですか? 東芝さん。

内容詳細?

手元のメモから。

ブートローダから OS へ

# 小ネタ:ディスクの数を知る BIOS コールは(なぜか)存在しない

  • Intel の執念の (笑) 互換性維持のため、x86 系 CPU は必ずリアルモードで起動する
    • ちなみにリアルモードとは「アドレス空間が仮想化されてない」って意味で ”Real” なんだそうな
  • ただし 32bit レジスタの上位ビットも使える (遅くてオペコード長いけど)。
  • Gate A20 問題
    • A20 とはむろんアドレスライン 20 のこと。
    • デフォルトでは Disable になっている
    • ので、1MB ごとにアドレスがラップしてしまう
    • しかし標準的 PC アーキテクチャではまともな方法で Enable にする方法がない
方法その1
キーボードコントローラがなぜか機能を持ってる。多分余ってたら割り当てたんだろう。しかし当然KBDだからバッファリングするのでバッファクリアしてあーだこーだするので遅い。
方法その2
System Control Port A 一部 BIOS で実装。しかし呼び出すとハングする奴もいるので気軽に (というかほぼ) 使えない。
方法その3
BIOS Call INT 15, AX=2400h 使えれば便利だが、すべての BIOS でサポートされているわけではない (割と新しめな BIOS のみ)。
  • PC 系の起動シーケンス '資料の8ページ見てもらえば早いんだけど)
    • まずは CPU にパワーオン
    • ROM をアドレスにマッピングしてブート*1
    • ROM にあった BIOS がメモリやらチップセットやらを初期化
    • 「最初のディスク」の先頭セクタを 0000:7C00 に読み込んで Jump
  • まてまて?「最初のディスク」って?
    • 物理的な接続とは無関係
    • 要は BIOS のブートデバイス……ってことでよいのかな?
    • BIOS では1セクタ=512byte と決まっている。実際のセクタサイズは無関係
  • MBR のユーウツ
    • 前述のとおり 512byte しかないのでたいへん!
    • しかも FAT の BPB (BIOS Parameter Block) とか NT Magic (NT がなぜか書く 1byte のコード。何に使ってるか不明) とかで食われちゃって 400byte ぐらい。ぎゃー。
    • もちろんコーディングはアセンブラゴリゴリ。バイナリゴルフみたいなもん (笑)
  • GRUB の歴史……は (資料 p.14) を見ればいいんで省略
    • GRUB はそもそも「LILOLinux しかロードできない!」「そんなんヤダ!」といって作られた。
    • 名前は Grand Unification Theory (大統一理論) のもじり
    • ベースは FreeBSD のローダだが、ロジックだけもらってコードは書き直されている
    • 複数モジュールに柔軟に対応できることが設計思想 (真のマイクロカーネルである GNU Hurd では必須)
    • GRUB2 では「新たなる統一」として「下位のアーキテクチャ (CPU、BIOS) 統一」を目指している。PPC サポートはその一つ。
  • GRUB の構造
    • さすがにブログで書く内容ではなくなってきたので省略。
    • 簡単に言えば、ディスクの1シリンダ目 (63 セクタ) は OS は使わないということを利用して、
  1. まずは割り込みを Disable にして (チェーンローダで割り込み Enable にするタコがいるから)
  2. A20 ラインを Enable にして (まずは BIOS → ダメなら KBD。SysCon は怖いので使わない)
  3. CS:IP がぐちゃぐちゃになってるときがあるので 0000:7C00 に Jump してきれいにして
  4. スタックも掃除して (ここまで他人の後始末)
  5. 次のセクタを読んで
  6. 起動
  7. 次のセクタには圧縮伸長ルーチンなど基本的なコードが入ってる。
  8. それと圧縮されたいろいろな基本サービスが。
  9. まずは圧縮を解いてメモリへ展開し、そこにジャンプ
  10. そうするとファイルシステムにアクセスできるようになるので、ファイルシステムの定義ファイルをよんでごにょごにょ。
OS からブートローダーへ
  • 一言で言えば「Linux はダメ OS」。
  • Linux のブートシーケンスは The Linux Boot Protocol by H. Peter Anvin (hpa) に書かれている。
    • これは奥地さんのアピールでやっとかかれたドキュメント。
    • でも hpa はどうやら GRUB が好きじゃないらしい。Too big だからって。

GRUB 2 について

  • 繰り返しになるけど GRUB2 の売りは「下周りも大統一」。
  • x86 についてはほぼ実用的なレベル。
  • GRUB Legacy にはなかった機能も入ってます
    • 書くの面倒くさいので資料 p.31 を見てね。
    • 面白かったのが搭載言語の話で、大きさとユーザ数で Bash like になったらしいけど、奥地さんは scheme が好きなのでそう提案したら「そんなことしたらユーザがいなくなっちゃうだろうが、何考えてんだ」って怒られたとか、Lua を試しに突っ込んでみたら 100KB ぐらいになってありえないね、って話とか、ささださんが来てたので Ruby だとどんぐらい? って言うはなしになって、サブセットで 300KB、そりゃ無理だ、とか、普段とレベルが違う話で笑えた。

雑駁な感想

ローレベル (ハードウェアに近いという意味ね) 過ぎてオイラのへっぽこ脳みそではついていけないかと思ったけど、かなり面白かったよ。

ローレベルにはローレベルの技術があってさ、それは例えば、すごい新しいファイルシステムを作るとか、エレガントなLLの仕様をつくるとか、そういう行為に匹敵するすごい仕事なんだなって改めて思った。

その後のビアバッシュも面白かったし、さらに2次会(あれ、3次会になるのかな?)の奥地さんの壊れ方も面白かった ;ー)

Linux カーネルにワクチン用の入り口をつくろうとか言う議論の話もちょっと面白かったな。
今だとワクチンソフト自身がカーネルシステムコールフックするとか言うウィルスっぽいことやってる。それは ugly なのでカーネルにサービス入れてくれと。そしたら当然、そのサービス悪用してウィルス作るやつって出るんじゃね? と。そもそもお前らが使ってるウィルスパターンに Linux のウィルスなんかあるのかと。一個もないだろと。そんなののためにサービスなんか作れるかボケ、みたいな議論があったとかなかったとか。酒の席なので覚えていない。
Printing みたいに関わってる人間が少ないコミュニティと違って、カーネルコミュニティはいろんな議論があって大変なんだろなーと。


最後に。
奥地さん、1時間枠に2時間オーバーはしゃべりすぎです (笑)

*1:今って BIOS 直接 ROM からブートすんの? 昔は一回メモリに読んでた記憶が……。