update v2
This commit is contained in:
378
docs/SHELL_IMPLEMENTATION.md
Normal file
378
docs/SHELL_IMPLEMENTATION.md
Normal 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
298
docs/TROUBLESHOOTING.md
Normal 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の適切な起動オプション
|
||||
- フォーカスの確保
|
||||
- 段階的な機能テスト
|
Reference in New Issue
Block a user