feat(kernel): per-process budgets (pages, endpoints, notifs, regions) carved from creator, returned on death; init owns pool
This commit is contained in:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user