fix: full init boot logic works — CreateProcess no longer spawns threads, boot uses out-param to avoid sret bug

- CreateProcess only creates process + grants cap, no thread spawning
- boot::boot takes &mut BootResult instead of returning it (fixes -> ! sret convention issue)
- Init creates 6 server processes, sets up supervisor, enters receive loop
- No faults on QEMU with full boot sequence
This commit is contained in:
2026-10-18 04:57:20 +02:00
parent 29cd0e7dfe
commit ffde4065ba
3 changed files with 27 additions and 35 deletions

View File

@@ -52,16 +52,28 @@ pub struct BootResult {
pub server_count: usize,
}
pub fn boot(manifest: &BootManifest, create_cap: CapSlot) -> BootResult {
impl BootResult {
pub fn empty() -> Self {
Self {
storage_endpoint: CapSlot::new(0).unwrap_or_else(|| unreachable!()),
create_cap: CapSlot::new(0).unwrap_or_else(|| unreachable!()),
server_pids: [const { None }; MAX_PIDS],
server_count: 0,
}
}
}
pub fn boot(manifest: &BootManifest, create_cap: CapSlot, result: &mut BootResult) {
let mut endpoints = EndpointRegistry::new();
let mut server_pids: [Option<ProcessId>; MAX_PIDS] = [const { None }; MAX_PIDS];
let mut storage_endpoint = create_cap; // placeholder until found
result.create_cap = create_cap;
result.storage_endpoint = create_cap;
result.server_count = 0;
for (i, server) in manifest.servers.iter().enumerate() {
let pid_raw = syscall::create_process(create_cap.value() as usize);
let pid = ProcessId::from_raw(pid_raw as u16);
if i < MAX_PIDS {
server_pids[i] = Some(pid);
result.server_pids[i] = Some(pid);
}
for binding in server.endpoints {
@@ -69,7 +81,7 @@ pub fn boot(manifest: &BootManifest, create_cap: CapSlot) -> BootResult {
if let Some(slot) = CapSlot::new(0) {
endpoints.register(name, slot);
if *name == "storage" {
storage_endpoint = slot;
result.storage_endpoint = slot;
}
}
}
@@ -87,19 +99,14 @@ pub fn boot(manifest: &BootManifest, create_cap: CapSlot) -> BootResult {
for server in manifest.servers {
if let BinarySource::Storage { path } = server.binary {
protocol_helpers::storage_write_binary(
storage_endpoint,
result.storage_endpoint,
path.as_bytes(),
&[],
);
}
}
BootResult {
storage_endpoint,
create_cap,
server_pids,
server_count: manifest.servers.len().min(MAX_PIDS),
}
result.server_count = manifest.servers.len().min(MAX_PIDS);
}
pub fn create_supervisor(manifest: &BootManifest, result: &BootResult) -> Supervisor {

View File

@@ -7,6 +7,12 @@ pub mod shutdown;
pub mod supervisor;
pub fn run() -> ! {
// Phase 1: just prove we can run from disk and exit cleanly
userspace::syscall::exit();
let create_cap = types::bounded::CapSlot::new(0)
.unwrap_or_else(|| unreachable!());
let mut result = boot::BootResult::empty();
boot::boot(&manifest::SNAKE_MANIFEST, create_cap, &mut result);
let mut sup = boot::create_supervisor(&manifest::SNAKE_MANIFEST, &result);
sup.run(create_cap);
}