update v2

This commit is contained in:
2025-07-05 14:31:39 +09:00
parent 163ac1668d
commit 3a9e563ee0
40 changed files with 1929 additions and 2128 deletions

View File

@ -0,0 +1,378 @@
# Aios Shell Implementation Guide
## Overview
Aiosのインタラクティブシェル実装についての詳細ガイド。
## Implementation History
### Phase 1: Initial Attempt (Failed)
**実装内容:**
```rust
// keyboard.rs - 複雑な実装
use core::convert::TryFrom;
static SCANCODE_TO_ASCII: [u8; 128] = [
// 複雑なマッピングテーブル
];
unsafe fn inb(port: u16) -> u8 {
// 危険なポートアクセス
}
```
**問題:**
- Page table panic (`page_table*.rs:105:25`)
- ポートI/O競合
- 配列サイズ不一致
### Phase 2: Safe Approach (Partially Working)
**実装内容:**
```rust
// keyboard_safe.rs
unsafe fn try_inb(port: u16) -> Option<u8> {
// 遅延付きアクセス
for _ in 0..1000 {
core::arch::asm!("nop");
}
// ... 安全なアクセス
}
```
**結果:**
- パニックは解決
- キーボード入力が機能しない
### Phase 3: Basic Implementation (Success)
**実装内容:**
```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
}
}
```
**結果:**
- パニック解決
- キーボード入力動作
- スキャンコード正常取得
## Architecture
### Keyboard Driver (`keyboard_basic.rs`)
```rust
/// PS/2キーボードの状態確認
pub fn has_key() -> bool
/// 生スキャンコードの読み取り
pub fn read_scancode() -> u8
/// スキャンコードからASCII文字への変換
pub fn scancode_to_char(scancode: u8) -> Option<char>
```
**キーマッピング:**
```rust
match scancode {
0x1E => Some('a'), // A key
0x30 => Some('b'), // B key
0x2E => Some('c'), // C key
// ...
0x39 => Some(' '), // Space
0x1C => Some('\n'), // Enter
_ => None,
}
```
### Shell Core (`main.rs`)
**State Management:**
```rust
static mut INPUT_BUFFER: [u8; 64] = [0; 64];
static mut INPUT_POS: usize = 0;
static mut CURSOR_ROW: usize = 12;
static mut CURSOR_COL: usize = 6;
```
**Input Processing:**
```rust
fn process_char(ch: char) {
match ch {
'\n' => execute_command(),
'\u{8}' => handle_backspace(),
' '..='~' => add_char_to_buffer(ch),
_ => { /* ignore */ }
}
}
```
**Command Execution:**
```rust
fn execute_command() {
let cmd = core::str::from_utf8(&INPUT_BUFFER[..INPUT_POS])?;
match cmd {
"help" => show_help(),
"version" => show_version(),
"echo" => echo_test(),
"clear" => clear_screen(),
_ => show_unknown_command(cmd),
}
}
```
## Key Features
### 1. Real-time Input
- キー押下の即座の反映
- バックスペース対応
- 文字制限64文字
### 2. Command Processing
- Enter キーでコマンド実行
- コマンド履歴(将来実装予定)
- エラーハンドリング
### 3. Available Commands
**help**
```
Aios Commands:
help - Show this help
version - Show version
echo - Echo test
clear - Clear screen
```
**version**
```
Aios 2.0 - AI Operating System
Interactive Shell with Keyboard Support
```
**echo**
```
Hello from Aios Interactive Shell!
```
**clear**
- 画面全体をクリア
- カーソル位置をリセット
### 4. Input Handling
**Scancode Processing:**
```rust
loop {
if keyboard_basic::has_key() {
let scancode = keyboard_basic::read_scancode();
// キーリリースを除外
if scancode != last_scancode && (scancode & 0x80) == 0 {
last_scancode = scancode;
if let Some(ch) = keyboard_basic::scancode_to_char(scancode) {
process_char(ch);
}
}
}
// CPU負荷軽減
for _ in 0..1000 {
unsafe { core::arch::asm!("nop"); }
}
}
```
## VGA Text Mode Interface
### Screen Layout
```
Row 0: "Aios - AI Operating System" (Center)
Row 1: "Interactive Shell Ready" (Center)
Row 2: "Type 'help' for commands" (Center)
Row 3: [Empty]
Row 4: [Empty]
Row 5: aios> [user input] (Prompt)
Row 6+: [Command output]
```
### Character Display
```rust
pub fn print_char(c: u8, x: usize, y: usize) {
if x >= 80 || y >= 25 { return; }
unsafe {
let vga = &mut *VGA_BUFFER;
vga.chars[y][x] = (0x0f << 8) | (c as u16);
// ^^^^ ^^^^^^^^^^
// Color Character
// (White/Black) (ASCII)
}
}
```
**Color Scheme:**
- `0x0f` = White text on black background
- Format: `(color << 8) | character`
## Testing Procedures
### 1. Scancode Debug Test
```rust
// 目的: キーボード入力の確認
// 表示: "Scancode: 0x1E -> 'a'"
```
### 2. Interactive Shell Test
```bash
# テストシーケンス
1. help <Enter> # ヘルプ表示確認
2. version <Enter> # バージョン情報確認
3. echo <Enter> # エコーテスト確認
4. clear <Enter> # 画面クリア確認
5. invalid <Enter> # エラーハンドリング確認
```
### 3. Input Edge Cases
```bash
# テストケース
- 空のコマンド (Enter のみ)
- 長いコマンド (64文字以上)
- バックスペースの動作
- 連続入力
```
## Performance Considerations
### CPU Usage
```rust
// 軽量な遅延ループ
for _ in 0..1000 {
unsafe { core::arch::asm!("nop"); }
}
```
### Memory Usage
- Input buffer: 64 bytes
- VGA buffer: Direct access (no buffering)
- Static variables: Minimal usage
### Polling Frequency
- 高頻度ポーリング遅延1000サイクル
- CPU halt命令は使用しない応答性重視
## Known Limitations
### 1. Character Set
- ASCII printable characters only (`' '` to `'~'`)
- 日本語等のマルチバイト文字は未対応
- 特殊キーF1-F12, Arrow keysは未対応
### 2. Input Features
- コマンド履歴なし
- Tab補完なし
- 行編集機能なし(カーソル移動等)
### 3. Display
- 80x25 text mode固定
- スクロール機能なし
- 色変更機能なし
## Future Enhancements
### 1. Advanced Input
```rust
// 計画中の機能
- Command history (/ keys)
- Tab completion
- Line editing (/ keys)
- Multi-line input
```
### 2. Extended Commands
```rust
// 追加予定のコマンド
- ls // File listing
- cat // File content
- mkdir // Directory creation
- cd // Change directory
- ps // Process list
- claude // AI integration
```
### 3. Display Improvements
```rust
// 計画中の機能
- Scrolling support
- Color themes
- Multiple windows
- Status bar
```
## Debugging Tips
### 1. Scancode Debugging
```rust
// スキャンコード確認用
print_str("Raw: 0x", x, y);
print_hex(scancode);
```
### 2. Buffer State Debugging
```rust
// バッファ状態確認
print_str("Pos: ", x, y);
print_number(INPUT_POS);
```
### 3. QEMU Console Output
```bash
# QEMUでの詳細ログ
qemu-system-x86_64 -kernel kernel.bin -d int,cpu
```
## Build Configuration
### Cargo.toml
```toml
[package]
name = "aios-kernel"
version = "0.2.0"
edition = "2021"
[dependencies]
bootloader = "0.9.23"
```
### Build Command
```bash
# 開発用
cargo bootimage --release
# テスト用
./scpt/bootimage-test.sh
```
## Success Metrics
実装成功の判定基準:
1. **キーボード入力**: 文字入力が画面に表示される
2. **コマンド実行**: `help`コマンドが正常動作
3. **バックスペース**: 文字削除が正常動作
4. **エラーハンドリング**: 不明コマンドでエラー表示
5. **画面管理**: `clear`コマンドで画面クリア
全ての機能が正常動作することを確認済み。

298
docs/TROUBLESHOOTING.md Normal file
View File

@ -0,0 +1,298 @@
# 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<u8> {
// 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<char> {
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の適切な起動オプション
- フォーカスの確保
- 段階的な機能テスト