feat: docs & ARCH 2.2, 2.3, 2.4
This commit is contained in:
88
kernel/docs/debug/introduction.md
Normal file
88
kernel/docs/debug/introduction.md
Normal file
@@ -0,0 +1,88 @@
|
||||
# Подсистема отладки: концептуальная модель
|
||||
|
||||
## Два канала вывода
|
||||
|
||||
Ядро имеет два параллельных канала для отладки:
|
||||
|
||||
1. **Экранный (framebuffer console)** — через `tty::Console`.
|
||||
- Использует PSF2-шрифты.
|
||||
- Цветной вывод (зелёный/жёлтый/красный для Info/Warn/Error).
|
||||
- Медленнее, но визуально нагляднее.
|
||||
|
||||
2. **Serial port (COM1)** — через `debug::serial`.
|
||||
- Текстовый вывод с ANSI escape codes.
|
||||
- Работает через QEMU/KVM serial console.
|
||||
- Быстрее, может быть перенаправлен в файл.
|
||||
|
||||
## LogLevel — уровни логирования
|
||||
|
||||
```rust
|
||||
pub enum LogLevel {
|
||||
Info, // Зелёный на экране, зелёный в serial
|
||||
Warn, // Жёлтый
|
||||
Error, // Красный
|
||||
}
|
||||
```
|
||||
|
||||
Каждый уровень имеет:
|
||||
- `serial_color_code()` — ANSI escape code для serial.
|
||||
- `console_color()` — RGB значение для framebuffer.
|
||||
|
||||
## Макросы
|
||||
|
||||
```rust
|
||||
// Основной макрос
|
||||
log!(console, level, module, format_args...)
|
||||
|
||||
// Специализированные
|
||||
info!(console, module, format_args...)
|
||||
warn!(console, module, format_args...)
|
||||
error!(console, module, format_args...)
|
||||
```
|
||||
|
||||
**Формат вывода на экран:**
|
||||
```
|
||||
[ LOG ] <module> | <message>
|
||||
```
|
||||
|
||||
**Формат в serial:**
|
||||
```
|
||||
GREEN[ LOG] RESET <module> | <message>
|
||||
```
|
||||
|
||||
## Цветовое кодирование
|
||||
|
||||
| Уровень | Экран (RGB) | Serial (ANSI) |
|
||||
|---------|-------------|---------------|
|
||||
| Info | 0x00FF00 | `\x1b[32m` (green) |
|
||||
| Warn | 0xFFFF00 | `\x1b[33m` (yellow) |
|
||||
| Error | 0xFF0000 | `\x1b[31m` (red) |
|
||||
| Текст | 0xFFFFFF (white) | `\x1b[0m` (reset) |
|
||||
|
||||
## Использование в kmain()
|
||||
|
||||
```rust
|
||||
// После инициализации serial
|
||||
debug::serial::init_global();
|
||||
|
||||
// После инициализации console
|
||||
info!(console, "BOOT", "LIS4 Kernel Starting...");
|
||||
info!(console, "MEM", "BitmapPMM initialized.");
|
||||
info!(console, "LAPIC", "Local APIC initialized.");
|
||||
```
|
||||
|
||||
## Архитектура
|
||||
|
||||
```
|
||||
┌──────────────┐ ┌───────────────────┐
|
||||
│ kmain() │────►│ log!() macro │
|
||||
└──────────────┘ └────────┬──────────┘
|
||||
│
|
||||
┌──────────────┼──────────────┐
|
||||
▼ ▼ ▼
|
||||
┌──────────┐ ┌──────────┐ ┌──────────┐
|
||||
│ Экран │ │ Serial │ │ Паника │
|
||||
│ Console │ │ COM1 │ │ Handler │
|
||||
│ (tty.rs) │ │(serial.rs)│ │(main.rs) │
|
||||
└──────────┘ └──────────┘ └──────────┘
|
||||
```
|
||||
110
kernel/docs/debug/serial.md
Normal file
110
kernel/docs/debug/serial.md
Normal file
@@ -0,0 +1,110 @@
|
||||
# Serial Port драйвер: `serial.rs`
|
||||
|
||||
## Назначение
|
||||
|
||||
Драйвер последовательного порта (UART 16550, COM1) для отладочного
|
||||
вывода. Позволяет видеть сообщения ядра через QEMU serial console,
|
||||
minicom, screen и т.д.
|
||||
|
||||
## Аппаратная модель
|
||||
|
||||
COM1 расположен по портам ввода-вывода `0x3F8`-`0x3FF`:
|
||||
|
||||
| Порт | Регистр | Назначение |
|
||||
|------|---------|------------|
|
||||
| 0x3F8 | DATA | Чтение/запись данных |
|
||||
| 0x3F9 | IER | Interrupt Enable |
|
||||
| 0x3FA | IIR/FCR | Interrupt ID / FIFO Control |
|
||||
| 0x3FB | LCR | Line Control |
|
||||
| 0x3FC | MCR | Modem Control |
|
||||
| 0x3FD | LSR | Line Status |
|
||||
| 0x3FE | MSR | Modem Status |
|
||||
|
||||
## Инициализация
|
||||
|
||||
```rust
|
||||
pub unsafe fn init() -> Self {
|
||||
let port = Self::COM1; // 0x3F8
|
||||
outb(port + 1, 0x00); // IER = 0 (disable interrupts)
|
||||
outb(port + 3, 0x80); // LCR DLAB=1 (enable baud rate programming)
|
||||
outb(port + 0, 0x03); // Divisor LSB = 3 (38400 baud)
|
||||
outb(port + 1, 0x00); // Divisor MSB = 0
|
||||
outb(port + 3, 0x03); // LCR = 8N1 (8 bits, No parity, 1 stop)
|
||||
outb(port + 2, 0xC7); // FCR = enable FIFO, clear, 14-byte threshold
|
||||
outb(port + 4, 0x0B); // MCR = DTR+RTS+OUT2 (enable IRQ + handshake)
|
||||
SerialPort(port)
|
||||
}
|
||||
```
|
||||
|
||||
### Детали конфигурации
|
||||
|
||||
1. **IER = 0**: отключаем прерывания UART (TODO: включить для RX).
|
||||
2. **DLAB = 1**: разрешаем программирование делителя бода.
|
||||
3. **Divisor = 3**: при тактовой 1.8432 MHz → 115200 / 3 = 38400 бод.
|
||||
4. **LCR = 0x03**: 8N1 — 8 бит данных, нет чётности, 1 стоп-бит.
|
||||
5. **FCR = 0xC7**: enable FIFO, clear both FIFOs, trigger at 14 bytes.
|
||||
6. **MCR = 0x0B**: DTR=1, RTS=1, OUT2=1 (необходимо для IRQ на ISA шине).
|
||||
|
||||
## Отправка байта
|
||||
|
||||
```rust
|
||||
fn is_transmit_empty(&self) -> bool {
|
||||
unsafe { (inb(self.0 + 5) & 0x20) != 0 } // LSR bit 5 = Transmitter Holding Register Empty
|
||||
}
|
||||
|
||||
pub fn send(&self, data: u8) {
|
||||
while !self.is_transmit_empty() {} // Ждём, пока UART готов
|
||||
unsafe { outb(self.0, data); }
|
||||
}
|
||||
```
|
||||
|
||||
## fmt::Write реализация
|
||||
|
||||
```rust
|
||||
impl core::fmt::Write for SerialPort {
|
||||
fn write_str(&mut self, s: &str) -> core::fmt::Result {
|
||||
for byte in s.bytes() { self.send(byte); }
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Глобальный экземпляр
|
||||
|
||||
```rust
|
||||
static SERIAL_PORT: Locked<Option<SerialPort>> = Locked::new(None);
|
||||
|
||||
pub fn init_global() {
|
||||
let mut guard = SERIAL_PORT.lock();
|
||||
*guard = Some(unsafe { SerialPort::init() });
|
||||
}
|
||||
|
||||
pub fn write_global(args: core::fmt::Arguments) {
|
||||
let mut guard = SERIAL_PORT.lock();
|
||||
if let Some(ref mut sp) = *guard {
|
||||
let _ = sp.write_fmt(args);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`init_global()` вызывается из `kmain()` после инициализации TTY.
|
||||
`write_global()` используется:
|
||||
- В `log!()` макросе (через debug.rs).
|
||||
- В `rust_panic()` обработчике.
|
||||
- В обработчиках исключений (GPF, Double Fault, Early Exception).
|
||||
|
||||
## Низкоуровневый I/O
|
||||
|
||||
```rust
|
||||
unsafe fn outb(port: u16, val: u8) {
|
||||
asm!("out dx, al", in("dx") port, in("al") val,
|
||||
options(nomem, nostack, preserves_flags));
|
||||
}
|
||||
|
||||
unsafe fn inb(port: u16) -> u8 {
|
||||
let res: u8;
|
||||
asm!("in al, dx", out("al") res, in("dx") port,
|
||||
options(nomem, nostack, preserves_flags));
|
||||
res
|
||||
}
|
||||
```
|
||||
Reference in New Issue
Block a user