Files
Elyz/kernel/docs/console.md
2026-07-06 00:25:49 +03:00

133 lines
4.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Консоль и отладка
---
## TTY — PSF2 терминал
**Файл**: `src/tty.rs`
Шрифтовой терминал на основе PSF2 (PC Screen Font v2). Это **реально используемая консоль** в `kmain`.
### Psf2Header — `#[repr(C, packed)]`
```rust
struct Psf2Header {
magic: u32, // магическое число PSF2
version: u32,
header_size: u32,
flags: u32,
num_glyphs: u32, // количество глифов
bytes_per_glyph: u32,
height: u32, // высота шрифта в пикселях
width: u32, // ширина шрифта в пикселях
}
```
### Console
```rust
pub struct Console<'a> {
framebuffer: &'a Framebuffer<'a>,
font: &'static [u8], // сырые данные PSF2
x: usize, // курсор X (в пикселях)
y: usize, // курсор Y (в пикселях)
fg_color: u32, // цвет текста (0xFFFFFF = белый)
bg_color: u32, // цвет фона (0x000000 = чёрный)
}
```
### Методы
| Метод | Описание |
|---|---|
| `new(framebuffer, font)` | Создаёт консоль, курсор в (0,0) |
| `set_color(fg)` | Устанавливает цвет текста |
| `clear()` | Зануляет фреймбуфер, сбрасывает курсор |
| `header()` | Возвращает ссылку на Psf2Header |
| `scroll()` | Сдвигает фреймбуфер на высоту шрифта, зануляет низ |
| `draw_glyph(glyph_index, x, y)` | Рисует глиф: сканирует bitmap шрифта, пишет `fg_color` для установленных битов |
| `write_char(c)` | Обрабатывает `\n`, word wrap, поиск глифа (0 для отсутствующих), скролл |
| `write_str(s)` | Реализация `fmt::Write` — итерация по символам |
`draw_glyph` — ключевой метод: строки шрифта — это побитовое представление, каждый бит — один пиксель. Если бит установлен → пишется `fg_color`, иначе пропускается.
---
## Serial — последовательный порт
**Файл**: `src/debug/serial.rs`
Драйвер UART 16550 на COM1.
### SerialPort
```rust
pub struct SerialPort(pub u16); // номер порта
```
### Инициализация UART (`init()`)
```rust
port + 1 = 0x00 // отключение прерываний
port + 3 = 0x80 // DLAB = 1 (доступ к делителю)
port + 0 = 0x03 // делитель младший байт (~38400 бод)
port + 1 = 0x00 // делитель старший байт
port + 3 = 0x03 // 8N1: 8 бит, no parity, 1 stop bit
port + 2 = 0xC7 // FIFO enable, clear, 14-byte threshold
port + 4 = 0x0B // DTR + RTS (data terminal ready)
```
### Методы
| Метод | Описание |
|---|---|
| `is_transmit_empty() -> bool` | Проверка бита 5 Line Status Register |
| `send(data: u8)` | Ждёт `is_transmit_empty()`, затем пишет в порт |
| `write_str(s)` (fmt::Write) | Поcимвольная отправка |
### Функции
| Функция | Описание |
|---|---|
| `init_global()` | Инициализирует COM1, сохраняет в `SERIAL_PORT` |
| `write_global(args: Arguments)` | Пишет форматированную строку в serial |
| `outb(port, val)` | `unsafe`: инструкция `out` (write I/O port) |
| `inb(port) -> u8` | `unsafe`: инструкция `in` (read I/O port) |
---
## Логирование
**Файл**: `src/debug.rs`
### LogLevel
```rust
pub enum LogLevel {
Info, // зелёный: ANSI \x1b[32m, RGB 0x00FF00
Warn, // жёлтый: ANSI \x1b[33m, RGB 0xFFFF00
Error, // красный: ANSI \x1b[31m, RGB 0xFF0000
}
```
### Макросы
#### `log!(console, level, module, $($arg)*)`
Формат: `[ LOG ] <module> | <message>\n`
Двойной вывод:
- **Console**: цветной `[ LOG ]` (по LogLevel) + белый `<module> | <message>`
- **Serial**: ANSI-цветной `[ LOG ]` + `<module> | <message>` + ANSI reset
#### `info!(console, module, ...)`
Обёртка над `log!` с `LogLevel::Info`. Зелёный `[ LOG ]`.
#### `warn!(console, module, ...)`
Обёртка над `log!` с `LogLevel::Warn`. Жёлтый `[ LOG ]`.
#### `error!(console, module, ...)`
Обёртка над `log!` с `LogLevel::Error`. Красный `[ LOG ]`.
Все макросы экспортируются (`#[macro_export]`) и доступны из любого модуля.