# Система 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, // индекс родителя (для дерева) — None у корневых } ``` ### CNode ```rust pub struct CNode { slots: Vec>, } ``` ### `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.