feat: docs & ARCH 2.2, 2.3, 2.4
This commit is contained in:
126
kernel/docs/capability/introduction.md
Normal file
126
kernel/docs/capability/introduction.md
Normal file
@@ -0,0 +1,126 @@
|
||||
# Capability-система: концептуальная модель
|
||||
|
||||
## Философия
|
||||
|
||||
**Capability** (дескриптор возможности) — это **неподделываемый токен**,
|
||||
дающий право выполнить определённую операцию над определённым объектом.
|
||||
|
||||
В традиционных ОС (Linux, Windows) доступ контролируется через:
|
||||
- PID + UID/GID + проверка при каждом системном вызове.
|
||||
- MMU: page tables определяют, что отображено, но не кто отобразил.
|
||||
|
||||
В модели capabilities:
|
||||
- **Если у вас нет capability — у вас нет доступа.**
|
||||
- Capability хранятся в CNode — защищённой таблице, доступной только ядру.
|
||||
- Capability можно создавать только от родительского capability
|
||||
(иерархия наследования).
|
||||
- Права можно только **урезать** (mint), но не расширить.
|
||||
- Capability можно **отозвать** (revoke), что уничтожает его
|
||||
и всех его потомков.
|
||||
|
||||
## Основные понятия
|
||||
|
||||
```
|
||||
Capability {
|
||||
object: CapObject, // на что указывает (Memory, CNode, PMActor...)
|
||||
rights: CapRights, // права (R, W, X, G)
|
||||
relation: Relation, // Strong (владеет), Borrow (заём), Transfer
|
||||
token_sig: u64, // уникальный идентификатор (для revoke)
|
||||
}
|
||||
|
||||
Relation {
|
||||
Strong: владеет объектом (capability владеет памятью)
|
||||
Borrow: заём — временный доступ без права распоряжаться
|
||||
Transfer: передача — владение переходит получателю
|
||||
}
|
||||
|
||||
CapRights {
|
||||
READ = 0x1,
|
||||
WRITE = 0x2,
|
||||
EXECUTE = 0x4,
|
||||
GRANT = 0x8, // разрешение создавать дочерние capability
|
||||
}
|
||||
```
|
||||
|
||||
## Иерархия и отзыв
|
||||
|
||||
```
|
||||
CNode (массив слотов)
|
||||
┌────────┬────────┬────────┬────────┐
|
||||
│ slot 0 │ slot 1 │ slot 2 │ slot 3 │ ...
|
||||
├────────┼────────┼────────┼────────┤
|
||||
│ cap │ cap │ cap │ cap │
|
||||
│ parent:│ parent:│ parent:│ parent:│
|
||||
│ None │ Some(0)│ Some(0)│ Some(1)│
|
||||
└────────┴────────┴────────┴────────┘
|
||||
│
|
||||
┌────────┴────────┐
|
||||
▼ ▼
|
||||
slot 1 slot 2
|
||||
(mint from 0) (mint from 0)
|
||||
|
||||
revoke(0) → slot 0 уничтожается
|
||||
→ рекурсивно: slot 1, slot 2 тоже уничтожаются
|
||||
→ token_sig slot 0 отправляется в MMU_REVOCATION_QUEUE
|
||||
→ VMM обработает отзыв при следующем page fault
|
||||
```
|
||||
|
||||
### Mint — создание дочернего capability
|
||||
|
||||
```rust
|
||||
cnode.mint(src, dest, relation, rights)
|
||||
```
|
||||
|
||||
- `src` — исходный слот (должен иметь GRANT).
|
||||
- `dest` — целевой слот (должен быть пустым).
|
||||
- `relation` — как наследник связан с родителем.
|
||||
- `rights` — права наследника (∩ с правами родителя).
|
||||
|
||||
### Revoke — отзыв capability
|
||||
|
||||
```rust
|
||||
cnode.revoke(slot_idx)
|
||||
```
|
||||
|
||||
1. Рекурсивно находит всех потомков и уничтожает их.
|
||||
2. Уничтожает сам capability.
|
||||
3. Отправляет `token_sig` в глобальную `MMU_REVOCATION_QUEUE`.
|
||||
4. VMM при следующем page fault обрабатывает все накопленные отзывы.
|
||||
|
||||
## Lock Ranking — предотвращение дедлоков
|
||||
|
||||
В `mint()` захватываются две блокировки (src и dest). Чтобы избежать
|
||||
инверсии блокировок, используется строгий порядок:
|
||||
|
||||
```rust
|
||||
let (src_slot, dest_slot) = if src < dest {
|
||||
// Захватываем меньший индекс первым
|
||||
_guard_low = self.slots[src].lock();
|
||||
_guard_high = self.slots[dest].lock();
|
||||
} else {
|
||||
_guard_low = self.slots[dest].lock();
|
||||
_guard_high = self.slots[src].lock();
|
||||
};
|
||||
```
|
||||
|
||||
## Интеграция с VMM
|
||||
|
||||
При отзыве capability, VMM должна аннулировать все VMA, связанные
|
||||
с отозванным токеном. Для этого:
|
||||
|
||||
1. `revoke()` пушит `token_sig` в lock-free очередь.
|
||||
2. При page fault: `process_pending_revocations()` дренирует очередь.
|
||||
3. VMA с `cap_token == token_sig` удаляются из AddressSpace.
|
||||
4. TLB flush для синхронизации MMU.
|
||||
|
||||
## Использование в kmain()
|
||||
|
||||
```rust
|
||||
let root_cnode = CNode::new(256);
|
||||
// Вставка capability на фрейм
|
||||
root_cnode.insert(0, mem_cap).unwrap();
|
||||
// Mint с урезанными правами
|
||||
root_cnode.mint(0, 10, Relation::Borrow, R | W).unwrap();
|
||||
// Revoke — отзыв всех потомков
|
||||
root_cnode.revoke(0);
|
||||
```
|
||||
Reference in New Issue
Block a user