feat: capability start

This commit is contained in:
Faynot
2026-04-19 22:31:15 +03:00
parent 4a2094fb06
commit 745687b0fa
3 changed files with 114 additions and 20 deletions

View File

@@ -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(),
}
}
}

31
kernel/src/cap/mod.rs Normal file
View File

@@ -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<Capability>,
}
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)
}
}

View File

@@ -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::<PageTable>() };
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();
}