feat: docs & ARCH 2.2, 2.3, 2.4
This commit is contained in:
152
kernel/docs/boot/introduction.md
Normal file
152
kernel/docs/boot/introduction.md
Normal 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)
|
||||
```
|
||||
Reference in New Issue
Block a user