ハラミTech

技術系ブログです

OS自作入門してみた&やりきった

最近自分にはコンピュータ・サイエンス(CS)に関しての基礎知識があまりないなぁと感じていました。
ここでいうCSとはどういうものなのかというと

挙げればいっぱいありますけど、ざっくり「低レイヤー」と呼ばれている部分に関してです。

現在様々な書籍を読んで勉強をしている最中です。
どんな書籍を読んで勉強しているかはまた別の記事で書くとして、
今回は「30日でできる! OS自作入門」という書籍を読んで実際にOSを作ってみたので、その報告記事です。
いやー、長かった・・・

30日でできる! OS自作入門

30日でできる! OS自作入門

書籍の概要・学べること

「HariboteOS」というOSをBIOSから作っていきながら、OSの仕組みを学べます。

などが実際に作りながら学べます。

こんな感じで動くOSが作れます。

3日目(画面が描画された)
f:id:mori_morix:20190721113223p:plain

10日目(マウス制御ができた)
f:id:mori_morix:20190721113334g:plain

29日目(ゲームが動いた)
f:id:mori_morix:20190721113513g:plain

30日目(完成!)
f:id:mori_morix:20190721113647p:plain

実施した自分の環境

この環境でやり遂げたソースを載せておきます。

GitHub - morix1500/zisakuos

かかった時間

「30日でできる!」と書いてあるので実際にかかった期間も載せておきます。

僕は1日2〜3時間やって、ちょうど30日でおわりました。
2日ほど作業できない日があったので期間的には32日間かかりました。

活動時間は以下のようになっていて、
仕事が終わって帰るのが18〜19時くらいなのでそのへんのコミットが多くなってます。

これはなにかというと、Gitリポジトリから活動時間帯(コミットした時間)を抽出できるものです。
詳しくは下記参照

At what time of day do famous programmers work?

$ git log --author="morix1500" --date=iso | perl -nalE 'if (/^Date:\s+[\d-]{10}\s(\d{2})/) { say $1+0 }' | sort | uniq -c|perl -MList::Util=max -nalE '$h{$F[1]} = $F[0]; }{ $m = max values %h; foreach (0..23) { $h{$_} = 0 if not exists $h{$_} } foreach (sort {$a <=> $b } keys %h) { say sprintf "%02d - %4d %s", $_, $h{$_}, "*"x ($h{$_} / $m * 50); }'
00 -    2 **
01 -    1 *
02 -    0 
03 -    0 
04 -    0 
05 -    0 
06 -    0 
07 -    0 
08 -   10 *************
09 -   19 **************************
10 -    9 ************
11 -    5 ******
12 -    0 
13 -    1 *
14 -    2 **
15 -    0 
16 -    4 *****
17 -   10 *************
18 -   14 *******************
19 -   22 ******************************
20 -   36 **************************************************
21 -   31 *******************************************
22 -   19 **************************
23 -    9 ************

感想

そもそもディスプレイにどうやって画面を描画しているんだろうとか、マウスはどうやって動かすとか
ぼんやりとは理解していたものが、はっきり実装のイメージがつきました。
意外に愚直にやってるんだなぁというのが正直な感想で、あまり難しくないのだなと苦手意識がなくなった気がします。

あとC言語でもプログラムを書くんですが、アセンブリを書く機会がめちゃくちゃ多いです。
CPUレジスタのことをわからないと当然かけないので、そのへんから丁寧に教えてくれます。
丁寧と行っても全部説明してくれるわけでもなく、「なんでここでこのレジスタ使うんだろ?」っていう疑問が結構ありました。
そのへんの知識は、同時に読んでいた「プログラムはなぜ動くのか」という本でもアセンブリを扱っており、知識を補完することが出来ました。

「概念としては理解してるけど実装はちょっと・・・」という方にはぜひおすすめしたい書籍です。
自分もそんな感じだったんですが、いろんな部分がクリアになって自分に自信が持てました。

今後OSに追加したい機能

ファイルシステムの実装やデバイスドライバの実装をやっていきたいのと、
ウィンドウサイズを可変にしたいですねぇ・・・

あとはRustで書き直したいです。

やれるかな・・・?

詰まったところ

この書籍はWindowsで行うことを前提にしています。
残念ながら自宅にWindows環境がないのでUbuntuでやりました。

やはりそれだとスムーズに行かなかったので、詰まったところを書いておきます。

必要なツールのインストール

以下のコマンドでインストールします。
バイナリエディタのbedは、vimライクでエディタを操作できるので非常にコーディングが楽でした。

# バイナリエディタ
$ go get -u github.com/itchyny/bed/cmd/bed
$ bed helloos.img

# QEMU
$ sudo apt install qemu

この書籍では、著者が作った独自ツールを多用していきます。
それは当然Windowsにしか対応していないので、Linuxを使っている場合は使えません。

サポートページにはLinux版を配布していますが、
Makefile以外は流用するとエラーになったり、ツールが足りなかったりします。

ちなみに29日目の圧縮機能実装をするまでは上記のものでも問題なくできます。
しかし圧縮機能実装時に必要なツールが含まれていないため実装できません。

また以下のようなエラーが日本語機能実装時に出てしまい、先に進めなくなりました。

../../../z_tools/gas2nask -a tek.gas tek.nas
skip:shrdl      $16, %edx, %eax
gmake[1]: *** [tek.nas] Error 1

以下にlinuxでも動くツールキットを用意してあるリポジトリがあったのでそれを使ったところ、
圧縮に必要なツールや上記のgas2naskの不具合?が解消され、無事30日目までやり遂げることができました!!
ほんと感謝しかないです・・・

GitHub - HariboteOS/z_tools_linux

あとはQEMUのバグなのか知りませんが、「13 タイマ2」の章がどうやっても動きませんでした。
その場合、qemuの実行時にkvmオプションをつけたところ、解消しました。

$ sudo apt install -y qemu-kvm libvirt0 libvirt-bin virt-manager libguestfs-tools
 
# Makefileの修正(qemu実行部分を置換)
$ sudo qemu-system-i386 -m 32 -fda haribote.img -enable-kvm