れもん(Twitter)が30日OS本やっていく。
date:2018/07/13 16:30-17:30
煩大のつまらない素晴らしい4限の講義も終わり、私の所属しているOUCCの部会まで暇なので、図書館に行ってみた。豊中キャンパスの総合図書館は、情報系の本がそこそこ揃っているので、我々JK1回生にとっては非常に重要な存在である[要出典]。
……おや?これはいわゆる30日OS本では?
ひたすらヤバい本(!!)であるとTwitterでしばしば話題になっているが、詳細はあまりよく知らない。でも読んでみたいこの一冊。まさかこれが入ってるとは、やっぱ図書館は有能だな。図書館は。大学上層部に爪の垢を煎じて 噴 霧 機 で 散 布 してやりたいものだ。とりあえず1時間ぐらい空いてるし始めてみようと思う。
これは序章らしきものである。前書きは作者の伝えたいことが書いてあるって、かのシェイクスピアも言ってたから。うんうん。知らんけど
読んだ感想。知識0からできるそうだが(本当に?)、とりあえずOS作りに必要な知識を拾っていきたい所存。最終的には悠里OSの方にまともな貢献をするための基礎知識が欲しい!(それよりも5000兆円欲しい!)
早速組んでいくわけだが、CDを犯大生協のLet's noteに入れようとしたらブオンブオンうるさい。仕方がなく代替ファイルが無いかggったら、こんな公式サイトがあったのね。必要最低限のファイルを取ってきた。
まずバイナリ組むらしい。わーいBZエディタたのしーい!
できた!
うごいた!
ここで、作者オリジナルのアセンブリを組むらしい。下図L.27~L.30の文字列のところはある程度自由にできるそうなのでいぢる。これが初オリジナル要素なんだなぁ。
なーんだ、簡単そうじゃん!(フラグかな?)
date:2018/07/14 1:00-1:30
これを読んでいくうえでどうしても付属のCD-ROMに入っているデータが欲しかったので、夜中にLet's noteの五月蝿いドライブをぶんぶん回して全部コピペしてきた。私が低周波公害である。
date:10:00-10:30
読了!アセンブリをもう少しやる感じだけど、普通に理解。しっかし、x86ってレジスタ多いねぇ(2003fが少ないだけでこれが普通である)。それと、Makefile便利ねぇ。
まとまった時間が取れなかったが、進めれてる。多分
date:2018/07/15 07:15-08:30
昨日はRPG研でキャンペーンのセッションやってたのです。楽しかった。けど疲れたので昼まで休んで、レポート書いて、今からOS本。
はい、出た、旧時代の利器フロッピー。この本10年以上前のものなので出てくるんですが、今はもはやHDDを超えてSSDなので、正味そこだけ聞き流してブートセクタの説明だけ見解けば大丈夫かな。結構今でもなお続いてる仕様多そうだし。
…と思ったんだけどさぁ、フロッピーの話大杉。シリンダとかはHDDまでなら十分使える話だけど、ねぇ。メモリ256Gの時代やでまぁいいか。続けよう。
date:23:00-24:00
ついついDoki Doki Literature Clubの実況みてて気がそれてしまった…ヤバいよねあれ。
さて、OSの方はと言うと、ブートは終わってOS本体。やったぜ。さてさて、本体は「なんとか.sys」らしい。こいつを読み込んで実行するのがIPLの役目なのであったわけだな。本体に色々書いていくわけだけども、まずは試しに黒い画面を表示しようということらしい。ほむ。
わーい!動いた動いた!よし、OS完成!(違うんだよなぁ…)さて、これからは超高級アセンブリ言語を用いて開発するらしい。いよいよ本番だね。
――――読み込み中――――
…っあ゙~~!!goto!!やっぱりCは超高級アセンブリ言語だぜ!!超高級アセンブリ言語のすることは違うなぁ!!…はい、まじめにやります。Cのコンパイルには何段階かあるようで、アセンブリにして―、いぢくってー、機械語にして―。それを筆者は全てMakefileにしてくれてるわけである。うーん、有能。今日はこれで終わりかな。
ほむ。Cからメモリに書き込みたい?ほならね、ポインタ使えって話でしょ?げっ、作者はこんなひねくれ読者にも対応していらっしゃる。
> メモリに書き込む命令がない:うそだ、あるじゃないか! と思ったあなたは、この本の対象読者としては、かなり物知りである。
見事に著者から はいプロ 世界一C言語が上手 プログラム界のtourist アセンブリ時代の終焉を告げるもの 実質コンパイラ C言語完全に理解するために生まれてきた男と煽られたので次行こう。
VRAMに数値を書き込んでいくようで、非常に楽しそうなことしていらっしゃる。どれ、一つ何か書いてみよう。
斜めの縞々を書いてみた。オリジナリティは大事。多分。
date:2018/07/16 00:00-01:30
日をまたいだのでタイトル。さて、やはりポインタを導入するようだが、本書ではint iと宣言しておいて*iと使ってエラーが出てる。当然である。よいこのみんなは変数宣言時にポインタを宣言しようね!で、ポインタの話はすっ飛ばして、色の話。色は当然RGBで設定されていて、16色パレットがあるわけである。その色を自分で設定しようって話らしい。つーことで設定した後がこちら。
さっきよりやや毒々しさが抜けたいつもの色って感じがする(本当に?)そんで、いろいろ頑張った結果が以下のようらしい。
日をまたいじゃったけど。ディスプレイに表示できるようになって、いよいよ本格的にスタートって感じがする。うん。
date:08:00-11:00
寝て起きて寝るのが杏の生きざまなので二度寝しま(させない。さて、やっていこう。今日の話はまず構造体だね。これはメモリにあるデータがどんなふうに並べられてるかを記述するやつだね。杏はexeやらgifやらのフォーマットを調べていじってたから知ってるよ。そんで、構造体を使うとスッキリ書けるというわけね。
次は文字の話なんだけど、フォント変えようとしても、ttfなんぞ対応できるわけないし変換もできないので放置。ぐぬぬ…とりあえず理解したので文字表示で遊んでみた。
露骨な宣伝乙、と自分を突っ込みつつ次々。変数表示くんだよ!知ってる~!はい次。マウスカーソル、おお!オリジナリティが出せそう。
シャリヤちゃん描いたんだけど小さくて見えないorz…※杏は色の関係で不可。
この最後はちょっと小難しい話。理解。プログラム用のメモリを分割するセグメンテーションと、CPUの割り込み処理ね。セグメントの管理をGDTに並べて、GDTの先頭アドレスをGDTRに保存、割り込み管理はIDTに並べて、IDTの先頭アドレスをIDTRに保存。簡単。てか、2003fのCPUに割り込み実装しないとなぁ…さて、レポートもあるし、ここでちょっときゅうけーい!
date:13:00-16:00
飯とレポートを終わらせて来た。まずファイル分割をするようだ。これに関しては知ってるので読んだけどスキップ。さて、セグメントと割り込みの話の続きね。GDTに書き込まれる情報を理解した。しっかし、後方互換性をどうにかしようとするとめんどくさい仕様が増えるねぇ。
次、PICの話。CPUじゃ1個しか割り込みの面倒を見切れないので、8個の信号を見てCPUに1個の命令を送ってくれる存在。大抵2個つながってて、計15個の割り込みが可能。ほむ。
次。割り込みハンドラ。割り込み発生→レジスタをスタックに退避→ハンドラ実行→レジスタを戻す→割り込み終了ね。ここで6日目の内容は終わりか―。ひとまず実行しよう。
本にもある通りキーボードは反応するけどマウスは反応がないね。文字が出てくれません。さて、わりかし今回は説明回っぽい感じがした。
date:20:15-21:45
今日は進捗が出まくってるね。まずキーコードを取得…うっ頭が。まぁ、どうせ日本語キーボードのみ想定してることでしょう。16進数表示してるけれども、どうやら離したときは押すキーコード+0x80が返ってくるのね。成程楽しいね。そんで、ハンドラではデータをためるだけにしてメイン関数で文字表示するようにする、と。成程。
さて、マウス。マウスって、今ではキーボードと並んで重要な入力装置だけどさ、登場が1960年後半、仕様が固まったのが1975年ごろ。遅いわな。ほんで、キーボード制御回路にあるマウス制御回路を有効化のちマウス有効化をするわけだな。するとマウスからの割り込みが有効になるのね。
わーい!いよいよ次でシャリヤちゃんが反応してくれるに違いない!
date:22:15-23:15
デレステは楽しいね。ガチャに爆死さえしなければ。で、マウスからの信号を解読しようの巻。マウスからは3バイト来るのでそれを解読して、ボタンとxとyの情報からマウスを動かそうという。完成品がこちらになります。
8日目の最後は、asmhead.nas、つまりアセンブリでの初期化コードの†完全理解†。終わり。今日はここまでにしよう。
割り込みがメインだったね。これで操作とかもできるようになるし、I/Oの基礎がそろったね。非常にワクワクしてくる。それはさておき、今日は海の日で進捗出たなぁ。平日にも1日分以上は進めたい。2週間で終わらせれたら完璧。
date:2018/07/17 09:00-13:00
講義を聴きながらの。今回はメモリ管理の話。メモリが使えるかどうかは、繋がっていれば適当な値を入れて出せばちゃんとした値が返ってくる。が、繋がっていないとランダムな値になる。それを利用しているが、CPUについているキャッシュメモリが邪魔してるので切って実行。そのままだとCコンパイラの最適化を食らうのでアセンブリで書くのか。理解。そんで、ある単位ごとにメモリチェックをして、プログラムがある容量を欲するとそれだけ確保してやるわけだが、これってCではmallocってやつだっけな。先週にプログラミングのレポートがあったんだけど、任意の長さの配列を作るのに使ってたな。あれ、9日目割とあっさり?
まずメモリ管理の話。これを要は何バイト単位かでやるって話。欲しいメモリが1234kBで単位が100kBなら1300kB貸すって話ね。はい終わり。
そんで本題。重ね合わせ処理。これはRPGツクールとかウディタを使ったことがある人とかPhotoshopかGIMPやらで画像編集したことがある人はレイヤーを思い出せば分かる話っぽいね。多くの枚数のレイヤーを用意して、そんで重ねてVRAMに書き込む。そうするとウィンドウとかマウスとか上手くいってくれるようね。そんで、再描画の関数を最適化するとこう。
わーい!サクサクとマウスが描画を邪魔せずに動いてる!レイヤーの概念を思いついた人に圧倒的感謝…!
まずはマウスを画面右と画面下に隠せるようにしようって話。そこで、今までマウスの座標を制限していたコードをいじるとこうなる。
vramは横方向に走査するように一つの配列で管理されてるわけだから、そりゃそうなるわなってことなんだけれども。そんでシートを更新する関数を修正してやればちゃんとなるわけだね。
無事に隠れてくれて、ソースを書きやすくして次。いよいよウィンドウを出すんだな。さて、ちょっとここでドイツ語の講義を聴いてくる。
date:14:30-15:30
いっひ しゅぷれっひぇ かいん どいちゅ。だす いすと しゅヴぃーりひ。さて続き。ウィンドウを作るぞー!と言っても、レイヤーを作ってそこに四角やらバツやらを描くだけなんだけども。描いたものがこちら。
元ソースだとウィンドウが1つで寂しいので、2つに増やした。これで良し。そんでもって、ウィンドウの更新に関して云々すると上にレイヤーがあってもちらちらしないカウンターができるじゃ。
どんどんOSじみてきたね。マウス動かせるとかウィンドウ表示できるとか。これからどうなるか楽しみ。ちゃんと内部構造も復習しなきゃね。
date:2018/07/18 13:30-14:30
CPUは時間を計れない。それは当然なので、コンピュータにはタイマーが存在して、割り込みから時間を伝えてくれるわけね。じゃぁ時計はどうしてるかってGoogle先生で調べてみると、タイマーとはまた別にRTCという回路があって、タイマーよりは分解能は劣るけど、電源が切れても時刻を刻んでくれるらしい。最近のOSではインターネットに繋がってるとRTCを自動補正してくれるものもあるらしいとな。ほぇー。さて本に戻ると、この割り込みを設定してみようという話。そんで、10ms周期にして表示をいじってみたものがこちら。
そしてタイムアウトの実装。構造体を用意してタイマーを登録していく。それで、設定した時刻と比較だり何だりしてOK。あとは最適化して12日目は終了。無駄な最適化に見えるけど、アルゴリズムの大切さはおねえさんが教えてくれた。
date:17:00-18:00
さて、まず文字列表示を関数にまとめ―の、タイマーのバッファを一つにまとめ―の、12日目のタイマーの性能をそれぞれ測定してみーの、更にキーボードとマウスのバッファもまとめーの、すると性能が良くなり―の、トツギーノ割り込み禁止中にあるずらし処理を改善しーの。終わり!
今日はタイマーのみをやった感じだけど、時間を測れるということは時計も当然できるので、よきかな。
date:2018/07/19 06:55-07:30
今日の最初は昨日のタイマーの性能測定。改善わかりみの令なので次。今回は半分あたりなので、どうやらもうOSの基盤部分はここら辺までらしく。そんで次の15日目でマルチタスクがあるので今回はおまけ回みたいな感じらしい。行ってみよう。
まずは高解像度にしてみようということらしいけど、時代は今やフルHDが普通で、4kやら8kが出てる時代。なので320*200のOSを必要とする人なぞおらんのじゃ。それで、今回はビデオカードに関するBIOSである"VESA BIOS extension"を使うのじゃ。すると色々楽しくなる。らしい。そんでもって、AX=0x4f02、BX=画面モード番号を突っ込むといいらしい。ほむ。そこで、QEMUが対応している最大サイズの1024*768にしてみた。のじゃ。
わーひろーい(錯覚)やっぱフルHDになれると目が肥える(?)次。キー入力をしてみようという。あぁキーコード。キーコードと文字に対応する表を作って、文字表示(ウィンドウ上に文字を描くだけ。)やらカーソル(文字数数えつつタイマーで切り替え。)やらウィンドウの移動(ウィンドウを左クリックするとレイヤーをマウスに合わせて移動させる)やらすると…
すると、ウィンドウを動かせたり文字をかけたり。やったー!
date:09:50-10:30
一限が休講でラッキー♪余った時間で途中までやろう。マルチタスクは複数のタスクを順番にちょっとずつやっていくやつ。タスクの切り替え方法は、まずレジスタをTSSというセグメントに保存(当然GDTに登録する)、そんで別のTSSからタスクのレジスタを引っ張ってくる、そんでジャンプ。それをタイマーで一定時間ごとにすればOK。
date:12:00-24:00(途切れ途切れ)
マルチタスクができたわけだし、ここで何か一つ自分で作ってみようとなった。そこで、右下のアレ、そう、時計を作ろう!となった。30日目までチラ見しても時計が無かったのでオリジナルだよね?ということでやっていこう。
まずタスクを用意…よし、できた。次、時刻の取得。ふむ。ネットによるとINT 0x1AでAH=0x04なら日付、AH=0x02なら時刻を取得できるらしい。よーし、naskfunc.nasのアセンブラファイルに書いてコンパイル♪…あれ?止まった!何でだろう…タスクが悪いのかな…あっ、そういえばINT命令でBIOSから色々取得していたのはブート中の16ビットモードの時だったよね。こりゃ無理なわけだ。よし、asmhead.nasに書こう。…あー、メモリのどこに時刻書こう。BOOTINFOはもうパンパンだしね。仕方がないので0x0fe0から書く。ようし、初期時刻が取れた!
あとはバグ探しの時に止めたタスクを再度動かして時刻の加算プログラムを作って…っと。よし、完成!
…ありっ?!カッコつけて時刻が変わる瞬間を狙ってスクショ取ろうと思ったら時計バグっちゃった…ただのコードの書き間違えだった。トホホ…。というわけでバグ修正して時計完成ー。ふー、やっぱ楽しいね!
というわけで、これから先の画像には右下に時計が出ることがあるかもね。コピペがめんどいときは出ないときもあるかも。
やー、物を作るっていいね。そういえば、デジハリと並んでネタな大学があったような。
date:2018/07/20 13:00-14:00
朝っぱらから本を求めて梅田を歩き回ってたので疲れた。
さて、マルチタスクを自動化…あっ、この後に時計作った方が良かったかも。すべてのプログラムをタスクとしてタスク情報を設定していくわけでござる。ほんで自動的にタスク追加してマルチタスクできるようにしたと。ほい。
次。スリープ。要は何も働いてなかったらそれに割く時間がもったいないので、割り込みが来るまでスリープというかマルチタスク表から削除しちゃえという。そんで、割り込みが来たらタスクをたたき起こすというか実行開始と言うか。
次。ウィンドウを大量に追加してみようとのこと。どうせ画像だすしついでだから時計も移植。タスクが多いでござる。
さて、タスク優先度の話。マウスがもっさりなので優先度高め。時計は…どうなんだろう、確かめてみよう。おお!優先度を高くしたら、これまでもっさりしていた時間の動きが実時間と同じになってる!同期は残念ながらできないのは百も承知なので、現実とのずれ(なんかかっこいい)が少なくなるのは非常にありがたい。
date:17:20-21:00
OUCC到着、ようし、電池が尽きぬ限りがっつり進捗だすぞー!まずは全部のタスクを終了したらおかしくなっちゃうので、番兵haltタスクくんを設置。
次、コンソールを作ろう。と言っても今まで通りウィンドウ作って文字入力できるようにして、そして忘れず黒塗りの背景に追突してしまう。後輩をかばいすべての責任を負った三浦に対し、車の主、暴力団員谷岡が言い渡した示談の条件とは…。
で、何が問題なのかと言うと、今はtask_aの方にキーボードの割り込みが吸収されちゃってるし、そっちのウィンドウがアクティブになってるように見えるってわけで。まず、ここではtabキーを押すとウィンドウ上部のタイトルの背景色を変えるようにする。次、FIFOをタスクの構造体に標準装備することで、task_aからでもコンソールのタスクのFIFOを覗けるように。そんで、キーが押されたらそのFIFOにねじ込む。
あとは、シフトやらCapsLockやら南無ロックやらを管理するようにすると、大文字小文字はさらなり、記号が入力できるようになり申す。いとよろし。
…あれ?時計のタスクを作ったらコンソールの方の入力が消えた…?ん、あ、そうか。タスクの優先度的にそっちにまずFIFOで送ったデータが流れてしまってるのか。一時的に時計の優先度を下げて…
よすよす(根本的に治ってない)。
まずカーソルをアクティブなウィンドウのみに表示させたいってことで。Tabを押したとき、当然それを操作しているtask_aはカーソルを簡単に消せるけど、コンソールの方はどう操作するか。それはFIFOでどうするかという情報を投げればよい。
おけおけ。次、改行。Enterが打たれると、改行指令を相手のFIFOにシュゥゥゥーッ!!超!エキサイティン!!そして相手のボール…じゃなくて情報を受け取ったコンソールは文字表示のy座標を足す。次。改行していくと行が足りなくなるので、スクロールをしたい。そこで、グラフィックを上にずらす→一番下の行を黒塗りの高級車にする→また行を書き始める、でできる。
スクロールまでができたらコマンドを足してみようという。入力された文字を貯めて、それをコマンドと比較する簡単なシステム。まずメモリ使用状況を出してみる。
次に画面消去。メタな話、clsは実行すると画像に残せないのでめんどくさい。
そしてdir。このOSは勿論平坦なファイルシステムなので、ファイル情報が入っている場所から読み込んで、ベタに書いていく感じである。
おまけ
コンソールができると、いよいよOSのソフトウェア部分を作っていくんだな、という感じがする。
date:2018/07/21 22:00-24:00
1日一つは進捗を出すべきと思って、疲れた体を叩き起こす。今回はまずtype/catコマンド、つまりファイルの中身を表示。ファイルの場所はunsigned short clustnoという変数を参考にすればよく、これが1変化すると開始場所が1セクタずれるらしい。それと、改行やらTabやら考慮。そして、ファイルは512バイトを超えると別のセクタに保管されるが、それが次のセクタとは限らない。そこで、FATというシステムを採用しているのだが、要は次にどこのセクタに保存しているかという表のことである。それを読んで512バイト以上のファイルに対応。
そして、アプリを作る。ファイルを読めるようになったので、読み込んでからそれをセグメントに詰めて、そこにジャンプすることで実現。
アプリ実行…いよいよという感じ。
date:17:00-
コンソールへのAPIを作るようで。まず文字表示API。まずはアプリケーションをアセンブリで書くが、C言語で書かれた関数はそのままでは呼べずAPIとしては使えないので、INT命令を使う。