feat(kernel): console cap gates DebugPutchar, no uart fast path; spawn start arg in a0; delegate returns slot

This commit is contained in:
2026-10-27 14:54:36 +01:00
parent 33e1c849d1
commit 7415bab7f5
31 changed files with 290 additions and 64 deletions

View File

@@ -62,6 +62,15 @@ pub fn system_control() -> Option<CapSlot> {
slot(info.system_control_slot)
}
/// The console capability, until init hands it to the log server.
pub fn console() -> Option<CapSlot> {
let info = boot_info();
if info.magic != types::bootinfo::MAGIC {
return None;
}
slot(info.console_slot)
}
/// Sorts the board's devices out.
pub fn discover() -> Devices {
let info = boot_info();

View File

@@ -111,6 +111,7 @@ const SERVERS: &[ServerInfo] = &[
];
pub fn run() -> ! {
libkos::start::set_console(devices::console());
libkos::println!("init: started (pid={:#x})", syscall::get_process_id().raw());
// Drivers wait for their device before serving, so this comes first:
@@ -151,7 +152,7 @@ pub fn run() -> ! {
if let Some(ep_cap) = syscall::create_endpoint() {
syscall::delegate(ep_cap, loaded.process_cap, ipc_perms);
syscall::spawn_thread_in(loaded.process_cap, loaded.entry_point, USER_STACK_TOP);
start(&loaded, true);
}
libkos::println!("ok (entry={:#x})", loaded.entry_point.raw());
@@ -171,7 +172,7 @@ pub fn run() -> ! {
let client = PermissionSet::empty().with(Permission::Execute);
syscall::delegate(INPUT_EP, snake.process_cap, client);
syscall::delegate(DISPLAY_EP, snake.process_cap, client);
syscall::spawn_thread_in(snake.process_cap, snake.entry_point, USER_STACK_TOP);
start(&snake, false);
libkos::println!("ok");
} else {
libkos::println!("SKIP");
@@ -182,6 +183,16 @@ pub fn run() -> ! {
idle();
}
/// Starts `program`, lending it init's console if `console`.
pub(crate) fn start(program: &LoadedProcess, console: bool) {
let write = PermissionSet::empty().with(Permission::Write);
let slot = libkos::start::console()
.filter(|_| console)
.and_then(|c| syscall::delegate(c, program.process_cap, write));
let arg = types::start_arg::encode(slot, None);
syscall::spawn_thread_in(program.process_cap, program.entry_point, USER_STACK_TOP, arg);
}
/// A region of init's own to read program files into.
fn scratch() -> Option<&'static mut [u8]> {
let region = syscall::create_region(PageCount::new(SCRATCH_PAGES)?).ok()?;

View File

@@ -45,10 +45,11 @@ fn start_spinner(storage: &mut Storage, scratch: &mut [u8], page: CapSlot) -> Re
.with(Permission::Read)
.with(Permission::Write)
.with(Permission::Delegate);
if !syscall::delegate(page, spinner.process_cap, rw) {
// The page first: the spinner expects it in slot 0.
if syscall::delegate(page, spinner.process_cap, rw).is_none() {
return Err("cannot give the spinner its page");
}
syscall::spawn_thread_in(spinner.process_cap, spinner.entry_point, crate::USER_STACK_TOP);
crate::start(&spinner, true);
if !wait_until(3000, || counters().iter().all(|c| *c > 0)) {
return Err("spinner threads did not all start");
}