148 lines
4.4 KiB
Markdown
148 lines
4.4 KiB
Markdown
# Система Capability
|
||
|
||
---
|
||
|
||
## Дескрипторы Capability
|
||
|
||
**Файл**: `src/cap/descriptor.rs`
|
||
|
||
### Relation
|
||
|
||
```rust
|
||
pub enum Relation {
|
||
Strong, // владение (исключительный доступ)
|
||
Borrow, // заимствование (временный доступ)
|
||
Transfer, // передача (владение перешло)
|
||
}
|
||
```
|
||
|
||
### CapObject
|
||
|
||
```rust
|
||
pub enum CapObject {
|
||
Empty, // null (слот свободен)
|
||
Memory { phys: PhysAddr, size_pages: usize }, // регион физической памяти
|
||
CNode { phys: PhysAddr, slots: usize }, // узел capability (таблица)
|
||
PMActor { id: u64 }, // ссылка на PMActor
|
||
}
|
||
```
|
||
|
||
### CapRights (bitflags, u8)
|
||
|
||
```rust
|
||
READ = 1 << 0
|
||
WRITE = 1 << 1
|
||
EXECUTE = 1 << 2
|
||
GRANT = 1 << 3 // разрешение на mint (порождение потомков)
|
||
```
|
||
|
||
### Capability
|
||
|
||
```rust
|
||
pub struct Capability {
|
||
pub object: CapObject, // ссылка на объект
|
||
pub rights: CapRights, // права доступа
|
||
pub relation: Relation, // тип отношений
|
||
pub token_sig: u64, // уникальный токен для отзыва (MMU)
|
||
}
|
||
```
|
||
|
||
- `empty()` — возвращает Capability с `CapObject::Empty`
|
||
- `is_valid() -> bool` — `object != Empty`
|
||
|
||
---
|
||
|
||
## Объекты ядра
|
||
|
||
**Файл**: `src/cap/object.rs`
|
||
|
||
### ObjectType
|
||
|
||
```rust
|
||
pub enum ObjectType {
|
||
Untyped, // сырая нетипизированная память
|
||
Frame, // выделенный физический фрейм
|
||
CNode, // узел capability
|
||
ThreadBlock, // блок управления потоком
|
||
PageTable, // страница таблицы
|
||
}
|
||
```
|
||
|
||
### KernelObject
|
||
|
||
```rust
|
||
pub struct KernelObject {
|
||
pub phys_addr: PhysAddr,
|
||
pub size_bits: u8, // размер как степень двойки
|
||
pub obj_type: ObjectType,
|
||
pub ref_count: AtomicUsize, // атомарный счётчик ссылок
|
||
pub owner_id: u64, // ID владельца
|
||
}
|
||
```
|
||
|
||
- `add_ref()` — atomic increment (Relaxed ordering)
|
||
- `release() -> bool` — atomic decrement (Release). Возвращает true, если счётчик достиг 0
|
||
|
||
---
|
||
|
||
## CNode
|
||
|
||
**Файл**: `src/cap/mod.rs`
|
||
|
||
Узел capability, хранит массив слотов с индивидуальной блокировкой.
|
||
|
||
### CNodeSlot
|
||
|
||
```rust
|
||
struct CNodeSlot {
|
||
cap: Capability,
|
||
parent_idx: Option<usize>, // индекс родителя (для дерева) — None у корневых
|
||
}
|
||
```
|
||
|
||
### CNode
|
||
|
||
```rust
|
||
pub struct CNode {
|
||
slots: Vec<Locked<CNodeSlot>>,
|
||
}
|
||
```
|
||
|
||
### `new(size) -> Self`
|
||
|
||
Создаёт `size` пустых слотов с `parent_idx = None`.
|
||
|
||
### `insert(slot, cap) -> Result<(), &str>`
|
||
|
||
Проверка границ, сохранение Capability в слоте.
|
||
|
||
### `mint(src, dest, relation, rights) -> Result<(), &str>`
|
||
|
||
**Порождение дочерней capability с урезанными правами:**
|
||
|
||
1. **Lock ordering**: блокировка слотов по возрастанию индекса (deadlock prevention)
|
||
2. Source-слот не пуст, имеет GRANT право
|
||
3. `child_rights = parent_rights & requested_rights` — дочерние права не могут превышать родительские
|
||
4. Копирует Capability, устанавливает новые права, relation, `parent_idx`
|
||
5. Ошибка при `src == dest`
|
||
|
||
### `revoke(slot_idx) -> Result<(), &str>`
|
||
|
||
**Каскадный отзыв с уведомлением VMM:**
|
||
|
||
1. `revoke_internal(slot_idx)` — рекурсивно находит и уничтожает всех потомков
|
||
2. Уничтожает саму Capability в слоте (Empty)
|
||
3. Пушит `token_sig` в `MMU_REVOCATION_QUEUE` (кроме 0 и `0xDEAD_BEEF`)
|
||
4. **Паника** при переполнении очереди
|
||
|
||
### `revoke_internal(slot_idx)`
|
||
|
||
Приватная рекурсия:
|
||
1. Сканирует все слоты в поисках `parent_idx == slot_idx`
|
||
2. Для каждого потомка: рекурсивный вызов
|
||
3. Затем уничтожает свой слот (Empty)
|
||
|
||
### `get_cap(slot) -> Option<Capability>`
|
||
|
||
Возвращает копию Capability.
|