99 lines
4.9 KiB
Markdown
99 lines
4.9 KiB
Markdown
# Точка входа: `src/main.rs`
|
||
|
||
Точка входа ядра (`kmain`). Инициализирует оборудование, подсистемы памяти, запускает тесты capability и PMActor.
|
||
|
||
## Атрибуты крейта
|
||
|
||
```rust
|
||
#![no_std] // без стандартной библиотеки
|
||
#![no_main] // без точки входа из libc
|
||
extern crate alloc; // аллокатор кучи
|
||
```
|
||
|
||
## Константы
|
||
|
||
- `KERNEL_FONT: &[u8]` — встроенный PSF2 шрифт 8×16 на 512 глифов (включён через `include_bytes!("font.psf")`)
|
||
|
||
## Limine Boot Protocol Request
|
||
|
||
Статические переменные в секции `.requests` (через `#[unsafe(link_section = ".requests")]`):
|
||
|
||
| Переменная | Тип | Назначение |
|
||
|---|---|---|
|
||
| `MEMORY_MAP_REQUEST` | `MemoryMapRequest` | Карта физической памяти |
|
||
| `HHDM_REQUEST` | `HhdmRequest` | Higher Half Direct Map offset |
|
||
| `KERNEL_ADDR_REQUEST` | `ExecutableAddressRequest` | Базовые адреса ядра (physical + virtual) |
|
||
| `BASE_REVISION` | `BaseRevision` | Проверка версии Limine |
|
||
| `FRAMEBUFFER_REQUEST` | `FramebufferRequest` | Линейный фреймбуфер |
|
||
| `_START_MARKER` | `RequestsStartMarker` | Маркер начала секции requests |
|
||
| `_END_MARKER` | `RequestsEndMarker` | Маркер конца секции requests |
|
||
|
||
---
|
||
|
||
## `FramebufferDisplay<'a>`
|
||
|
||
Низкоуровневый рендерер пикселей, обёртка над `limine::framebuffer::Framebuffer`.
|
||
|
||
**impl `DrawTarget` (embedded_graphics):**
|
||
- `Color = Rgb888`, `Error = Infallible`
|
||
- `draw_iter(pixels)` — запись пикселей в память фреймбуфера с проверкой границ
|
||
|
||
**impl `OriginDimensions`:**
|
||
- `size()` — размеры фреймбуфера
|
||
|
||
---
|
||
|
||
## `Console<'a>` (встроенный, НЕ используется)
|
||
|
||
Обёртка над FramebufferDisplay. **В `kmain` используется `tty::Console`**, этот — мёртвый код.
|
||
|
||
Поля: `display`, `x`, `y`, `current_color`.
|
||
Методы: `new()`, `set_color()`, `clear()`, `scroll()`, `write_str()`.
|
||
|
||
---
|
||
|
||
## `kmain()` — точка входа
|
||
|
||
`unsafe extern "C" fn() -> !`
|
||
|
||
1. **Проверка `BASE_REVISION.is_supported()`** — убеждается, что загрузчик поддерживает нужную версию Limine
|
||
2. **Получение ответов Limine**: фреймбуфер, карта памяти, HHDM offset, адреса ядра
|
||
3. **Инициализация `tty::Console`** — создаёт консоль на первом фреймбуфере, чистит экран
|
||
4. **Инициализация Serial** — `debug::serial::init_global()` для отладки через COM1
|
||
5. **Вывод "BOOT"** через `info!` макрос
|
||
6. **Инициализация BitmapPMM** — из карты памяти и HHDM смещения
|
||
7. **Инициализация LAPIC** — `cpu::lapic::init(hhdm_offset)` для MMIO доступа к Local APIC
|
||
8. **Создание P4 (PML4)** — выделяет фрейм, зануляет его
|
||
9. **Картирование HHDM** — все non-reserved entry памяти маппятся identity + HHDM
|
||
10. **Картирование .text секции ядра** — по виртуальному базовому адресу
|
||
11. **Активация страничных таблиц** — `p4.activate(p4_phys)` — запись CR3
|
||
12. **Выделение кучи 8 MiB** — постранично маппится в `0xFFFF_9000_0000_0000`
|
||
13. **Инициализация SlabAllocator** — `ALLOCATOR.init()` с диапазоном кучи
|
||
14. **`init_cpu_features()`** — обнаружение INVPCID инструкции
|
||
15. **Регистрация адресного пространства ядра** — `vmm::init_kernel_space()`
|
||
16. **Инициализация IDT** — регистрация обработчиков page fault и TLB shootdown
|
||
17. **Инициализация PMRouter** — 65536 каналов маршрутизации
|
||
18. **Включение прерываний** — `sti` инструкция
|
||
19. **Тест capability системы**: создание CNode, insert/mint/revoke
|
||
20. **PMActor + Buddy тест** (строки 257-359): создание актора, аллокация, OOM, carve, free+coalescing
|
||
21. **Вывод ASCII-арт логотипа**
|
||
22. **Бесконечный HLT** — `hcf()`
|
||
|
||
---
|
||
|
||
## `hcf()`
|
||
|
||
```rust
|
||
fn hcf() -> ! {
|
||
loop { x86_64::instructions::hlt(); }
|
||
}
|
||
```
|
||
|
||
Бесконечный цикл HLT — снижает энергопотребление, процессор ждёт следующего прерывания.
|
||
|
||
---
|
||
|
||
## `rust_panic(info: &PanicInfo) -> !`
|
||
|
||
Обработчик паники: пишет информацию в serial, затем вызывает `hcf()`.
|