今回は、もはや何番煎じかわかりませんが、名著『30日でできる! OS自作入門』にチャレンジして学んだことのまとめです。
なぜOSの自作に挑戦しようかと思ったかというと、低レイヤの技術をもっと学びたいと思ったからです。
先日、CTFに初めてチャレンジした際、バイナリ解析を行いましたが、残念ながらバイナリについてはあまり理解ができませんでした。
CTF未経験の僕が30分でバイナリ解析を学び、練習問題を解いた話【備忘録】
そこで『基礎から勉強しなければ』と思った時、この記事を思い出したのです。
僕の敬愛するちょまどこと、千代田まどかさんの記事です。
寝食削ってその世界にハマった。ちょまどさんが語る、プログラミングへの尽きせぬ「愛」とは
ちょまどさんはMicrosoft社のクラウド・デベロッパー・アドボケイトとして活動されているのですが、彼女がプログラミングを学び始めたころ、Twitter民にこんなアドバイスをされたそうです。
「基礎から学びたいなら、OSを自作するといいよ」
その『基礎』じゃねーよ、とツッコミを入れたくなるようなアドバイスですが、確かにこれは的を射ています。
このアドバイスを思い出したことで、僕はバイナリなど低レイヤの技術についてより理解すべく、OSの自作を志したのです。
というわけで、本記事ではこちらの書籍のDay1の内容について主にまとめていきます。
[kattene]
{
“image”: “https://images-na.ssl-images-amazon.com/images/I/41Q4Q20S5PL._SX387_BO1,204,203,200_.jpg”,
“title”: “30日でできる! OS自作入門”,
“description”: “プログラミングの基礎からはじめて、30日後にはウィンドウシステムを有する32bitマルチタスクOSをフルスクラッチで作り上げるという入門書。”,
“sites”: [
{
“color”: “orange”,
“url”: “https://www.amazon.co.jp/30%E6%97%A5%E3%81%A7%E3%81%A7%E3%81%8D%E3%82%8B-OS%E8%87%AA%E4%BD%9C%E5%85%A5%E9%96%80-%E5%B7%9D%E5%90%88-%E7%A7%80%E5%AE%9F/dp/4839919844/ref=as_li_ss_tl?_encoding=UTF8&qid=1575642351&sr=8-2&linkCode=ll1&tag=kashiwabayu0c-22&linkId=fc8dfb704a10dfe436cd0533824cb38f&language=ja_JP”,
“label”: “Amazon”,
“main”: “true”
},
{
“color”: “red”,
“url”: “https://hb.afl.rakuten.co.jp/hgc/19ccb99f.0160a535.19ccb9a0.c987af9a/?pc=https%3A%2F%2Fitem.rakuten.co.jp%2Frakutenkobo-ebooks%2Fa3d23a47c1613f27839e17de2a9fddcd%2F&m=http%3A%2F%2Fm.rakuten.co.jp%2Frakutenkobo-ebooks%2Fi%2F13185995%2F&link_type=hybrid_url&ut=eyJwYWdlIjoiaXRlbSIsInR5cGUiOiJoeWJyaWRfdXJsIiwic2l6ZSI6IjI0MHgyNDAiLCJuYW0iOjEsIm5hbXAiOiJyaWdodCIsImNvbSI6MSwiY29tcCI6ImRvd24iLCJwcmljZSI6MSwiYm9yIjoxLCJjb2wiOjEsImJidG4iOjEsInByb2QiOjB9”,
“label”: “楽天”
}
]
}
[/kattene]
もくじ
1日目のゴール
今回のゴールは、機械語のファイルを作成して、OSの機能を使わずに”Hello, World”を出力させることです。

