# Aios Troubleshooting Guide ## Common Issues and Solutions ### 1. Page Table Panic Error (`page_table*.rs`) #### Problem QEMUでAiosを実行すると、以下のようなパニックが発生する: ``` panicked at 'page_table*.rs:105:25' ``` #### Root Cause この問題は主にシェル機能とキーボード入力の実装時に発生する。具体的な原因: 1. **ポートI/O競合**: PS/2キーボードのポートアクセス(0x60, 0x64)がbootloaderクレートと競合 2. **メモリアクセス違反**: unsafe なポートアクセスがページテーブルの整合性を破壊 3. **割り込み処理**: キーボード割り込みの不適切な処理 #### Solution Steps **Step 1: 問題の特定** ```rust // 危険なポートアクセス例 unsafe fn inb(port: u16) -> u8 { let result: u8; core::arch::asm!( "in al, dx", out("al") result, in("dx") port, ); result } ``` **Step 2: 安全な実装への移行** ```rust // 安全なポートアクセス(遅延付き) unsafe fn try_inb(port: u16) -> Option { // Add delay to avoid rapid polling for _ in 0..1000 { core::arch::asm!("nop"); } let result: u8; core::arch::asm!( "in al, dx", out("al") result, in("dx") port, options(nomem, nostack, preserves_flags) ); Some(result) } ``` **Step 3: 完全な対策** 最終的に、以下の基本的なアプローチで解決: ```rust /// Check if there's data in keyboard buffer pub fn has_key() -> bool { unsafe { let status: u8; core::arch::asm!( "in al, 0x64", out("al") status, options(nomem, nostack, preserves_flags) ); (status & 1) != 0 } } /// Read raw scancode from keyboard pub fn read_scancode() -> u8 { unsafe { let scancode: u8; core::arch::asm!( "in al, 0x60", out("al") scancode, options(nomem, nostack, preserves_flags) ); scancode } } ``` #### Prevention - `options(nomem, nostack, preserves_flags)` を必ず使用 - ポーリング頻度を制限(1000サイクル毎など) - エラーハンドリングの実装 - 段階的テスト(まずデバッグ版で検証) --- ### 2. Keyboard Input Not Working #### Problem キーボード入力が QEMU で認識されない問題。 #### Symptoms - QEMUは正常に起動する - 画面表示は正常 - キーを押しても反応しない - スキャンコードが取得できない #### Root Causes **Cause 1: QEMUのフォーカス問題** - QEMUウィンドウにフォーカスがない - マウスキャプチャが無効 **Cause 2: ポーリング頻度の問題** ```rust // 問題のあるコード if counter % 50000 == 0 { // キーボードチェックの頻度が低すぎ } ``` **Cause 3: スキャンコードマッピングの不備** ```rust // 不完全なマッピング static SCANCODE_TO_ASCII: [u8; 128] = [ // 配列サイズが127で不一致 ]; ``` #### Solutions **Solution 1: QEMUの正しい起動** ```bash # GTK表示でフォーカス確保 qemu-system-x86_64 \ -drive format=raw,file="$BOOT_IMAGE" \ -display gtk # または、nographic を避ける qemu-system-x86_64 \ -drive format=raw,file="$BOOT_IMAGE" ``` **Solution 2: 適切なポーリング頻度** ```rust loop { if keyboard_basic::has_key() { let scancode = keyboard_basic::read_scancode(); // 即座に処理 } // 軽い遅延のみ for _ in 0..1000 { unsafe { core::arch::asm!("nop"); } } } ``` **Solution 3: 段階的デバッグ** **Phase 1: スキャンコード確認** ```rust // デバッグ版でスキャンコードを表示 if keyboard_basic::has_key() { let scancode = keyboard_basic::read_scancode(); print_hex(scancode); // 16進数で表示 } ``` **Phase 2: キーリリース除外** ```rust // キープレスのみ処理(bit 7 = 0) if (scancode & 0x80) == 0 { // キープレス処理 } ``` **Phase 3: 完全なマッピング** ```rust pub fn scancode_to_char(scancode: u8) -> Option { match scancode { 0x1E => Some('a'), 0x30 => Some('b'), // ... 全てのキーをマッピング 0x1C => Some('\n'), // Enter _ => None, } } ``` #### Verification Steps 1. **基本テスト**: スキャンコード表示版でキー入力確認 2. **マッピングテスト**: 特定キー(a, enter等)の動作確認 3. **シェルテスト**: コマンド入力・実行の確認 #### Working Configuration 最終的に動作した設定: ```rust // keyboard_basic.rs pub fn has_key() -> bool { unsafe { let status: u8; core::arch::asm!("in al, 0x64", out("al") status, options(nomem, nostack, preserves_flags)); (status & 1) != 0 } } // メインループ loop { if keyboard_basic::has_key() { let scancode = keyboard_basic::read_scancode(); if scancode != last_scancode && (scancode & 0x80) == 0 { if let Some(ch) = keyboard_basic::scancode_to_char(scancode) { process_char(ch); } } } // 軽い遅延 for _ in 0..1000 { unsafe { core::arch::asm!("nop"); } } } ``` --- ### 3. Build Errors #### Type Mismatch in Arrays ```rust // Error: expected array with size 128, found 127 static SCANCODE_TO_ASCII: [u8; 128] = [...]; // 要素が127個 // Solution: 正確な要素数 static SCANCODE_TO_ASCII: [u8; 128] = [ // 128個の要素を確保 0, 27, b'1', ..., 0 // 最後に0で埋める ]; ``` #### Unused Imports ```rust // Warning: unused import use core::convert::TryFrom; // 削除 // Warning: unused import use crate::keyboard; // 使用しない場合は削除 ``` --- ### 4. QEMU-specific Issues #### Display Problems ```bash # 問題: nographic で表示されない qemu-system-x86_64 -kernel kernel.bin -nographic # 解決: 標準表示を使用 qemu-system-x86_64 -kernel kernel.bin ``` #### Mouse Capture ``` # QEMUでマウスキャプチャを有効化 Ctrl+Alt+G (toggle mouse capture) ``` #### Exit QEMU ``` # QEMUの終了方法 Ctrl+A, X # または Alt+F4 # ウィンドウを閉じる ``` --- ### Best Practices 1. **段階的実装** - 静的表示 → スキャンコード確認 → 完全シェル 2. **デバッグ情報の表示** - スキャンコードの16進表示 - ポーリング回数のカウンタ - キー受信回数の表示 3. **安全なポートアクセス** - `options(nomem, nostack, preserves_flags)` 使用 - 適切な遅延の実装 - エラーハンドリング 4. **テスト環境** - QEMUの適切な起動オプション - フォーカスの確保 - 段階的な機能テスト