この記事は、自作OS Advent Calendar 2016の一部として作成されました。
みなさんは「はりぼてOS」をご存知ですか?
はりぼてOSは、川合秀実氏著の「30日でできる!OS自作入門」という本の中でつくりあげられるOSです。 名前の通り、非常に「はりぼて」な完成度となっておりますが、それでもブートローダーを含めフルスクラッチで開発されており、またKさん(川合秀実氏のこと)らしく、フロッピーディスク1枚に余裕で収まるサイズを実現しており、OS自作の基礎を学ぶには最適です。
…なんてことは、自作OSアドベントカレンダーをご覧になっている皆様にとっては常識でしょう(笑)。まさにこの本は、自作OS界における「聖書」と言っても過言ではありません(本の厚さ的にも)。
まず、この本が前提としている開発環境は、なんとWindowsなのです。まあ確かに入門者向けなのでWindows用となっているのはわからなくもないですが、開発環境がWindowsに制限されているなんて、OS自作らしくないですよね。
ということで、他のOSで開発するにはどうすればいいだろうか、と思って調べてみると、サポートページにはあっけなくLinuxとMac向けの開発環境セットへのリンクが書かれていました。
「なあんだ、hikaliumがやるまでもないじゃん。解散!」 と思ったあなた方。解散するのはまだ早いですよ!
すでにパッケージは存在していましたが、それらは完璧ではありませんでした。
これは面倒です!だって、コンパイルするOSごとに、Makefileの書き換えが必要になるんですよね?いったいいくつMakefileがあると思っているのですか!?
それに、改造したはりぼてOSをGitHubで公開した際などに、コンパイルしたい人の開発環境にあわせてMakefileを書き換えなければいけないなんて…ちょっと面倒ですよね。
make run
やmake install
ができないmake runではqemuを使用します。しかし、Windows版以外の開発環境にはqemuが含まれていないため、「手動で頑張ってね!」という一言が書かれています。これは悲しいです。全環境でmake run
としたら起動してほしいです。
make install
についても同様です。というか、今時フロッピードライブなんてPCについてないですよね!どうしたものでしょうか…。
既存の開発パッケージは、先人たちが各自の知識を振り絞って作成したものでした。そのため、コンパイラのコンパイル時に当てるパッチなどは各自異なっており、共通のソースに基づいたものではありませんでした。
今回、諸事情により「バイナリレベルで完全に一致するharibote.sysを生成したい」という目標があったので、これを達成するために、開発パッケージをソースコードからまとめ直す必要がありました。
ということで、私は開発環境をソースコードからコンパイルする必要性に駆られ、まずtolsrc(tolsetのソース)を手に入れることにしました。 このtolsrcは、本に付属しているCDにも入っているのですが、今回はすでにMacでコンパイルできると書かれていた、Akkieさんによるソースパッケージを利用させていただきました。
しかし、なんとAkkieさんが作成したtolsrcをmakeしても、コンパイルエラーが出てしまい、gocc1(本家tolsetにおけるcc1)等のコンパイルに失敗してしまいました。 これは、配布されているtolsrcのソース(というか主にgccのソース)があまりにも古く、最新のC言語の規格に一致しない部分や、ビット幅依存の部分が存在したためです。
そのエラーは、主に以下の4点が原因となっていました。
int main(int argc, char *argv[])
と定義すべきint main(int argc, UCHAR *argv[])
となっていた__builtin_stdarg_start
がリンクできない__builtin_stdarg_start
だった__builtin_va_start
である。-m32
をつけることで解決。-m32
が反映されない問題に数十分費やしてしまった。さて、ここまででほとんどの実行バイナリは用意できました。 しかし、もう一つ大きな問題が残っています。それは、開発環境ごとのコマンドの違いです。
copy
cp
copy /b file1+file2 dstFile
(2016-12-07追記)記事の公開後に川合さんから「Windowsのコピーコマンドで結合という意味になるのは、+でつないでいるからであって/bというオプションのおかげではないですよ!」とのご指摘を受けましたので、修正しました。ご指摘ありがとうございます!
ちなみに、`/b`は「バイナリモードで(改行コードを変換せず)処理してね」ということのようです。
cat
del
rm
これらをどうやって共通にするか。
その解決策として私が選んだのは、「専用のプログラムをつくる」ということでした。
その名も、haritol
です。
haritol concat
haritol remove
引数によって、動作を変えます。 さらに、Windowsでは、一般のプログラムに渡す引数ではワイルドカードが機能しないという問題がありました。これは、Makefile内臓のワイルドカード機能を用いて解決しました。
もちろん、Makefileの書き換えは必要でしたが、それでも一度書き換えてしまえば、すべての開発環境で同様にコンパイルすることが可能なはりぼてOSソースコードを用意することができました。
この成果は、以下のgithubで公開しています。
「書き換え済みharib27f」と、各環境にあわせた「z_tools」をダウンロードして、z_toolsはz_tools
に名前を変更すれば、あとはharib27f/
に移動し、make run
するだけです!簡単でしょ?
この成果は、tolsetの移植にかかわった偉大なる先人方、特にAkkie氏、わこう氏、hideyosi氏の成果に基づいています。 また、uchan氏には、go_0023sのコンパイルエラーが発生した際に助けていただきました。
そしてなにより、「30日でできる!OS自作入門」の著者であり、私が現在サイボウズ・ラボユースでお世話になっているKさん(川合秀実氏)には、感謝してもしきれません。というかこのネタ自体が、Kさんからお願いされたお仕事に基づいています。
最後に、はりぼてOSと自作OS界で活動されているすべての皆様に、感謝申し上げます。