30日OS自作入門3日目(Win10)

初めに

引き続き30日OS自作を進めていきます。

もくじ

さぁほんとのIPLを作ろう(harib00a)

まず、述べられているのが

INT    0x0c

これはディスクの処理をBIOSにお願いしているみたいです。

レジスタの状態

AH:読み込み、書き込み、ベリファイ*1、シーク*2を分け
*1:正しく動いているかの確認
*2:磁気ヘッダや光ピックアップを目的の読み取り位置に移動させること

AL:セクタ数の指定(連続したセクタの処理用)
セクタとは・・・シリンダからさらに区切るために、放射状に等分した領域

CH:シリンダ番号の指定
シリンダ・・・玉ねぎの層みたいに分けた領域
CL:セクタ番号の指定
ES:BS・・・バッファアドレスの指定

バッファアドレス

メモリ上のどこに書き出すかを指定しているアドレス

EFLAG.CF

エラーの処理、エラーがあると1ないと0となる。エラーがあった場合AHにエラーコードが送られる。

次のセクタを読むため

CLを2増やすことと、ESを0x20増やすこと
これは、CLがセクタ番号をESが読み込み番地の指定をしているから

参照資料

(AT)BIOS - os-wiki
ctrl+Fで「ディスクからの読み込み」って検索したら早いと思う。

エラーになったらやり直そう

フロッピーディスクはたまに読めない場合があるので、5回くらい繰り返し処理で読み込みする。この際エラーが出ると、AH=0x00、DL=0x00、INT 0x13で「システムのリセット」を行う。

18セクタまで読んでみる

先ほどの、「次のセクタを読むため」のようにESとCLを使って指定する。この際ALに17を入れて一気に指定してしまうのもできはしないが、連続処理に条件があるかもしれないので避けている。
これで、ディスク上のC0-H0-S1からC0-H0-S18までのデータをメモリ上の0x8200~0xa3ffに読み込むことができた。

OS本体を書き始めてみる

HLTだけ書いたデータをバイナリエディタで見てみると、空のディスクにインストールするとファイル名は0x002600以降で、ファイルの中身は0x004200以降に入るらしい。
(USBとかでも同じなのか気になりますね…)

ブートセクタからOS本体を実行させてみる

記述したプログラムを起動させたい場合、ブートセクタの先頭が0x8000番地に来る。読み込まれるデータは0x8000+0x4200=0xc200番地に読み込まれるので、haribote.nas(OS本体)の最初の読み込みアドレス処理でORG 0xc200を指定し、ipl.nasブートローダー)はJMP 0x2c00でジャンプすれば橋渡しができる!!!!!(こうやってつないでたのかと感激である)

OS本体の動作を確認してみる

2日みたいに文字を描写するだけだと面白くないので、ビデオBIOSで黒画面を描写するらしい。
この際も以下のページの、ビデオモード設定に従って設定をし表示を行う。
(AT)BIOS - os-wiki
f:id:No000:20191011173749p:plain こんな感じー

32ビットモードへの準備

モードの移行に関して

PCの起動時は16bitモードなので、16bit用のレジスタ、命令しか使用できないので、32bitモードにする。
32bitモードの利点は
・メモリが1MBを超えて使える
機械語での誤作動を防ぐ保護モードが使える
しかし、BIOSが使えなくなる(BIOSは16bitの機械語で書いてあるため)
*32bitから16bitになる方法はあるらしい…(めんどくさいけれど)

キーボード対応と画面モードのバックアップ

このコードの追加でキーボードの状態をBIOSを介して教えてもらった後、メモリにメモしています。
画面モードのバックアップは、画面モードによりどのVRAMを使用するか決まっているので、どのVRAMを使うか・画素数・解像度をメモリにメモします。
この際のBoot_Infoはメモリ上の保持しているデータのことの総称?として表しています

ついにC言語導入へ

ここでは、
アセンブリC言語を関数として利用できるようにする
C言語での処理を書く
MakefileアセンブリをヘッドとしてC言語と繋げる

C言語の基礎

・{}は関数の中身を囲んでいる
・一つ目のvoidは何もデータを必要としていないvoid
・2つ目のvoidは何もデータを返さないvoid
・goto文⇒JMP命令みたいなやつ
基礎中の基礎ですね、書籍にはほんとにわかりやすく書いてます

その後は、独特のコンパイラと拡張子の説明があり
・オブジェクトファイルにはリンクするための、のりしろの情報が余分にある
・中間処理を多くしているのは、コンパイラの内部処理を見てもらうためと柔軟性のため
・Harimainがmain関数に当たる
あたりが重要と感じました

とにかくHLTしたい

haribote00iだとC言語の中にラベルとgoto文で無限ループを実装されてたのですが、HLT命令ができないのでnaskfunc.nasアセンブリ言語で書いた関数を置きそこから関数を引っ張ってくるようです。
f:id:No000:20191011173749p:plain まだ真っ黒

EQU

C言語でいう#defineのようなもので、定数を定義するのに使う

CYLS EQU 10

WCOFF

出力フォーマットの設定、WCOFFモードになる

[FORMAT "WCOFF"]

GLOBAL命令

連携させる関数に書く、グローバル関数みたいなやつ

GLOBAL  _io_hlt

参考

GO/nask - os-wiki

新出命令

JC命令

キャリーフラグが1だったら、指定のラベルにジャンプする。

JC   error

JNC(jump if not carry)命令

キャリーフラグが0だったら指定されたラベルにジャンプする命令

JNC    fin

JAE(jump if above or equal)命令

比較命令で比較した結果が大きいまたは同じかだった場合にジャンプする

JAE    error

JBE(jump if below or equal)命令

比較命令で比較した結果が、小さいまたは同じかだった場合にジャンプする

JBE    readloop

JB命令

比較命令の結果が小さければ、ジャンプしなさいということ

JB    readloop

写経ミスのメモ

・DBとDDのミスがあるので、ビットの数を意識してやる。
・0c123とxを押し間違える
・MOVとSUBを間違える

メモ

・メモリの番地と中のデータ、どちらを指しているかをしっかりと意識 ・BXに512を足す意味を調べる

調べてるときに知ったこと

HDDって複数枚のディスクが入っているらしい…知らなかった…(情弱)