「作りながら学ぶ OS カーネル」本について

もう 7 年ぐらい前の話になりますが、本屋で適当に技術書を眺めていたところ「作りながら学ぶ OS カーネル -保護モードプログラミングの基本と実践-」という本を見つけて衝動買いしました。

作りながら学ぶOSカーネル保護モードプログラミングの基本と実践 | Amazon
https://www.amazon.co.jp/%E4%BD%9C%E3%82%8A%E3%81%AA%E3%81%8C%E3%82%89%E5%AD%A6%E3%81%B6OS%E3%82%AB%E3%83%BC%E3%83%8D%E3%83%AB%E4%BF%9D%E8%AD%B7%E3%83%A2%E3%83%BC%E3%83%89%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%81%AE%E5%9F%BA%E6%9C%AC%E3%81%A8%E5%AE%9F%E8%B7%B5-%E9%87%91-%E5%87%A1%E5%B3%BB/dp/4798022543

タイトルにある通り、Intel x86 の保護モードで動くシンプルな OS カーネルをアセンブリで書いていく内容です。内容は素晴らしいのですが、致命的な欠点があります。以下のブログや Amazon のレビューでも悉く指摘されていますが、誤植の量が半端ないのです。誤植と言っても、本文の記述が間違っているだけでなく、肝心なカーネルのコードも間違っていて、そのままコピペしても動作しないレベルの間違いが複数ヶ所あります。

読書メモ/「作りながら学ぶOSカーネル - 保護モードプログラミングの基本と実践」 - Glamenv-Septzen.net
https://www.glamenv-septzen.net/view/1342

今読んでる本 - 『作りながら学ぶOSカーネル』
http://qune.jp/archive/001252/index.html

無差別に技術をついばむ鳥 書籍をつつく102-作りながら学ぶOSカーネル。題名どおりの名著♪
http://indori.blog32.fc2.com/blog-entry-748.html

本を買わずとも、以下のページからコードを無料でダウンロードすることができます。が、誤植を加味しても本を買う価値はあると思います。

作りながら学ぶOSカーネル 保護モードプログラミングの基本と実践|サポート|秀和システム
https://www.shuwasystem.co.jp/support/7980html/2254.html

著者が日本の方ではないので日本語と英語が微妙に拙いというのもありますが、これは許容範囲です。むしろ我々日本人が英語で書いた論文や記事に対して、英語のネイティブ スピーカーが抱くであろう感情を想起してくれる貴重な資料です。そもそも韓国語で書かれていたら全く読めないので、日本語で出版されたことはとても有難いですね。

ところで、上記ブログでも指摘があるように、本書と似たような趣旨の本に「30日でできる! OS自作入門」という本があります。この本は某ポッドキャストでも話題になりました。残念ながらこちらは読んだことがありません。Kindle 本になっているのですぐ買えるんですけど。高いし。

30日でできる! OS自作入門 | 川合 秀実 | 工学 | Kindleストア | Amazon
https://www.amazon.co.jp/dp/B00IR1HYI0/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1

なぜ数年ぶりにブログを更新するかといえば、最近ようやくこの本のコードを全て動かすことに成功したからです。この記事の主旨は本とコードの宣伝です。玄人志向ではありますが、カーネル開発のトラブルシューティングを余儀なくされるという点でとても画期的な本なので、初心者向きではないですが、ある程度アセンブリが分かってデバッグが好きな人にはとても刺さる内容だと思います。Amazon のレビューでは ★ 4 つにしました。

msmania/oskernel-practice: 作りながら学ぶ OS カーネル
https://github.com/msmania/oskernel-practice

動作環境

本書で作るカーネルは、Windows 上にインストールした Bochs という IA-32 エミュレーターで動かすことが想定されています。この構成は宗教的な理由であまり好きになれなかったので、最初は Windows で Bochs の代わりに Hyper-V を使って動かしていました。具体的には、フロッピーの代わりに仮想ハードディスクとなる VHD ファイルの MBR を書き換え、そこからカーネルが起動するようにしていました。

VHD には、Windows で動く dd.exe を使ってセクタ単位の Direct I/O で書き込んでいたのですが、一度ディスク構成が変わってディスク番号がずれ、別の外付け HDD のデータを飛ばすというありがちなミスをしました。そんなリスクはありますが、Windows + Hyper-V の力技で 8 章までは行けます。しかし最後の 9 章で躓きます。

9 章では、カーネルの一部を C 言語で書くことになり、コンパイラーとして GCC を使うことが想定されています。これも宗教的な理由ですが、Windows に GCC を入れるのは好きになれません。かといって Visual C++ のコンパイラー/リンカーの仕様には制限があり、出力形式は PE イメージに限定されています。OS カーネルを書くにはフラットな Raw イメージが必要なため、Visual C++ は使えません。というわけで、9 章のために Linux で GCC を使う手法に変えました。エミュレーターは本の通りに Bochs を使ってもいいのですが、QEMU の勉強も兼ねて QEMU を使うことにしました。QEMU についても某ポッドキャストで出てきましたね。好きな回です。

上記をふまえ、動作環境は以下の通りです。

  • OS: Ubuntu 18.04.2 LTS
  • Emulator: QEMU emulator version 2.11.1(Debian 1:2.11+dfsg-1ubuntu7.9)
  • C: gcc (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0
  • Assembler: NASM version 2.13.02

9 章「C 言語でカーネルを作る」のコードについて

一番苦労したのは、やはり最後の 9 章です。8 章までの間違いは printf デバッグみたいな原始的な手法で見つけて直せますが、9 章はデバッガーを使ってまともにデバッグしないとたぶん無理です。そういう意味で本書は、カーネルデバッグの実践機会まで提供してくれるのです。大半の人は諦めてしまいそうですが。

9 章の内容に関する問題は以下の通りです。本に書かれているのと全く同じバージョンの環境を用意すれば、幾つかは問題ないかもしれません。

  • 本に書かれているコマンドではカーネル イメージが正しくコンパイルできない
  • 本に書かれているコマンドではカーネル イメージが正しくリンクできない
  • 本に書かれたアセンブリのコードでは C 言語の関数が呼べない
  • カーネル イメージのセクター数が合わない

本書ではコマンドを普通に手打ちする流れですが、一発で make できるように Makefile を書きました。詳細はコードを見てもらうとして、実際に make run するとこんな風になります。


一応コードを動かすことには成功していますが、仮想フロッピーの特定のセクターからデータを読み込めないという謎の現象に遭遇したため、データのオフセットを適当に弄ってそのセクターを回避するという手段を取っています。これはいつか QEMU そのものをデバッグして原因を究明したいところです。

もう一点、フロッピーのデータを DMA で読み込むときに I/O ポート 0x08 に 0x14 と 0x10 を送信するのですが、QEMU では無効なコマンドらしくコンソールに以下のログが出力されます。

dma: command 14 not supported
dma: command 10 not supported

本書では、これは DMA を無効/有効化するスイッチというように書かれていますが、OSDev wiki によるとポート 0x08 は Status Register で、読み取り専用になっています。この本の謎は尽きません。

ISA DMA - OSDev Wiki
https://wiki.osdev.org/ISA_DMA