From 745687b0fa17ebb4b0782a829a003d39780e0a73 Mon Sep 17 00:00:00 2001 From: Faynot Date: Sun, 19 Apr 2026 22:31:15 +0300 Subject: [PATCH] feat: capability start --- kernel/src/cap/descriptor.rs | 36 +++++++++++++++++++ kernel/src/cap/mod.rs | 31 +++++++++++++++++ kernel/src/main.rs | 67 +++++++++++++++++++++++++----------- 3 files changed, 114 insertions(+), 20 deletions(-) create mode 100644 kernel/src/cap/descriptor.rs create mode 100644 kernel/src/cap/mod.rs diff --git a/kernel/src/cap/descriptor.rs b/kernel/src/cap/descriptor.rs new file mode 100644 index 0000000..2cab17e --- /dev/null +++ b/kernel/src/cap/descriptor.rs @@ -0,0 +1,36 @@ +// src/cap/descriptor.rs +use crate::mem::address::PhysAddr; + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum CapObject { + Empty, + Memory { frame: PhysAddr, size: usize }, + Thread { id: u64 }, + CNode { frame: PhysAddr, size: usize }, // Капа на таблицу других кап + Endpoint { id: u64 }, // Для IPC +} + +bitflags::bitflags! { + #[derive(Debug, Clone, Copy, PartialEq, Eq)] + pub struct CapRights: u8 { + const READ = 1 << 0; + const WRITE = 1 << 1; + const EXECUTE = 1 << 2; + const GRANT = 1 << 3; // Право передавать эту капу дальше + } +} + +#[derive(Debug, Clone, Copy)] +pub struct Capability { + pub object: CapObject, + pub rights: CapRights, +} + +impl Capability { + pub const fn empty() -> Self { + Self { + object: CapObject::Empty, + rights: CapRights::empty(), + } + } +} diff --git a/kernel/src/cap/mod.rs b/kernel/src/cap/mod.rs new file mode 100644 index 0000000..2f7c823 --- /dev/null +++ b/kernel/src/cap/mod.rs @@ -0,0 +1,31 @@ +// src/cap/mod.rs +pub mod descriptor; + +use alloc::vec::Vec; +pub use descriptor::{Capability, CapObject, CapRights}; + +/// CNode — это таблица возможностей. +/// Дескриптор (u64) — это просто индекс в этом векторе. +pub struct CNode { + caps: Vec, +} + +impl CNode { + pub fn new(size: usize) -> Self { + let mut caps = Vec::with_capacity(size); + for _ in 0..size { + caps.push(Capability::empty()); + } + Self { caps } + } + + pub fn insert(&mut self, slot: usize, cap: Capability) -> Result<(), &'static str> { + if slot >= self.caps.len() { return Err("Index out of bounds"); } + self.caps[slot] = cap; + Ok(()) + } + + pub fn get(&self, slot: usize) -> Option<&Capability> { + self.caps.get(slot) + } +} diff --git a/kernel/src/main.rs b/kernel/src/main.rs index cb67368..4c521b8 100644 --- a/kernel/src/main.rs +++ b/kernel/src/main.rs @@ -13,6 +13,7 @@ use limine::request::{FramebufferRequest, RequestsEndMarker, RequestsStartMarker use crate::mem::paging::{PageTable, PageTableFlags}; use crate::mem::address::{PhysAddr, VirtAddr}; +pub mod cap; mod mem; #[macro_use] pub mod debug; @@ -173,45 +174,34 @@ unsafe extern "C" fn kmain() -> ! { info!(console, "BOOT", "RINA Kernel Starting..."); - // Initialize Physical Memory Manager + // 1. Инициализация PMM unsafe { mem::pmm::BitmapPMM::init(&mmap_res, hhdm_offset); } info!(console, "MEM", "Physical Memory Manager initialized."); - // Prepare Kernel Page Tables (P4) + // 2. Инициализация страничного управления let p4_phys = mem::pmm::alloc_page().expect("OOM: Failed to allocate P4 table"); let p4 = unsafe { &mut *p4_phys.to_virt(hhdm_offset).as_mut_ptr::() }; unsafe { core::ptr::write_bytes(p4 as *mut _ as *mut u8, 0, 4096); } let flags = PageTableFlags::PRESENT | PageTableFlags::WRITABLE; - // Mapping Strategy: HHDM + Identity Mapping for active segments for entry in mmap_res.entries() { let phys = PhysAddr(entry.base); let virt_hhdm = phys.to_virt(hhdm_offset); - p4.map_region(virt_hhdm, phys, entry.length, flags, hhdm_offset); - if entry.entry_type != limine::memory_map::EntryType::RESERVED { p4.map_region(VirtAddr(entry.base), phys, entry.length, flags, hhdm_offset); } } - // Map the kernel itself based on provided executable addresses - p4.map_region( - VirtAddr(kaddr_res.virtual_base()), - PhysAddr(kaddr_res.physical_base()), - 0x1000 * 1024, // 4MB default - flags, - hhdm_offset - ); + p4.map_region(VirtAddr(kaddr_res.virtual_base()), PhysAddr(kaddr_res.physical_base()), 0x1000 * 1024, flags, hhdm_offset); info!(console, "MMU", "Switching to Kernel Page Tables..."); unsafe { p4.activate(p4_phys); } - // Initialize Global Heap + // 3. Инициализация Кучи let heap_start = 0xFFFF_9000_0000_0000; let heap_size = 8 * 1024 * 1024; - for i in (0..heap_size).step_by(4096) { let frame = mem::pmm::alloc_page().expect("OOM: Heap allocation failed"); p4.map_page(VirtAddr(heap_start + i as u64), frame, flags, hhdm_offset); @@ -221,13 +211,50 @@ unsafe extern "C" fn kmain() -> ! { let mut allocator = allocator::ALLOCATOR.lock(); allocator.init(heap_start as usize, heap_size); } - info!(console, "HEAP", "Global Allocator is online."); - // Integrity Test - let mut test_vec = Vec::new(); - test_vec.push(42); - info!(console, "CORE", "Vec test passed. Pointer: {:?}", test_vec.as_ptr()); + // --- Инициализация Модели Capabilities --- + + // Создаем корневой CNode для ядра на 256 слотов + let mut root_cnode = cap::CNode::new(256); + + // Пример: Превращаем физическую страницу в Capability "Memory" + if let Some(frame) = mem::pmm::alloc_page() { + let mem_cap = cap::Capability { + object: cap::CapObject::Memory { frame, size: 4096 }, + rights: cap::CapRights::READ | cap::CapRights::WRITE, + }; + + // Помещаем в слот 0. Теперь "Дескриптор 0" — это право доступа к этой памяти. + root_cnode.insert(0, mem_cap).unwrap(); + info!(console, "CAP", "Created memory capability at slot 0"); + } + + // Проверка + if let Some(c) = root_cnode.get(0) { + info!(console, "CAP", "Slot 0 verification: {:?}", c.object); + } + + let logo = r#" + ########### + ################## + ###### ###### + ##### ##### + #### ##### #### + #### ### ###### #### + #### #### #### #### + #### #### ### #### + #### ### ## ### #### + #### ######## #### #### + #### #### #### #### + #### ###### ### #### + #### ####### #### + ##### ##### + ###### ###### + ################## + ############ +"#; + let _ = writeln!(console, "{}", logo); hcf(); }