第92回カーネル読書会行ってきました

第92回カーネル読書会に参加してきました。
今日のお題は「ブートローダとOSの親密な関係」(講師:OKUJIさん)


GRUB開発者自らの発表でしたので、とても面白かったですよ。
BIOSの挙動の違いや明文化されていない慣習もあってブートローダーの開発はとっても大変そう(いつもGRUBは便利に使わせていただいています。ありがとうございます)
でもこういう話って興味深いですよね。オフレコの話もおおかったな(笑
今回は大変なボリュームで大変楽しめました。
(立ち見の出る盛況ぶりでした)


以下、メモ(正確性は期待しないでくだちい)



・冒頭の質問タイムで聴講者のレベル確認
 アセンブラのサンプルコードの結果、システムコール int 13の意味、/dev/hd*とはなに?



・コンピューターが起動するまで
 MBRをまずよむ / RealModeから起動する。恐るべし互換性 / セグメントについて
 A20 - 起動時はアドレスバスの20bit目はディゼーブルになってる。
 A20をイネーブルにするまともな標準がない困る。インテルのひとに聞きたいくらい。なぜかキーボードコントローラで設定するとか3通りくらいある
 有効か無効かは実際にメモリーに書いてみて試すしかない
 いろいろ不安定なので、GRUBが起動時にハングするのはこれのせいだょ


 MBRってどこから?→最初のディスク(起動したのが最初のディスク。BIOS依存でさっぱりわからない。BIOSもディスクの種類はわかったいない。→EDD ver.3ならわかるが・・・)
 BIOSは1セクタ512にあつかっているが、MOやCDはちがうので論理的に512バイト読む
 読んだコードのジャンプ先; 0000:7C00※これが07c0:0000になってるBIOSもあるorz
 BIOSが多少は初期化してくれるが、バグが多い。
 A20の状態や、割り込みが有効になってるのもある(スタックやレジスタは未定義)
 PH○ENIX-BIOSはいろいろ問題が多い・・・


 MBRは512バイトしかないので、貧民的プログラミング(バイナリGOLF?w)
 BPBとかパーティションテーブルのせいで、400バイトもない。NTはNT magicとかのフラグまである
 BIOSのWOrkaroundもつめこまないといけない
 たいへん


 やってること:割り込み禁止、アドレスセット→スタック・レジスタ初期化→自分自身の残りをロード(GRUB2は3段ブートしてる)


GRUBの歴史
 1995年から開発(Erich's GRUB)
 1999年からGNUプロジェクトになった(GRUB Legacy)みんながつかってるやつ
 2005年から、GRUB2の開発開始


 1999年にLBAサポートしてから8GByteの壁を破った(Okujiさんの成果)。当時Liloではできなかった。
 2004年 SaveDefaultが完成して、安全なブートができるようになった(リモートでもアップグレードでできる)
 2006年 PowerPCサポートでマルチアーキテクチャになった



GRUBが作られた理由
 大統一理論のモジリ?
 どんなOSでも使えるブートローダでOS間のブート環境を統一したい。
 →OSを作ろうと志すひとたちは、ブートローダで力尽きるひとが多い。たとえば・・・(オフレコ)
  GRUBつかって〜
  でも、まだなんでかブートローダ作る人はおおいよね
 OSとブートローダとの通信プロトコルも統一しよう
 複数モジュールに柔軟に対応できるブートローダがなかった。GRUBなら出来る(ファイルシステムを解釈してロードする)


・GRUB2の物理的構造
 boot:512byte (MBR)
 diskboot:512byte (MBR直後の空き領域(31Kbyteくらい)にkernelと一緒に)←ここにおくのは場所を固定したいから(慣習としてHDDの最初のシリンダーはOSには使われていないので、ブートローダをみんなおいてる)
 kernet:29Kbyte (圧縮して格納。先頭は展開ルーチンなので非圧縮)LZO,LZNAで圧縮(選べる)
 module〜:いろいろ (ファイルシステム上)


・GBUR2の機能的構造
 kernelに似通っている(が、ミニOSとよばれることもあるが、あくまで高機能ブートローダとして認識してほしい)
 
 memory / device / terminal / loader / partmap / filesystem / file / io / command-(menu,shell)といった抽象レイヤーがある。


Linuxのブートのされかた
 Linuxが特定のメモリレイアウトを要求する。
 zImageは、このメモリレイアウトにしたがって構築されている。
 GRUB自身のメモリ領域と被る(後から上書きすることになるから、GRUBをリロケータブルコードで書いて、自分自身は安全なアドレスに移動できるようになっている)
 Real modeで突入しないといけないので、ブートコードが1Mbyte以下でないといけない。だからA20はイネーブルにしないといけない。
 Linuxはなんで、Realmodeカーネル要るの?最初からプロテクトモードでBOOTできればいいのにね。(互換性の問題でこうなっているようだ)


・OSがブートローダにしてあげられること
 ・ブートローダを構築する
 ・設定する
 ・ブートの仕方を教える


ブートローダの設定
 ・バイナリイメージの書き換え(メモリ上で行う、diskbootやcoreimageなどのセクタ位置の調整などをする)
 ・バイナリイメージをディスクに書き込む(MBRなど)
  coreがMBR直度にある場合は決めうちでよいが、ファイルシステム上にある場合は大変。(Blocklistで管理する。フラグメント化してると大きくなる)


・ディスクの検出問題
 OSとBIOSで根本的に数え方が違う(バス単位 vs 十把一絡げ)
 GRUBは、bootとcoreが同じディスクなら検出不要だが、そうでないばあいはヒューリスティックに大体あうのを期待して数える。だめな場合は、手動設定する
 Windowsは、最初のディスクではないといけないなどの理由で、複雑になってる(Windowsめー)


 ディスクを検出する確実な手段があに。
 まともな間苗つけルールないし。どんどんデバイスが増える。rd,cciss,ida,mmcblkとか・・・何?
 全部ioctlしてさがすと余計なものもみつかるし遅い。大変


・ディスクの書き込み問題
 ファイルに書いたからといって、キャッシュがあるのでディスクにかかれるわけではない。
 BSDはfsyncで確実にかかれるが、linuxではfsyncではジャーナルにしか書きこまれない
 GRUBは、BLKFLSBUFでキャッシュをフラッシュして、sync 2回。これでもだめなら、readで読んだデータとデバイスから直接読んだないようが一致するまで、待つ。それでもダメなデバイスがある。祈りが必要w
(ioctlで確実にフラッシュするAPIつくといいね・・・改良しようか・・・?)


 デバイスに直接書くと、OS問わずOSが混乱することがある。ファイルシステムとの不整合が発生する。
 *BSDには、/dev/r*つかえば安全だけど、Linuxにはそんな気の利いた仕組みは存在しない(Lixnuの場合は、setupしたら出来るだけ早くリブートしよう。。。)


 linuxには、ブート関連には10年以上放置されてるバグがいっぱいあるよ・・・(みんなおもしろくないから、わざわざ見ないのね)
 lixnuにはいろいろいいたいことがある


・GRUB2が作られた理由
 OS側は大統一できたかもしれないが、これからはアーキテクチャも大統一の時代だ!どこでも同じブートローダが使いたい。
 GRUB Legacyは進化の袋小路になってる。抽象化、メモリ管理がなってない。x86,BIOSべったりハードコード。
 最新リリース1.96。
 Debianがもうすぐ正式採用
 PC用は実用上十分(fallback機能などこまかいきのうはまだないが仏用十分)


(EFIへの移植はアップルの秘密主義で大変。仕様は公開されているが実装はぜんぜん違うぽい)


・GRUB2の新機能
 Rescue modde搭載で、もっと安全
 ELF object formatでsynamic linkng可能(サードパーティの拡張がしやすい)
 Unicode対応
 ハードコードせずに、ファイル名、ラベル名、UUIDでデバイス検出
 LVM/RAIDサポート
 BashLikeなスクリプト(既存環境との乖離をふせぎたい。でも、Luaを組み込むとか非公式にやってるひとがいる。でも、大きくなりすぎだって)
 スタイルシートによるfancy menu
 Emacs-likeなmenu editor


#実はGRUB2の設計はRubyの思想に影響を受けている。
Rubyの処理系をブートローダにいれたらどうかなー。サブセットで300Kbyteくらい?



・まとめ
 ブートローダって、とっても大事
 ブートローダって、どっても面倒(協力して。わざわざブートローダつくるのはやめよぅ)

 GRUB2使って!

 「GRUB2は、世界を支配します」





・質問コーナー
どうやってデバッグするのか?
ブートローダの作り方」 http://enbug.tdialy.net/20060716.html#p03
「How To Debug」http://grub.enbug.org/HowToDebug

症状を人に説明できるように把握することからはじめる
ダメになる場所をbinary serchで決定する(二分探査で絞り込もう)
grub-emu , qemuなどのエミュレーターを使う
機種依存の問題は実機でテストする(netbootが使えると便利、CD-ROM依存の問題は大変)


SSDはBIOSレベルでは普通のディスクに見えるからかわらない・・・はず


EFIになったらレガシーな問題から開放されるのでは?
→アップルみたいに規格外なことをやって仕様を公開しないメーカーがある
→DRM,TPMまわりでモジュールが暗号化されると、フリーソフトがサポートできるかという心配
ファームウェアファイルシステムが認識できるので、検出は楽(ただし、それ以外のファイルシステムはサポートできない)



発表のあとはピザタイム〜
バイナリハック的な話もできた




今日は楽しかったなー。みなさんお疲れ様でした。