fix: bugs
This commit is contained in:
147
kernel/docs/capabilities.md
Normal file
147
kernel/docs/capabilities.md
Normal file
@@ -0,0 +1,147 @@
|
||||
# Система 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.
|
||||
Reference in New Issue
Block a user