From ffde4065ba609b455f7a8c4bc0a9618e536efd4c Mon Sep 17 00:00:00 2001 From: Gabriel Kaszewski Date: Sun, 18 Oct 2026 04:57:20 +0200 Subject: [PATCH] =?UTF-8?q?fix:=20full=20init=20boot=20logic=20works=20?= =?UTF-8?q?=E2=80=94=20CreateProcess=20no=20longer=20spawns=20threads,=20b?= =?UTF-8?q?oot=20uses=20out-param=20to=20avoid=20sret=20bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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 --- crates/init/src/boot.rs | 31 ++++++++++++++++---------- crates/init/src/lib.rs | 10 +++++++-- crates/kernel/src/syscall/lifecycle.rs | 21 ----------------- 3 files changed, 27 insertions(+), 35 deletions(-) diff --git a/crates/init/src/boot.rs b/crates/init/src/boot.rs index 307cbc0..08e42c8 100644 --- a/crates/init/src/boot.rs +++ b/crates/init/src/boot.rs @@ -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; 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 { diff --git a/crates/init/src/lib.rs b/crates/init/src/lib.rs index d72a966..0f11502 100644 --- a/crates/init/src/lib.rs +++ b/crates/init/src/lib.rs @@ -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); } diff --git a/crates/kernel/src/syscall/lifecycle.rs b/crates/kernel/src/syscall/lifecycle.rs index 128940a..fa54241 100644 --- a/crates/kernel/src/syscall/lifecycle.rs +++ b/crates/kernel/src/syscall/lifecycle.rs @@ -56,27 +56,6 @@ impl Kernel

{ self.process_memory[new_pid.raw() as usize] = Some(domain::memory::process_memory::ProcessMemory::new(new_pid, 1024)); - let priority = types::bounded::Priority::new(16) - .unwrap_or_else(|| unreachable!()); - let time_slice = types::time::TimeSlice::new(100); - - let tid = match self.threads.spawn(new_pid, priority, time_slice, None) { - Ok(t) => t, - Err(e) => { - let _ = self.processes.destroy(new_pid); - return SyscallOutcome::Complete(SyscallResult::Error(e)); - } - }; - - if let Err(e) = self.processes.get_mut(new_pid).and_then(|p| p.add_thread(tid)) { - let _ = self.threads.destroy(tid); - let _ = self.processes.destroy(new_pid); - return SyscallOutcome::Complete(SyscallResult::Error(e)); - } - - let core = self.platform.core_id(); - self.scheduler.add(tid, priority, core); - let slot = match self.grant_cap( caller_pid, domain::resource::Resource::Process(new_pid),