4.4 KiB
4.4 KiB
Система Capability
Дескрипторы Capability
Файл: src/cap/descriptor.rs
Relation
pub enum Relation {
Strong, // владение (исключительный доступ)
Borrow, // заимствование (временный доступ)
Transfer, // передача (владение перешло)
}
CapObject
pub enum CapObject {
Empty, // null (слот свободен)
Memory { phys: PhysAddr, size_pages: usize }, // регион физической памяти
CNode { phys: PhysAddr, slots: usize }, // узел capability (таблица)
PMActor { id: u64 }, // ссылка на PMActor
}
CapRights (bitflags, u8)
READ = 1 << 0
WRITE = 1 << 1
EXECUTE = 1 << 2
GRANT = 1 << 3 // разрешение на mint (порождение потомков)
Capability
pub struct Capability {
pub object: CapObject, // ссылка на объект
pub rights: CapRights, // права доступа
pub relation: Relation, // тип отношений
pub token_sig: u64, // уникальный токен для отзыва (MMU)
}
empty()— возвращает Capability сCapObject::Emptyis_valid() -> bool—object != Empty
Объекты ядра
Файл: src/cap/object.rs
ObjectType
pub enum ObjectType {
Untyped, // сырая нетипизированная память
Frame, // выделенный физический фрейм
CNode, // узел capability
ThreadBlock, // блок управления потоком
PageTable, // страница таблицы
}
KernelObject
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
struct CNodeSlot {
cap: Capability,
parent_idx: Option<usize>, // индекс родителя (для дерева) — None у корневых
}
CNode
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 с урезанными правами:
- Lock ordering: блокировка слотов по возрастанию индекса (deadlock prevention)
- Source-слот не пуст, имеет GRANT право
child_rights = parent_rights & requested_rights— дочерние права не могут превышать родительские- Копирует Capability, устанавливает новые права, relation,
parent_idx - Ошибка при
src == dest
revoke(slot_idx) -> Result<(), &str>
Каскадный отзыв с уведомлением VMM:
revoke_internal(slot_idx)— рекурсивно находит и уничтожает всех потомков- Уничтожает саму Capability в слоте (Empty)
- Пушит
token_sigвMMU_REVOCATION_QUEUE(кроме 0 и0xDEAD_BEEF) - Паника при переполнении очереди
revoke_internal(slot_idx)
Приватная рекурсия:
- Сканирует все слоты в поисках
parent_idx == slot_idx - Для каждого потомка: рекурсивный вызов
- Затем уничтожает свой слот (Empty)
get_cap(slot) -> Option<Capability>
Возвращает копию Capability.