feat(userspace): log server sole console holder; init boots from manifest; adapter loads only init+storage
This commit is contained in:
@@ -5,13 +5,9 @@ fn kern() -> &'static mut kernel::Kernel<crate::platform::RiscVPlatform> {
|
||||
unsafe { &mut *crate::kernel_ptr() }
|
||||
}
|
||||
|
||||
pub fn grant_all(
|
||||
uart: &Uart,
|
||||
init_pid: ProcessId,
|
||||
storage_pid: ProcessId,
|
||||
display_pid: ProcessId,
|
||||
input_pid: ProcessId,
|
||||
) {
|
||||
/// Init gets storage's process and endpoint (slots 1 and 2), storage its
|
||||
/// endpoint (slot 0); everything else init starts itself.
|
||||
pub fn grant_all(uart: &Uart, init_pid: ProcessId, storage_pid: ProcessId) {
|
||||
let all_perms = types::permission::PermissionSet::empty()
|
||||
.with(types::permission::Permission::Read)
|
||||
.with(types::permission::Permission::Write)
|
||||
@@ -49,74 +45,5 @@ pub fn grant_all(
|
||||
)
|
||||
.unwrap_or_else(|_| crate::halt(uart, "grant failed"));
|
||||
|
||||
let display_ep = kern()
|
||||
.create_endpoint(display_pid)
|
||||
.unwrap_or_else(|_| crate::halt(uart, "display endpoint failed"));
|
||||
|
||||
kern()
|
||||
.grant_capability(
|
||||
display_pid,
|
||||
domain::resource::Resource::Endpoint(display_ep),
|
||||
ipc_perms,
|
||||
)
|
||||
.unwrap_or_else(|_| crate::halt(uart, "grant failed"));
|
||||
|
||||
kern()
|
||||
.grant_capability(
|
||||
init_pid,
|
||||
domain::resource::Resource::Endpoint(display_ep),
|
||||
all_perms,
|
||||
)
|
||||
.unwrap_or_else(|_| crate::halt(uart, "grant failed"));
|
||||
kern()
|
||||
.grant_capability(
|
||||
init_pid,
|
||||
domain::resource::Resource::Process(display_pid),
|
||||
all_perms,
|
||||
)
|
||||
.unwrap_or_else(|_| crate::halt(uart, "grant failed"));
|
||||
|
||||
let input_ep = kern()
|
||||
.create_endpoint(input_pid)
|
||||
.unwrap_or_else(|_| crate::halt(uart, "input endpoint failed"));
|
||||
|
||||
kern()
|
||||
.grant_capability(
|
||||
input_pid,
|
||||
domain::resource::Resource::Endpoint(input_ep),
|
||||
ipc_perms,
|
||||
)
|
||||
.unwrap_or_else(|_| crate::halt(uart, "grant failed"));
|
||||
|
||||
kern()
|
||||
.grant_capability(
|
||||
init_pid,
|
||||
domain::resource::Resource::Endpoint(input_ep),
|
||||
all_perms,
|
||||
)
|
||||
.unwrap_or_else(|_| crate::halt(uart, "grant failed"));
|
||||
kern()
|
||||
.grant_capability(
|
||||
init_pid,
|
||||
domain::resource::Resource::Process(input_pid),
|
||||
all_perms,
|
||||
)
|
||||
.unwrap_or_else(|_| crate::halt(uart, "grant failed"));
|
||||
|
||||
uart.write_str("k-os: capabilities granted\n");
|
||||
}
|
||||
|
||||
/// Until the log server owns the console, the servers loaded here print
|
||||
/// through a console cap of their own, its slot passed in `a0`.
|
||||
pub fn grant_console(uart: &Uart, servers: &[super::loader::LoadedProcess]) {
|
||||
let write =
|
||||
types::permission::PermissionSet::empty().with(types::permission::Permission::Write);
|
||||
for server in servers {
|
||||
let slot = kern()
|
||||
.grant_capability(server.pid, domain::resource::Resource::Console, write)
|
||||
.unwrap_or_else(|_| crate::halt(uart, "console grant failed"));
|
||||
if let Some(ctx) = kern().thread_context_mut(server.tid) {
|
||||
ctx.registers_mut()[10] = types::start_arg::encode(Some(slot), None);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,10 +12,8 @@ const USER_VA_BASE: usize = 0x10000;
|
||||
const USER_STACK_PAGES: usize = USER_VA_BASE / PAGE_SIZE - 1;
|
||||
const MAX_FILE_SIZE: usize = 64 * 1024;
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct LoadedProcess {
|
||||
pub pid: ProcessId,
|
||||
pub tid: ThreadId,
|
||||
}
|
||||
|
||||
fn kern() -> &'static mut kernel::Kernel<crate::platform::RiscVPlatform> {
|
||||
@@ -50,30 +48,17 @@ pub fn load_init(uart: &Uart, blk: &mut VirtioBlk) -> LoadedProcess {
|
||||
setup_thread(tid, entry);
|
||||
uart.write_str("k-os: init loaded\n");
|
||||
|
||||
LoadedProcess { pid, tid }
|
||||
LoadedProcess { pid }
|
||||
}
|
||||
|
||||
/// The servers boot loads, their budgets carved from init's.
|
||||
pub const STORAGE: Limits = Limits {
|
||||
/// Storage's budget, carved from init's.
|
||||
const STORAGE: Limits = Limits {
|
||||
pages: 256,
|
||||
endpoints: 2,
|
||||
notifications: 2,
|
||||
// A buffer per client (8) and the disk's DMA.
|
||||
regions: 12,
|
||||
};
|
||||
/// The framebuffer alone is ~1000 pages at 1280x800.
|
||||
pub const DISPLAY: Limits = Limits {
|
||||
pages: 1280,
|
||||
endpoints: 2,
|
||||
notifications: 2,
|
||||
regions: 4,
|
||||
};
|
||||
pub const INPUT: Limits = Limits {
|
||||
pages: 64,
|
||||
endpoints: 2,
|
||||
notifications: 2,
|
||||
regions: 4,
|
||||
};
|
||||
|
||||
pub fn load_server(
|
||||
uart: &Uart,
|
||||
@@ -81,10 +66,9 @@ pub fn load_server(
|
||||
init: ProcessId,
|
||||
filename: &[u8],
|
||||
label: &str,
|
||||
limits: Limits,
|
||||
) -> LoadedProcess {
|
||||
let pid = kern()
|
||||
.create_process_internal(init, limits)
|
||||
.create_process_internal(init, STORAGE)
|
||||
.unwrap_or_else(|| crate::halt(uart, "process create failed"));
|
||||
let entry = load_elf(uart, blk, pid, filename);
|
||||
let tid = kern()
|
||||
@@ -95,7 +79,7 @@ pub fn load_server(
|
||||
uart.write_str(label);
|
||||
uart.write_str(" loaded\n");
|
||||
|
||||
LoadedProcess { pid, tid }
|
||||
LoadedProcess { pid }
|
||||
}
|
||||
|
||||
fn setup_thread(tid: ThreadId, entry: usize) {
|
||||
|
||||
@@ -40,32 +40,14 @@ extern "C" fn kmain(hart: usize) -> ! {
|
||||
boot::hardware::probe_block_device(&uart).unwrap_or_else(|| halt(&uart, "no block device"));
|
||||
|
||||
let init = boot::loader::load_init(&uart, &mut blk);
|
||||
use boot::loader::{DISPLAY, INPUT, STORAGE, load_server};
|
||||
let storage = load_server(
|
||||
&uart,
|
||||
&mut blk,
|
||||
init.pid,
|
||||
b"storage.elf",
|
||||
"storage",
|
||||
STORAGE,
|
||||
);
|
||||
let display = load_server(
|
||||
&uart,
|
||||
&mut blk,
|
||||
init.pid,
|
||||
b"display.elf",
|
||||
"display",
|
||||
DISPLAY,
|
||||
);
|
||||
let input = load_server(&uart, &mut blk, init.pid, b"input.elf", "input", INPUT);
|
||||
// Init needs storage to load anything else; the rest is init's to start.
|
||||
let storage = boot::loader::load_server(&uart, &mut blk, init.pid, b"storage.elf", "storage");
|
||||
|
||||
let board = board::devices().unwrap_or_else(|| halt(&uart, "bad board table"));
|
||||
kern_mut()
|
||||
.register_board(init.pid, &board)
|
||||
.unwrap_or_else(|_| halt(&uart, "board registration failed"));
|
||||
boot::caps::grant_all(&uart, init.pid, storage.pid, display.pid, input.pid);
|
||||
// Last, so the servers' fixed slots stay where they expect them.
|
||||
boot::caps::grant_console(&uart, &[storage, display, input]);
|
||||
boot::caps::grant_all(&uart, init.pid, storage.pid);
|
||||
// After grant_all: init already relies on those slots.
|
||||
let mut placed = [None; board::BOARD_DEVICES];
|
||||
let boot_caps = kern_mut()
|
||||
|
||||
Reference in New Issue
Block a user