feat(kernel): console cap gates DebugPutchar, no uart fast path; spawn start arg in a0; delegate returns slot
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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()?;
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user