feat: docs & ARCH 2.2, 2.3, 2.4
This commit is contained in:
103
kernel/docs/memory/address-translation.md
Normal file
103
kernel/docs/memory/address-translation.md
Normal file
@@ -0,0 +1,103 @@
|
||||
# Адресация и трансляция: `address.rs`
|
||||
|
||||
## Концептуальная модель
|
||||
|
||||
В x86-64 MMU транслирует виртуальные адреса (48 бит, канонические)
|
||||
в физические (до 52 бит) через 4-уровневую иерархию page tables.
|
||||
|
||||
Ядро использует **Higher-Half Direct Map (HHDM)** — область виртуальной
|
||||
памяти, где вся физическая память отображена 1:1 с фиксированным смещением.
|
||||
|
||||
```
|
||||
Физический адрес 0x0
|
||||
│
|
||||
│ + HHDM_OFFSET (например, 0xFFFF8000_0000_0000)
|
||||
▼
|
||||
Виртуальный адрес 0xFFFF8000_0000_0000
|
||||
```
|
||||
|
||||
## Физический адрес: `PhysAddr(pub u64)`
|
||||
|
||||
Представляет собой физический адрес. Это **newtype** над `u64` — строгая
|
||||
типизация предотвращает случайное смешивание физических и виртуальных адресов.
|
||||
|
||||
**Методы:**
|
||||
- `to_virt()` — преобразует в виртуальный адрес через HHDM:
|
||||
`VirtAddr(self.0 + HHDM_OFFSET)`
|
||||
- `is_aligned()` — проверка выравнивания на 4KiB
|
||||
- `align_down()` / `align_up()` — выравнивание вниз/вверх до границы 4KiB
|
||||
|
||||
## Виртуальный адрес: `VirtAddr(pub u64)`
|
||||
|
||||
**Методы:**
|
||||
- `to_phys()` — обратное преобразование: вычитает HHDM, возвращает `None`
|
||||
если адрес ниже HHDM (не канонический для физической памяти)
|
||||
- `as_ptr<T>()` — получить `*const T` (для чтения)
|
||||
- `as_mut_ptr<T>()` — получить `*mut T` (для записи)
|
||||
|
||||
## HHDM Offset: глобальное состояние
|
||||
|
||||
```rust
|
||||
static HHDM_OFFSET: AtomicU64 = AtomicU64::new(0);
|
||||
```
|
||||
|
||||
- `init_hhdm(offset: u64)` — вызывается в `kmain()` сразу после получения
|
||||
ответа от bootloader'а. Сохраняет offset через `Ordering::Release`.
|
||||
- `get_hhdm() -> u64` — читает offset через `Ordering::Relaxed` (высокая
|
||||
производительность, на этой архитектуре атомарность гарантирована).
|
||||
|
||||
### Почему Atomic?
|
||||
|
||||
HHDM инициализируется однократно до включения прерываний и создания
|
||||
дополнительных потоков. Atomic гарантирует, что даже если в будущем
|
||||
инструкции будут переупорядочены, значение будет видно всем ядрам.
|
||||
|
||||
## Код и абстракция
|
||||
|
||||
```rust
|
||||
// address.rs (полный код)
|
||||
static HHDM_OFFSET: AtomicU64 = AtomicU64::new(0);
|
||||
|
||||
pub fn init_hhdm(offset: u64) {
|
||||
HHDM_OFFSET.store(offset, Ordering::Release);
|
||||
// ^ Release: все предыдущие записи становятся видимы для
|
||||
// всех acquire-операций на HHDM_OFFSET
|
||||
}
|
||||
|
||||
pub fn get_hhdm() -> u64 {
|
||||
HHDM_OFFSET.load(Ordering::Relaxed)
|
||||
// ^ Relaxed: в однопоточном контексте и при инициализации
|
||||
// до включения прерываний это безопасно и максимально быстро
|
||||
}
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct PhysAddr(pub u64);
|
||||
// ^ repr(transparent): гарантирует, что PhysAddr имеет то же
|
||||
// представление в памяти, что и u64 — важно для FFI и передачи
|
||||
// в ассемблерные инструкции (mov cr3, rax)
|
||||
|
||||
impl PhysAddr {
|
||||
pub fn to_virt(self) -> VirtAddr {
|
||||
VirtAddr(self.0 + get_hhdm())
|
||||
// ^ Концептуально: физический адрес + HHDM смещение даёт
|
||||
// виртуальный адрес, по которому этот физический фрейм
|
||||
// отображён в higher half
|
||||
}
|
||||
}
|
||||
|
||||
impl VirtAddr {
|
||||
pub fn as_mut_ptr<T>(self) -> *mut T {
|
||||
self.0 as *mut T
|
||||
// ^ Прямая интерпретация числа как указателя.
|
||||
// Безопасность на стороне вызывающего кода.
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Где используется
|
||||
|
||||
- `PhysAddr::to_virt()` — в `paging.rs` для доступа к Page Table entries,
|
||||
в `pmm.rs` для обнуления фреймов, в `buddy.rs` для intrusive list.
|
||||
- `VirtAddr::as_mut_ptr()` — в `paging.rs` для создания ссылок на PTE.
|
||||
- `init_hhdm()` — в `kmain()` при старте.
|
||||
- `get_hhdm()` — в `lapic.rs` для вычисления LAPIC_base.
|
||||
Reference in New Issue
Block a user