This repository has been archived on 2026-09-02. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
opencoreRS/kernel/src/ipc/capability.rs
T

134 lines
4.4 KiB
Rust

//! Capability System.
//!
//! Capability — это токен (unforgeable token), дающий право на определённую
//! операцию над определённым объектом ядра.
use alloc::vec::Vec;
use bitflags::bitflags;
use core::sync::atomic::{AtomicU64, Ordering};
bitflags! {
/// Набор прав, которые даёт capability.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Rights: u32 {
/// Право на чтение (read / receive).
const READ = 1 << 0;
/// Право на запись (write / send).
const WRITE = 1 << 1;
/// Право на передачу capability другому процессу.
const GRANT = 1 << 2;
/// Право маппировать память объекта в адресное пространство.
const MAP = 1 << 3;
/// Право управлять объектом (изменять параметры).
const MANAGE = 1 << 4;
/// Полный набор прав.
const ALL = Self::READ.bits() | Self::WRITE.bits()
| Self::GRANT.bits() | Self::MAP.bits()
| Self::MANAGE.bits();
}
}
/// Тип объекта ядра, на который ссылается capability.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum KernelObject {
/// Канал IPC (для обмена сообщениями).
Channel(u64),
/// Регион физической памяти.
MemoryObject { phys: u64, size: usize },
/// Прерывание (IRQ).
Interrupt(u8),
/// Поток выполнения.
Thread(u64),
/// Адресное пространство (процесс).
AddressSpace(u64),
}
/// Capability — токен доступа к объекту ядра.
#[derive(Debug, Clone, Copy)]
pub struct Capability {
/// Уникальный идентификатор capability.
pub id: u64,
/// Набор прав.
pub rights: Rights,
/// Объект, к которому даётся доступ.
pub object: KernelObject,
}
static CAP_ID_COUNTER: AtomicU64 = AtomicU64::new(1);
impl Capability {
/// Создать capability с полными правами (только ядро).
pub fn new_full(object: KernelObject) -> Self {
let id = CAP_ID_COUNTER.fetch_add(1, Ordering::Relaxed);
Capability { id, rights: Rights::ALL, object }
}
/// Создать capability с заданными правами.
pub fn new(rights: Rights, object: KernelObject) -> Self {
let id = CAP_ID_COUNTER.fetch_add(1, Ordering::Relaxed);
Capability { id, rights, object }
}
/// Проверить наличие права.
pub fn has(&self, right: Rights) -> bool {
self.rights.contains(right)
}
/// Создать производный capability с урезанными правами.
pub fn derive(&self, restrict_to: Rights) -> Option<Capability> {
if !self.has(Rights::GRANT) {
return None;
}
let id = CAP_ID_COUNTER.fetch_add(1, Ordering::Relaxed);
Some(Capability {
id,
rights: self.rights & restrict_to,
object: self.object,
})
}
}
/// Таблица capabilities процесса.
#[derive(Debug, Clone)]
pub struct CapabilityTable {
entries: Vec<Option<Capability>>,
}
impl CapabilityTable {
pub fn new() -> Self {
CapabilityTable {
entries: Vec::new(),
}
}
/// Получить capability по индексу.
pub fn get(&self, index: usize) -> Option<&Capability> {
self.entries.get(index).and_then(|opt| opt.as_ref())
}
/// Добавить capability, вернуть индекс в таблице.
pub fn insert(&mut self, cap: Capability) -> usize {
for (i, entry) in self.entries.iter_mut().enumerate() {
if entry.is_none() {
*entry = Some(cap);
return i;
}
}
let idx = self.entries.len();
self.entries.push(Some(cap));
idx
}
/// Отозвать capability по индексу.
pub fn revoke(&mut self, index: usize) -> bool {
if let Some(entry) = self.entries.get_mut(index) {
if entry.is_some() {
*entry = None;
return true;
}
}
false
}
}