30日OS自作入門3日目(Win10)
初めに
引き続き30日OS自作を進めていきます。
もくじ
- 初めに
- もくじ
- さぁほんとのIPLを作ろう(harib00a)
- エラーになったらやり直そう
- 18セクタまで読んでみる
- OS本体を書き始めてみる
- ブートセクタからOS本体を実行させてみる
- OS本体の動作を確認してみる
- 32ビットモードへの準備
- ついにC言語導入へ
- とにかくHLTしたい
- 新出命令
- 写経ミスのメモ
- メモ
- 調べてるときに知ったこと
さぁほんとの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
こんな感じー
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にアセンブリ言語で書いた関数を置きそこから関数を引っ張ってくるようです。
まだ真っ黒
EQU
C言語でいう#defineのようなもので、定数を定義するのに使う
例
CYLS EQU 10
WCOFF
出力フォーマットの設定、WCOFFモードになる
例
[FORMAT "WCOFF"]
GLOBAL命令
連携させる関数に書く、グローバル関数みたいなやつ
GLOBAL _io_hlt
参考
新出命令
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って複数枚のディスクが入っているらしい…知らなかった…(情弱)