Slide 1

Slide 1 text

64bit UEFIからxv6を起動してみた YⅠ OS開発ゼミ フルスクラッチOS @PiBVT

Slide 2

Slide 2 text

xv6とは? UNIX V6をMITがx86向けに再実装したもの コンパクト(約1万行) x86で BIOSから起動できる マルチコア対応などの改良有

Slide 3

Slide 3 text

なぜUEFI? BIOSは2020年までに互換機能が削除される →2020年以降もxv6を実機で動かしたい。 →xv6を64bit UEFIから起動できた人はいない(当社調べ) →何か楽しそう

Slide 4

Slide 4 text

起動するまでの壁 1.64bitのプロセッサで32bitのバイナリを実行する →32bitバイナリのOSを実行するためにCPUのモードを変更する →バイナリの64bit対応は必要ないため、少しの変更で動かすことが出来る 2.BIOSに依存した部分をUEFI用に書き換える →CPUの情報を取得する部分がBIOS依存のため、UEFI対応にする

Slide 5

Slide 5 text

x86-64のCPUモード x86-64には大別して以下のモードがある。 ・Real mode (16bit) ・Protected mode (16/32bit) ・Long mode (64bit) UEFI起動時にCPUはLong modeであるため、 Long mode → Protected mode の移行をして32bitカーネルを実行する。

Slide 6

Slide 6 text

CPUモードの変更 たった6ステップでモード変更が出来る! Intel® 64 and IA-32 Architectures Software Developer’s Manual V3より

Slide 7

Slide 7 text

が、なぜかpagingが有効化できない Legacy paged-protected modeでないといけない。 →ん? QEMUで確認するとPAEのフラグが立っている。 →PAEを無効化すると動いた。 仕様書はしっかりと読もう! (1週間以上溶かしました。)

Slide 8

Slide 8 text

モード移行後、カーネルの初期化関数が走り始める! が...

Slide 9

Slide 9 text

mpinit()がBIOS依存 mpinit()は各プロセッサのLAPICやIOAPIC等の情報を取得する関数 →BIOSが作成するMP Floating Pointer Structureを利用。 MP構造体はプロセッサの情報やAPIC関連の情報を持つ。 →UEFIにはそんなものない。 詰み?

Slide 10

Slide 10 text

UEFI用にmpinit_uefi()を実装しました。

Slide 11

Slide 11 text

UEFIにはMP構造体に相当するものとして MADT(Multiple APIC Description Table)がある。 UEFI側でMADTのアドレスを取得 →mpinit_uefi()内でMADTのアドレスからLAPICやIOAPICの情報を取得 →mpinit()のUEFI版移植完成。

Slide 12

Slide 12 text

壁を乗り越え、シェルが起動

Slide 13

Slide 13 text

UEFIからxv6が起動した ・IDEやディスプレイのドライバが動かないが、ほとんどの機能は動いた。 ・シリアルポート経由で表示できる。 ・lsやmkdir,echoなどのコマンドが動く。 今後の目標 ・フレームバッファを利用してディスプレイ上で表示できるようにしたい。 ・NICのデバドラとTCP/IPのプロトコルスタック作って通信したい。

Slide 14

Slide 14 text

経験してみて分かったこと ・既存のOSを改造することには、新しいものを作る場合とは違う難しさがある。 ・まずは、Intel SDMやUEFIの仕様書を読もう。話はそれから。 ・QEMU monitor等でレジスタ・メモリーの様子を観察すれば問題の原因をつかめる ・段階的に初期化関数が動くようになるのは快感 ・地獄のデバッグ作業を乗り越えシェルが起動したときの感動は言葉にできない 自作OSは楽しい!