Files
Elyz/kernel/docs/capabilities.md
2026-07-06 00:25:49 +03:00

4.4 KiB
Raw Blame History

Система 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::Empty
  • is_valid() -> boolobject != 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 с урезанными правами:

  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.