『ゼロからのOS自作入門』を手を動かしながら読んだ際に書き残したX(旧Twitter)のPostです。デバッグ情報や参照した資料などの記録を含みます。
引用形式で表示するために、.twitter-tweet
を削除して埋め込んでいるPostがあります。
OSの仕組みにも興味がわいてきました。わたしもおいおいチャレンジしてみようかな。
— Masahiro Oono (@words_oono) May 1, 2022
『ゼロからのOS自作入門』の写経を終えて https://t.co/CbuCrLr6FD
プログラミング言語自作に取り組んでいて、OS自作にも興味がわいたというところ、わかる気がします。まだうまく言えないけれど、なんとなくつながっている気がするんだよなぁ。
— Masahiro Oono (@words_oono) May 1, 2022
言語自作入門のJITコンパイラ編に取り組んだときに調達した Intel NUC にちょうど Ubuntu 20.04.6 LTS が入っているのでこれを開発用にして、N5095 を積んだ Beelink MINI S を試験用にすることにしました。 #ゼロからのOS自作入門
— Masahiro Oono (@words_oono) June 21, 2023
※ この開発用マシンで動作確認をしたのは5章の内容までです
とりあえず環境構築を済ませて、いっぱい数値を打ち込んで、ハローワールドだけしておきました。#ゼロからのOS自作入門 pic.twitter.com/akL6lEKxam
— Masahiro Oono (@words_oono) June 21, 2023
まだ写経の要領がつかめないな。ま、じっくりやりましょう。
— Masahiro Oono (@words_oono) June 26, 2023
実機でマウスを動かせなかった悲しみを乗り越えた。#ゼロからのOS自作入門
— Masahiro Oono (@words_oono) June 28, 2023
※ 精神的には乗り越えましたが技術的には乗り越えられなかったので、6章以降はQEMUで動作確認をしながら読み進めることになります
disk.img を作る make_img スクリプトに混ぜ込んだバグだったのですぐ直ってよかったけど、ブートローダ専用のデータ領域からデータ構造を移動する変更をした直後に発生したバグだったのでちょっとドキッとした(笑)#ゼロからのOS自作入門 pic.twitter.com/38v7hxYr1r
— Masahiro Oono (@words_oono) July 1, 2023
「デスクトップ」と「マウスカーソル」に対応するレイヤにそれぞれを描画するところまで写経しました。こういう処理を書くのはたのしいですね。処理の高速化とちらつきの解消はまたこんど。#ゼロからのOS自作入門 pic.twitter.com/9gz6hSKnLW
— Masahiro Oono (@words_oono) July 3, 2023
あっ、InitializeLAPICTimer()を呼ぶのを忘れてた(笑)#ゼロからのOS自作入門
— Masahiro Oono (@words_oono) July 4, 2023
時間が溶けていく。
— Masahiro Oono (@words_oono) July 7, 2023
昨日10章まで写経して、ちょうど1/3読み終わったところ。目次を見る限り、ここから20章までの内容をどう実装するのかは特に興味を惹かれるところです。集中して写経していきます。#ゼロからのOS自作入門
— Masahiro Oono (@words_oono) July 8, 2023
ラジオでちらっと話が出てたけど、確かにOS自作入門は、目次をながめているときはアプリが出てくるまでの内容の方がOSっぽくておもしろそうな印象でした。でも権限まわりの理解のために前半をなんども読み直す必要があったからなのか、わたしはむしろアプリが出てきてからの方がおもしろくなりました。
— Masahiro Oono (@words_oono) August 29, 2023
※ 電子の森ラジオ018 生物として機械語を見る ゲスト 大神祐真さん 12:32あたり
※ 読了後に振り返ってみると、20章までに学んだ内容については21章以降の実装を進める過程で腹落ちした感じです
たのしそう、と思って読みはじめたけど、思った以上にたのしいですね。
— Masahiro Oono (@words_oono) July 9, 2023
おっ、「MikanOS に存在する既知のバグ」をまとめてくれている。#ゼロからのOS自作入門
— Masahiro Oono (@words_oono) July 12, 2023
osbook_day15b ~ osbook_day16f: osbook_day15b で実行後すぐにTaskBウィンドウが消える
osbook_day06b: ScanAllBus() で funcion=0 から探索すべき
https://t.co/WgEAtidF2J
観てる。#ゼロからのOS自作入門
— Masahiro Oono (@words_oono) July 13, 2023
第7回 タイマー/第8回 マルチタスク https://t.co/OI8BRhzOXV @YouTubeより
写経しながらじっくりマルチタスクのところを読んでいます。ここはとてもたのしいですね。#ゼロからのOS自作入門
— Masahiro Oono (@words_oono) July 15, 2023
観てる。#ゼロからのOS自作入門
— Masahiro Oono (@words_oono) July 15, 2023
第7回 タイマー/第8回 マルチタスク https://t.co/aSMkwIi7ql @YouTubeより
こ、これがぎっくり首ってやつか。動かせん(笑)
— Masahiro Oono (@words_oono) July 15, 2023
※ 首やっちゃいました。以降、サポーターを巻いて読むことになります
首が痛む割りに読めたので、よかったよかった。次は15章 ターミナルだー! #ゼロからのOS自作入門
— Masahiro Oono (@words_oono) July 17, 2023
痛みに耐えて写経したところの読み直しから今夜はやろう。タスクに優先順位を付けたりウィンドウをアクティブ化したりするしくみは、OS自作に限らずゲームAIを書く時などにも使えそうなのでしっかり理解しておきたい。
— Masahiro Oono (@words_oono) July 18, 2023
ちょうど16章の写経が終わりそうなタイミングで、輪読会の動画をアップしてくれていることに気づきました。https://t.co/4doAntmrPe #ゼロからのOS自作入門
— Masahiro Oono (@words_oono) July 20, 2023
ターミナルでいくつかのコマンドが実行できるようになりました! 次はたのしみにしていた17章 ファイルシステムに取り組みます。#ゼロからのOS自作入門 pic.twitter.com/eEgw87tjLO
— Masahiro Oono (@words_oono) July 21, 2023
なんか変だな、と思ったらコマンド履歴を実装するのを忘れていた。
— Masahiro Oono (@words_oono) July 22, 2023
観てる。#ゼロからのOS自作入門
— Masahiro Oono (@words_oono) July 24, 2023
第9回 ファイルシステム/第10回 アプリケーション https://t.co/RrSNvvQQZm @YouTubeより
今日からは19章 ページングを読んでいきます。実は、この章と20章 システムコールの内容はぜひ実装してみたかったんです。たのしみー! #ゼロからのOS自作入門
— Masahiro Oono (@words_oono) July 25, 2023
観てる。#ゼロからのOS自作入門
— Masahiro Oono (@words_oono) July 25, 2023
第11回 アドレス変換第/第12回 システムコール https://t.co/8cIWi8N7kG @YouTubeより
4階層ページングのアドレス変換のしくみおもしろいね。これってページテーブルを多段にすることでエントリ数を減らしてメモリの使用量の削減を狙ってるのかな。#ゼロからのOS自作入門
— Masahiro Oono (@words_oono) July 26, 2023
観てる。#ゼロからのOS自作入門
— Masahiro Oono (@words_oono) July 27, 2023
第11回 アドレス変換第/第12回 システムコール https://t.co/4RI2qVFa1S @YouTubeより
観てる。#ゼロからのOS自作入門
— Masahiro Oono (@words_oono) July 27, 2023
第11回 アドレス変換第/第12回 システムコール https://t.co/d80nj39aFD @YouTubeより
20章は思ったよりむずかしいな。#ゼロからのOS自作入門
— Masahiro Oono (@words_oono) July 28, 2023
※ 第20章 システムコール
書籍とあわせて東工大の講義動画を観て写経していたら、じわじわと分かってきました。#ゼロからのOS自作入門
— Masahiro Oono (@words_oono) July 28, 2023
セグメントディスクリプタやCSレジスタ、ページング構造のエントリなどが関係し合いながらCPUの動作権限を切り替える処理を書くので混乱しないように、これって何だったかなー、とひとつひとつ確認しながら読み進めてる。#ゼロからのOS自作入門
— Masahiro Oono (@words_oono) July 29, 2023
8章でさらっと流したところをしっかり理解していく感じ。
— Masahiro Oono (@words_oono) July 29, 2023
“ここで重要なのは、 どんなコードでも継続渡し形式として「見る」ことができる、という事実である。 C言語などクロージャを持たない言語では、[…] 例えばある時点でのスタックとマシンレジスタの状態を継続とみなせば、 概念的には継続渡し形式としてコードを解釈することが可能だ。” https://t.co/ge0ZqcwSp6
— Masahiro Oono (@words_oono) July 29, 2023
OS自作でコンテキストを切り替えるコードを読んでいると、なんとなく継続を連想する。ま、よく分かっていないんだけどね。
— Masahiro Oono (@words_oono) July 29, 2023
観てる。#ゼロからのOS自作入門
— Masahiro Oono (@words_oono) July 30, 2023
第11回 アドレス変換第/第12回 システムコール https://t.co/iW2TL4by9p @YouTubeより
おっ、講義動画はこれで終わりなんだね。
— Masahiro Oono (@words_oono) July 30, 2023
これまで読んできた章の理解がふわっふわしてるから、21章の最初のところの説明でさっそく混乱してしまった(笑)#ゼロからのOS自作入門
— Masahiro Oono (@words_oono) July 30, 2023
ふわっふわしたところを補足して読み返した。
— Masahiro Oono (@words_oono) July 30, 2023
CPL=3 のときに割り込みが発生して CPL=0 に切り替わるとき、CPU の仕様で TSS.RSP0 の値が RSP に設定されるが、アプリがシステムコールを実行中に割り込みが発生したときは CPU=0 なので RSP はアプリ用のスタックを指したまま変わらない。
アプリ用領域のマッピングは各コンテキストで固有だから、割り込みが発生して RestoreContext() が呼ばれコンテキストが切り替えが発生すると、PML4table を指す CR3 が更新されてアプリ用スタックが載っているページング構造のエントリの present フラグが0になる。
— Masahiro Oono (@words_oono) July 30, 2023
present フラグが0のときは有効な物理アドレスが設定されていないことを意味し、この状態で iret 命令を実行してスタックへのアクセスが発生すると、CPU がページフォルトを発生させてOSがクラッシュする。
— Masahiro Oono (@words_oono) July 30, 2023
21章の「IST を設定しよう (osbook_day21a)」の写経は、アプリを複数起動できるように改造したあとに回すことにしました。とりあえず進みます。#ゼロからのOS自作入門
— Masahiro Oono (@words_oono) August 2, 2023
CPLに注意しながら読むと、何やってるか意味が分かってくるなー。
— Masahiro Oono (@words_oono) August 4, 2023
おお、やっぱり。コードが読み解けている気がしてうれしい。
— Masahiro Oono (@words_oono) August 6, 2023
"ここで[…]「21.1 ISTを設定しよう」で説明したのと同様の問題が起きるのです[…]紙面の都合でこのバグをここで紹介、修正しますが、実はこのバグが顕在化するのは「24.3 複数アプリの同時起動」の時点" #ゼロからのOS自作入門(p.532)
この書き方なんか見たことある気がするなぁ、と思ったら、まあまあ言語自作入門テキストで似た感じのコードを書いていたりしてね、そういう繋がりを見つけるのもたのしみのひとつ。
— Masahiro Oono (@words_oono) August 6, 2023
※ 「言語自作入門テキスト」とは、「10日くらいでできる!プログラミング言語自作入門」のことです
目次をながめたときに24章以降は難しそうと思ったんだけど、やっぱり「ちょっと」難しくなるみたいだ(ごくり… "次章からはまたちょっと難しい内容になると思うので、今のうちに楽しんでしまいましょう。" #ゼロからのOS自作入門
— Masahiro Oono (@words_oono) August 7, 2023
「24.3 複数アプリの同時起動」の改造をして syscall::ReadEvent() を呼ぶアプリを実行すると、OSがクラッシュすることを確認。これは無効なページを参照してしまうために発生する想定内の挙動で、システムコール実行時にスタックを入れ替える修正をすると解消した。#ゼロからのOS自作入門
— Masahiro Oono (@words_oono) August 8, 2023
「システムコール実行時にスタックを入れ替える修正」というのは、asmfunc.asm > SyscallEntry にて syscall_table に登録された関数を実行する前に追加する14行のこと(osbook_day22g)。
— Masahiro Oono (@words_oono) August 8, 2023
後回しにしていた IST の設定(osbook_day21a)も済ませた。
— Masahiro Oono (@words_oono) August 8, 2023
そういえばgrepコマンドを追加する直前のb5cc526aで、Makefile.elfappのCPPFLAGSに-Dオプションを追加して定義している「__SCLE」は何なんだろう? 外してもいちおうgrepコマンドは動いているみたいだけど。#ゼロからのOS自作入門
— Masahiro Oono (@words_oono) August 9, 2023
おかしい、どんどんOSがバギーになってきてる(笑)
— Masahiro Oono (@words_oono) August 13, 2023
26.5「ファイル書き込み(1)」の内容をコードに反映するとターミナルで「apps/cp memmap abc」を実行した際に、write()をまだ実装していないためにcpコマンド全体は失敗するが、fopen()は成功してABCという空のファイルが生成されるはずなのだが生成できなかった。#ゼロからのOS自作入門
— Masahiro Oono (@words_oono) August 14, 2023
上の問題は、fat::CreateFile()でエントリのDIR_AttrフィールドにATTR_ARCHIVEフラグを設定すると解消した。#ゼロからのOS自作入門
— Masahiro Oono (@words_oono) August 14, 2023
auto dir = fat::AllocateEntry(parent_dir_cluster);
...
dir->attr = fat::Attribute::kArchive;
参考: https://t.co/DAmd9oCYDY
26.6「ファイル書き込み(2)」の内容をコードに反映するとcpコマンドが成功するはずなのだがページフォルトが発生するようになってしまった。どこかで写経ミスったかも、めんどくさそうなバグを引いてしまった。#ゼロからのOS自作入門
— Masahiro Oono (@words_oono) August 14, 2023
※ 後日、検証するために当該問題が発生したコミットまで戻り再現を試みましたがページフォルトは発生しませんでした(なぜだ…
しかし、うまいことに次章(27章)でデマンドページングを実装することに気付き、原因が気になったものの一旦バグを残して先に進むことにした。直ってくれー! と祈りながら27.1「デマンドページング」を写経するとcpコマンドが成功するようになった。ほっ。#ゼロからのOS自作入門
— Masahiro Oono (@words_oono) August 14, 2023
RustとWebAssemblyによるゲーム開発が届いていた。しかし、ゼロからのOS自作入門を読了 or 挫折するまでは他の技術書を読むことを禁止しているので、そろりそろりとページをめくって構文の面構えをたのしむだけにとどめている。ううむ、読みたい…。
— Masahiro Oono (@words_oono) August 15, 2023
図がとても分かりすくて助かります。#ゼロからのOS自作入門
— Masahiro Oono (@words_oono) August 16, 2023
※「分かりすくて」->「分かりやすくて」
数日前から目の前のパソコン、OSに対して不思議な親しみを感じはじめています。なんだろうこれ。
— Masahiro Oono (@words_oono) August 17, 2023
※ なんだろう
システムコールまわりが初見ではよく分からなくて、いちどマルチタスクまで戻ってしっかり読み直したけど、こんどはメモリマップトファイルとコピーオンライトのところでコードを読むのが辛くなったので、ファイルシステムやFATまで戻ってもういちど読み直した。#ゼロからのOS自作入門
— Masahiro Oono (@words_oono) August 18, 2023
Terminal::Print()とcatコマンドをUTF-8に対応させるところまで写経しました。日本語表示、いいねーー。#ゼロからのOS自作入門 pic.twitter.com/m0l62TBYEf
— Masahiro Oono (@words_oono) August 19, 2023
ほほう…。 pic.twitter.com/eDAWkHGoqI
— Masahiro Oono (@words_oono) August 19, 2023
このあと、qemu-system-x86_64コマンドを実行しても画像の状態から先に進まなくなった。QEMUモニタで確認してみるとRIP=000000007fba53b4で止まっているようだ。さらにRIPが指す命令列を突き合わせてみるとLoader.efiには存在せず、ブートローダの起動より前に止まってしまっていることが分かった。 pic.twitter.com/liPYTAE9XQ
— Masahiro Oono (@words_oono) August 20, 2023
どうもファームウェアが壊れたっぽい。OVMF_CODE.fdは$HOME/osbook/devenvに置いてあるので、mikanos-buildリポトリをクローンし直してみた。するとqemu-system-x86_64コマンドで正常に起動するようになった。このあたりのことは、まだ慣れない。#ゼロからのOS自作入門
— Masahiro Oono (@words_oono) August 20, 2023
※「mikanos-buildリポトリ」->「mikanos-buildリポジトリ」
※ https://github.com/uchan-nos/mikanos-build
PF祭り開催中
— Masahiro Oono (@words_oono) August 20, 2023
よーし、リダイレクト成功した! PF祭りを抜けた!
— Masahiro Oono (@words_oono) August 20, 2023
28.3「リダイレクト」の内容をコードに反映した後、ターミナルにて「echo deadbeef > piyo」を実行した際、ページフォルトが発生するようになった。調査したところapps/cpを実行した歳もページフォルトが発生するようになっていた。ファイル生成まわりの処理があやしい。#ゼロからのOS自作入門
— Masahiro Oono (@words_oono) August 21, 2023
※「実行した歳も」->「実行した際も」
コミットをたどって検証したところ、27.2「メモリマップトファイル」の内容をコードに反映した段階で「apps/cp memmap abc」の実行によりページフォルトが発生することを確認した。
— Masahiro Oono (@words_oono) August 21, 2023
上の問題は、fat::CreateFile()でエントリのDIR_FstClusHIとDIR_FstClusLOフィールドに0をセットすると解消した。#ゼロからのOS自作入門
— Masahiro Oono (@words_oono) August 21, 2023
auto dir = fat::AllocateEntry(parent_dir_cluster);
...
dir->first_cluster_high = 0;
dir->first_cluster_low = 0;
参考: https://t.co/DAmd9oCYDY
— Masahiro Oono (@words_oono) August 21, 2023
※ 当該問題の対策とあわせて26.5「ファイル書き込み(1)」の「ABCという空のファイルが生成されるはずなのだが生成できなかった」問題の対策をしたコードです
ついに最終章。テキストビューアと画像ビューアを実装するところまで写経しました。ほんとうに終わりまでおもしろかった。#ゼロからのOS自作入門 pic.twitter.com/w31q3XLXtb
— Masahiro Oono (@words_oono) August 23, 2023
読了。ゼロからのOS自作入門 | マイナビブックス https://t.co/NSaeYzIEbz
— Masahiro Oono (@words_oono) August 23, 2023