From a384ebec4fbbf7bbf25bce04e5ac8befbb12a59a Mon Sep 17 00:00:00 2001 From: August Date: Sun, 11 Oct 2026 21:55:45 -0400 Subject: [PATCH] Capability structure start --- docs/STATE_OF_DEVELOPMENT.md | 15 +++++++++- src/kernel/capability.rs | 57 ++++++++++++++++++++++++++++++++++++ src/kernel/main.rs | 1 + 3 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 src/kernel/capability.rs diff --git a/docs/STATE_OF_DEVELOPMENT.md b/docs/STATE_OF_DEVELOPMENT.md index 51619bd..d025873 100644 --- a/docs/STATE_OF_DEVELOPMENT.md +++ b/docs/STATE_OF_DEVELOPMENT.md @@ -18,4 +18,17 @@ The next issue to work on will be paging and memory allocation. I need to allocate memory to load and start the initial process, and to do that, I need to finalize how I want process page mappings to be stored. It has to align with Gila's capability model. After that, I can write some basic -syscalls, and compile a very minimal binary to test running processes. \ No newline at end of file +syscalls, and compile a very minimal binary to test running processes. + +## 2026-10-11: Capability Data Structures + +Starting to design the shape of capability structures. Using a doubly linked +list allows easy tracking of derived capabilities, but presents ownership +issues. I can't think of anything smarter than using raw addresses to denote +where capabilities are, so those are used as our references. We use null +checking and convert these pointers into `Option<&mut Capability>` whenever +possible to uphold safety. + +The capability's fields allow a hierarchical structure for components and +capabilities, and in the future, user processes can create capabilities to +resources that aren't managed by the kernel. \ No newline at end of file diff --git a/src/kernel/capability.rs b/src/kernel/capability.rs new file mode 100644 index 0000000..d91243d --- /dev/null +++ b/src/kernel/capability.rs @@ -0,0 +1,57 @@ +#![allow(dead_code)] + +#[repr(C, packed)] +pub struct Capability<'a> { + component: u16, // Issuing component ID, 0.25 bytes + resource: u16, // Resource type, 0.25 bytes + instance: u64, // Instance ID, 1 byte + rights: u32, // Access rights, 0.5 bytes + child: *mut Capability<'a>, // Derived capability, 1 byte + parent: *mut Capability<'a>, // Parent capability, 1 byte +} + +pub struct CapabilityBlock<'a> { + caps: [Capability<'a>; 1024], +} + +impl<'a> Capability<'a> { + fn null() -> Capability<'a> { + Capability { + component: 0, + resource: 0, + instance: 0, + rights: 0, + child: core::ptr::null_mut(), + parent: core::ptr::null_mut(), + } + } + + fn child(&self) -> Option<&'a Capability<'a>> { + unsafe { self.child.as_ref() } + } + + fn child_mut(&mut self) -> Option<&'a mut Capability<'a>> { + unsafe { self.child.as_mut() } + } + + fn delete_child(&mut self) { + if let Some(child) = self.child_mut() { + match child.child_mut() { + // Current child has no children. Null it and gorget it + None => { + let _ = core::mem::replace(child, Capability::null()); + self.child = core::ptr::null_mut(); + } + // Current child has children. Delegate their deletion to the child + Some(other_child) => other_child.delete_child(), + } + } + } + + pub fn revoke(&mut self) { + match self.child() { + None => {} + Some(_c) => {} + } + } +} diff --git a/src/kernel/main.rs b/src/kernel/main.rs index e20badc..e896029 100644 --- a/src/kernel/main.rs +++ b/src/kernel/main.rs @@ -7,6 +7,7 @@ mod arch; mod boot; +mod capability; mod constants; mod interrupt; #[macro_use]