こちらが今回の成果物です。
VirtualBox上の仮想マシンとして動かしています。
OSの機能を使わない出力
ところで、OSの機能を使わずに”Hello, World”を出力させるとはどういうことでしょうか。
様々なプログラミング言語の入門書では、最初の一歩として”Hello, World”という文字列を出力させるプログラムを組むことがほとんどです。
例えばPythonであれば、print(“Hello,World”)といった具合です。
上記のようにプログラムで文字列を出力する場合、内部ではOSがプログラミング言語を実行させ、そのプログラミング言語が、OSの持つ出力機能を利用して文字列を出力しています。
つまり、このコードはOSがインストールされていないコンピュータでは実行すらできないのです。
では、OSなしでコンピュータに文字列を出力するよう命令するにはどうしたらよいのか。
答えは『機械語を使う』ことです。
機械語とは、0か1の数字の羅列で表現された、コンピュータにだけ理解できる言葉のことです。
今回は、この機械語を直接手入力してプログラムを作成することによって、OSの機能を利用しなくても文字列を出力できるようにしています。
バイナリファイルを作成しよう
実際に今回作成したバイナリはこちらです。
***の部分は、前後の行と全く同じなので省略してます。
実際は9万行以上のファイルになりました…。
驚きです。
Offset: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 00000000: EB 4E 90 48 45 4C 4C 4F 49 50 4C 00 02 01 01 00 kN.HELLOIPL..... 00000010: 02 E0 00 40 0B F0 09 00 12 00 02 00 00 00 00 00 .`.@.p.......... 00000020: 40 0B 00 00 00 00 29 FF FF FF FF 48 45 4C 4C 4F @.....)....HELLO 00000030: 2D 4F 53 20 20 20 46 41 54 31 32 20 20 20 00 00 -OS...FAT12..... 00000040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000050: B8 00 00 8E D0 BC 00 7C 8E D8 8E C0 BE 74 7C 8A 8...P<.|.X.@>t|. 00000060: 04 83 C6 01 3C 00 74 09 B4 0E BB 0F 00 CD 10 EB ..F.<.t.4.;..M.k 00000070: EE F4 EB FD 0A 0A 68 65 6C 6C 6F 2C 20 77 6F 72 ntk}..hello,.wor 00000080: 6C 64 0A 00 00 00 00 00 00 00 00 00 00 00 00 00 ld.............. 00000090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ *** 000001e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 000001f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 AA ..............U* 00000200: F0 FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 p............... 00000210: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ *** 000013f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00001400: F0 FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 p............... 00001410: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ *** 167ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
さて、このバイナリファイルですが、バイナリエディタで作成することができます。
バイナリファイルを編集できるバイナリエディタは様々な種類がありますが、今回はインストール不要で利用できるHexEd.it – Browser-based Online Hex Editingを利用しました。
とはいえ、いくらエディタがあっても、9万行すべてを手入力するのは無理があります。
そこで、まずはすべてが0のバイナリファイルをコマンドで生成しました。
下記のコマンドです。
fallocate -l 1474560 helloos.img
このコマンドで生成したファイルをHexEd.it – Browser-based Online Hex Editingで開き、必要な部分を手入力したらプログラムは完成です。
では、実際に動かしてみましょう。
VirtualBoxでイメージを実行する
いよいよ完成したイメージをコンピュータ上で動かしてみましょう。
30日でできる! OS自作入門では、フロッピーディスクに書き込んだイメージを実行するよう書かれていました。
ですが、現在手元にフロッピーの読み込みが可能なPCはおろか、フロッピーディスクすらありません。
そこで今回はVirtualBoxを代わりに用いることで、作成したOSを起動してみたいと思います。
VirtualBoxのインストール方法や細かい使い方については割愛します。
まず、新しいインスタンスを作成したら、OSのタイプを「Other」、バージョンを「Other/Unknown」に設定してください。
他の設定は初期設定のままで問題ありません。
インスタンスを作成したら、「ストレージ」のタブから、新しいフロッピーディスクイメージを作成し、先ほどのバイナリファイルを指定しましょう。
この際、「Could not get the storage format of the medium」というエラーが発生した場合は、イメージファイルが破損している可能性があります。
内容や行数が間違いないことを確認してください。
無事にセットアップが完了したら、あとは起動ボタンを押すだけで自作のOSが動いてくれます。
人生初の機械語プログラミング大成功です!
まとめ
今回は、OS自作の入門として、OSの機能を使わずに機械語で直接”Hello, World”を出力するプログラムを作成しました。
実際に手を動かしてみたことで、少しバイナリについての理解が深まったように感じます。
教材として使用している『30日でできる! OS自作入門』はまだ始まったばかりなので、これから頑張って進めていきたいと思います。
↓次の記事はこちら!
参考
CTF未経験の僕が30分でバイナリ解析を学び、練習問題を解いた話【備忘録】