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

View File

@@ -0,0 +1,152 @@
# Процесс загрузки: концептуальная модель
## Цепочка загрузки
```
Питание включено
CPU reset vector (0xFFFFFFF0)
UEFI firmware / BIOS
Limine bootloader ─────────────────────────────┐
│ │
│ 1. Переводит CPU в 64-bit long mode │
│ 2. Настраивает page tables (identity map) │
│ 3. Загружает ядро по физическому адресу │
│ 4. Настраивает HHDM │
│ 5. Заполняет Limine requests │
│ 6. Передаёт управление на kmain │
│ │
▼ │
kmain() (точка входа) │
│ │
... инициализация ... │
│ │
▼ │
HCF (останов CPU) ─────────────────────────────┘
```
## Limine Boot Protocol
Elyz использует [Limine](https://github.com/limine-bootloader/limine) —
современный bootloader с открытым исходным кодом.
Статические `Limine requests` сообщают bootloader'у, что нужно ядру:
| Request | Назначение |
|---------|------------|
| `FramebufferRequest` | Получить framebuffer для графического вывода |
| `MemoryMapRequest` | Получить карту физической памяти |
| `HhdmRequest` | Получить HHDM offset |
| `ExecutableAddressRequest` | Получить физический/виртуальный адрес ядра |
| `BaseRevision` | Проверить совместимость с Limine |
### Размещение в секциях
Requests размещаются между специальными маркерами в секции `.data`:
```rust
#[used]
#[unsafe(link_section = ".requests_start_marker")]
static _START_MARKER: RequestsStartMarker = RequestsStartMarker::new();
// ... все requests ...
#[used]
#[unsafe(link_section = ".requests_end_marker")]
static _END_MARKER: RequestsEndMarker = RequestsEndMarker::new();
```
Линкер скрипт сохраняет эти секции:
```ld
.data : {
*(.data .data.*)
KEEP(*(.requests_start_marker))
KEEP(*(.requests))
KEEP(*(.requests_end_marker))
} :data
```
## Точка входа — kmain
Линкер скрипт: `ENTRY(kmain)`.
```rust
#[unsafe(no_mangle)]
unsafe extern "C" fn kmain() -> ! { ... }
```
Атрибуты:
- `no_mangle` — сохраняет имя `kmain` (линкер ищет именно его).
- `extern "C"` — C ABI (Linux x86-64 calling convention: RDI, RSI, ...).
- `unsafe` — на этапе инициализации все операции потенциально опасны.
- `-> !` — kmain никогда не возвращается (HALT).
## Build system
### GNUmakefile
```makefile
KARCH ?= x86_64
RUST_TARGET ?= $(KARCH)-unknown-none
RUST_PROFILE ?= dev
all:
RUSTFLAGS="-C relocation-model=static" \
cargo build --target $(RUST_TARGET) --profile $(RUST_PROFILE)
cp target/$(RUST_TARGET)/$(RUST_PROFILE_SUBDIR)/kernel .
```
- `relocation-model=static`: ядро не использует динамическую перелокацию.
- `--target x86_64-unknown-none`: bare-metal target (без ОС).
- Результат копируется в `kernel/` (корень).
### build.rs — linker script
```rust
fn main() {
let arch = std::env::var("CARGO_CFG_TARGET_ARCH").unwrap();
println!("cargo:rustc-link-arg=-Tlinker-{arch}.ld");
println!("cargo:rerun-if-changed=linker-{arch}.ld");
}
```
Подставляет правильный linker script для архитектуры.
### rust-toolchain.toml
```toml
[toolchain]
channel = "nightly"
targets = ["x86_64-unknown-none"]
```
Требуется nightly Rust из-за:
- `#![no_std]`, `#![no_main]`.
- `core::arch::global_asm!`, `core::arch::asm!`.
- `const { ... }` в инициализации констант.
## Память: расположение после загрузки
```
Физическая память:
┌───────────────────────┐ 0x0
│ Reserved │
├───────────────────────┤
│ Usable (free) │ ← входит в mmap entries
├───────────────────────┤
│ Kernel image │ ← загружен Limine
├───────────────────────┤
│ PMM metadata │ ← bitmap + ref_counts + L1
├───────────────────────┤
│ ... (usable) │
└───────────────────────┘ max_addr
Виртуальная память (Higher Half):
0xFFFF_8000_0000_0000 ─── HHDM (вся физическая память 1:1)
0xFFFF_9000_0000_0000 ─── Kernel heap (8 MiB)
```