最適な画面モードの設定で苦戦した話
@Egh2Deywos
目次
自己紹介
背景
モニターの性能を最大限生かせない・・・
最適な画面モードを設定しよう!!!
手順
https://wiki.osdev.org/VESA_Video_Modes
を参考にやってみた
基本的な流れ
手順
https://wiki.osdev.org/VESA_Video_Modes
を参考にやってみた
基本的な流れ
手順 1.利用可能な画面モードの一覧を取得
ES:DIにこの構造体が書き込まれる
利用可能画面モード番号の配列
0X0100 |
0X0101 |
0X0102 |
0X0103 |
0X0104 |
0X0105 |
0XFFFF |
手順
https://wiki.osdev.org/VESA_Video_Modes
を参考にやってみた
基本的な流れ
手順 2.最適な画面モードを探す
INT 0x10, AX=0x4F01, CX=mode, ES:DI=256byte buffer
ES:DIに、画面モードに関する情報が書き込まれる
その他いろいろ
手順 2.最適な画面モードを探す
「最適」をどう定義する?
best_mode;
for each mode {
if(0x18 <= mode.bits_per_pixel){
if(best_mode.width <= mode.width && best_mode.height <=mode.height){
best_mode = mode;
}
}
}
手順
https://wiki.osdev.org/VESA_Video_Modes
を参考にやってみた
基本的な流れ
手順 3.最適な画面モードに移行
INT 0x10, AX=0x4f02, BX=mode(+0x4000)
ここはharibote OSと同様
やってみよう!
やってみた
Virtual Boxでの実行結果
やってみた
手順1,2,3ができているかどうか、順番に確かめてみよう!
実機での実行結果
バグ倒しの旅
手順1.利用可能な画面モードの一覧を取得できているかどうか
video mode = 0x0000
video mode = 0x0000
video mode = 0x0000
video mode = 0x0000
video mode = 0x0000
video mode = 0x0000
video mode = 0x0000
video mode = 0x0000
ううっ…
バグ倒しの旅
VideoModePtr[1]がセグメント、VideoModePtr[0]がオフセットだった
バグ倒しの旅
VideoModePtr = 0xc00090b9
これがそのまま物理アドレスだと思ってた(というか上位16ビットを無視してた)
セグメント0xc000、オフセット0x90b9という意味だった。
ここを直して画面モードの一覧を取得できるようになった!
さらに、手順2もうまくいった!(実機での最適な画面モードは0x017fだった)
バグ倒しの旅
しかし!!!
バグ倒しの旅
同一の画面モードの情報を複数回取得しているのがまずい?
バグ倒しの旅
best_mode;
for each mode {
modeの画面モード情報を0x700番地に書き込み
if(0x18 <= mode.bits_per_pixel){
if(best_mode.width <= mode.width && best_mode.height <=mode.height){
best_mode = mode;
0x700番地の画面モード情報を0x600番地に書き写す
}
}
}
同一の画面モードの情報取得を一回で済ませられるように変更
バグ倒しの旅
やったー!!!
いよいよ画面切替!
バグ倒しの旅
画面が使えない
シリアルポートない
printデバッグできない
ううっ…
バグ倒しの旅
VRAMの物理アドレスはわかっている(0xe0000000番地)
32ビットモードに入ってからの処理を全て削除し、VRAMに直接書き込み
具体的には、0xe0000000番地から0xe0200000番地まで0xffを書き込みまくった
バグ倒しの旅
画面モード切替は成功していることが分かった
→ではどこでバグってる?
バグ倒しの旅
実験を繰り返した結果、マウスを有効化するinit_mouse()関数がトリガーだった
init_mouse()を実行する | 画面が表示されない |
init_mouse()を実行しない | 画面が表示される |
init_mouse()関数の中身を確認してみる
バグ倒しの旅
マウスを使うためにいろいろやり取りしてる
バグ倒しの旅
マウスとのやり取りはキーボード制御回路を通して行う
バグ倒しの旅
キーボード制御回路への送信はこんな感じ
もしかしてここで無限ループに陥ってる?
無限ループに陥っているとしたらなぜ?
割り込みが禁止されていないのでは?
初期化前にcli、初期化後にstiしてみた
バグ倒しの旅
やったー!!!
まとめ
今後の課題