feat: docs & ARCH 2.2, 2.3, 2.4

This commit is contained in:
Faynot
2026-07-07 16:40:41 +03:00
parent c092a81331
commit 1bfde637d0
50 changed files with 5113 additions and 1823 deletions

150
kernel/docs/tty.md Normal file
View File

@@ -0,0 +1,150 @@
# Framebuffer Console: `tty.rs`
## Назначение
Драйвер графического вывода текста на framebuffer. Использует
PSF2 (PC Screen Font 2) шрифты для отрисовки символов.
Является основным визуальным каналом вывода ядра (через info! макрос).
## Структура Console
```rust
pub struct Console<'a> {
framebuffer: &'a Framebuffer<'a>, // ссылка на Limine framebuffer
font: &'static [u8], // PSF2 шрифт
pub x: usize, // текущая позиция X (колонка)
pub y: usize, // текущая позиция Y (строка)
pub fg_color: u32, // цвет текста (RGB)
pub bg_color: u32, // цвет фона (RGB)
}
```
## PSF2 Header
```rust
#[repr(C, packed)]
struct Psf2Header {
magic: u32, // 0x864AB572 (PSF2 magic)
version: u32,
header_size: u32, // размер заголовка
flags: u32,
num_glyphs: u32, // количество глифов
bytes_per_glyph: u32, // байт на глиф
height: u32, // высота глифа в пикселях
width: u32, // ширина глифа в пикселях
}
```
Шрифт — `font.psf` (8×16, встроен через `include_bytes!`).
## Операции
### clear()
Заполняет весь framebuffer нулями. Сбрасывает позицию курсора в (0, 0).
```rust
pub fn clear(&mut self) {
unsafe {
core::ptr::write_bytes(fb.addr(), 0, (fb.pitch() * fb.height()) as usize);
}
self.x = 0;
self.y = 0;
}
```
### scroll()
Сдвигает содержимое framebuffer вверх на высоту шрифта.
Новые строки заполняются нулями.
```rust
fn scroll(&mut self) {
let shift = font_height * pitch; // смещение на 1 строку
let size = pitch * (height - font_height); // сколько копировать
unsafe {
ptr::copy(addr.add(shift), addr, size);
ptr::write_bytes(addr.add(size), 0, shift);
}
self.y -= font_height;
}
```
### draw_glyph(glyph_index, x, y)
Рисует глиф (символ) в заданной позиции.
```rust
fn draw_glyph(&mut self, glyph_index: u32, x: usize, y: usize) {
let bytes_per_line = (width + 7) / 8; // пиксели → байты
let glyph_offset = header_size + (glyph_index * bytes_per_glyph);
for cy in 0..height {
let glyph_row = self.font[glyph_offset + cy * bytes_per_line];
for cx in 0..width {
if (glyph_row & (0x80 >> cx)) != 0 {
// Пиксель включён — рисуем fg_color
let offset = ((y + cy) * fb_pitch) + ((x + cx) * 4);
unsafe {
fb_addr.add(offset).cast::<u32>().write_volatile(self.fg_color);
}
}
// Если пиксель выключен — фон остаётся (нет очистки)
}
}
}
```
- `width=8`, `bytes_per_line=1`: каждый ряд глифа = 1 байт.
- `(0x80 >> cx)`: проверка бита слева направо (MSB first).
- `write_volatile`: запрещает компилятору оптимизировать запись в MMIO.
### write_char(c)
Печатает символ:
- `\n` → переход на новую строку.
- Другие символы → draw_glyph. Если символ > num_glyphs → глиф 0.
- Перенос строки по ширине экрана.
- Скроллинг при достижении низа.
## fmt::Write реализация
```rust
impl fmt::Write for Console<'_> {
fn write_str(&mut self, s: &str) -> fmt::Result {
for c in s.chars() {
self.write_char(c);
}
Ok(())
}
}
```
## Использование в kmain()
```rust
let fb = fb_res.framebuffers().next().expect("No framebuffer");
let mut console = tty::Console::new(&fb, KERNEL_FONT);
console.clear();
info!(console, "BOOT", "LIS4 Kernel Starting...");
// ... остальные логи
let _ = writeln!(console, "{}", logo); // ASCII art при загрузке
```
## Детали реализации
- **Цвета**: write_volatile для 32-битного пикселя. Формат — RGBA?
(зависит от режима framebuffer).
- **Фон**: не перерисовывается. Только пиксели текста.
Для полной очистки — clear().
- **PSF2 magic**: `0x864AB572` — проверяется в заголовке.
- **Производительность**: draw_glyph простая, без буферизации.
Для скроллинга — memcpy всего framebuffer.
## Зависимости
- `KERNEL_FONT: &[u8]` — встроен в main.rs через `include_bytes!("font.psf")`.
- `limine::framebuffer::Framebuffer` — через HHDM отображённый framebuffer.