feat(kernel): per-process budgets (pages, endpoints, notifs, regions) carved from creator, returned on death; init owns pool

This commit is contained in:
2026-10-27 15:08:58 +01:00
parent 7415bab7f5
commit 4049ba5007
46 changed files with 672 additions and 119 deletions

View File

@@ -7,6 +7,7 @@ mod selftest;
use types::address::{EntryPoint, StackPointer, VirtualAddress};
use types::bounded::{CapSlot, PageCount};
use types::budget::Limits;
use types::permission::{Permission, PermissionSet};
use libkos::fs::Storage;
use libkos::syscall;
@@ -42,7 +43,12 @@ pub(crate) struct LoadedProcess {
pub(crate) entry_point: EntryPoint,
}
pub(crate) fn load_binary(storage: &mut Storage, scratch: &mut [u8], filename: &[u8]) -> Option<LoadedProcess> {
pub(crate) fn load_binary(
storage: &mut Storage,
scratch: &mut [u8],
filename: &[u8],
limits: Limits,
) -> Option<LoadedProcess> {
let file_size = read_file(storage, scratch, filename)?;
let elf_data = &scratch[..file_size];
let elf_info = match elf::parse(elf_data) {
@@ -50,7 +56,7 @@ pub(crate) fn load_binary(storage: &mut Storage, scratch: &mut [u8], filename: &
Err(_) => return None,
};
let process_cap = syscall::create_process(CREATE_CAP)?;
let process_cap = syscall::create_process(CREATE_CAP, limits)?;
for segment in elf_info.segments() {
let page_start = segment.vaddr & !0xFFF;
@@ -102,14 +108,25 @@ pub(crate) fn load_binary(storage: &mut Storage, scratch: &mut [u8], filename: &
struct ServerInfo {
filename: &'static [u8],
name: &'static str,
limits: Limits,
}
/// Enough for a small program: its image, stack and a little heap.
pub(crate) const SMALL: Limits = Limits {
pages: 64,
endpoints: 2,
notifications: 2,
regions: 2,
};
const SERVERS: &[ServerInfo] = &[
ServerInfo { filename: b"log.elf", name: "log" },
ServerInfo { filename: b"permis.elf", name: "permis" },
ServerInfo { filename: b"session.elf", name: "session" },
ServerInfo { filename: b"log.elf", name: "log", limits: SMALL },
ServerInfo { filename: b"permis.elf", name: "permis", limits: SMALL },
ServerInfo { filename: b"session.elf", name: "session", limits: SMALL },
];
const SNAKE: Limits = Limits { pages: 128, ..SMALL };
pub fn run() -> ! {
libkos::start::set_console(devices::console());
libkos::println!("init: started (pid={:#x})", syscall::get_process_id().raw());
@@ -142,7 +159,7 @@ pub fn run() -> ! {
for server in SERVERS {
libkos::print!("init: loading {}... ", server.name);
let loaded = match load_binary(&mut storage, scratch, server.filename) {
let loaded = match load_binary(&mut storage, scratch, server.filename, server.limits) {
Some(l) => l,
None => {
libkos::println!("SKIP");
@@ -166,7 +183,7 @@ pub fn run() -> ! {
}
libkos::print!("init: loading snake... ");
if let Some(snake) = load_binary(&mut storage, scratch, b"snake.elf") {
if let Some(snake) = load_binary(&mut storage, scratch, b"snake.elf", SNAKE) {
// A client only calls: Execute, never Read, so it cannot pose as
// the server and take other clients' requests.
let client = PermissionSet::empty().with(Permission::Execute);

View File

@@ -40,7 +40,7 @@ fn start_spinner(storage: &mut Storage, scratch: &mut [u8], page: CapSlot) -> Re
for i in 0..=THREADS {
word(i).store(0, Ordering::SeqCst);
}
let spinner = crate::load_binary(storage, scratch, b"smptest.elf").ok_or("cannot load smptest.elf")?;
let spinner = crate::load_binary(storage, scratch, b"smptest.elf", crate::SMALL).ok_or("cannot load smptest.elf")?;
let rw = PermissionSet::empty()
.with(Permission::Read)
.with(Permission::Write)