NONOS runs on one core on every real multicore machine because the AP bring-up path is compiled out of every shipped build. The whole path is gated on #[cfg(feature = "nonos-smp")] (kernel_core/init/start_secondary.rs:21), and nonos-smp = [] (Cargo.toml:219) is referenced by no feature list, no Makefile, no mk/*.mk. microkernel-core (the default) does not pull it, so cargo build and every prod image compile start_secondary_cpus to an empty body. All non-BSP cores are left in firmware INIT state.
The SMP code itself is largely real, not stubbed: CPUID+MADT topology (smp/topology/detection.rs), INIT-SIPI-SIPI, a real->protected->long-mode trampoline, per-CPU GDT/IDT/TSS and per-CPU GS base (smp/percpu/operations.rs:68), per-CPU run queues, and a TLB-shootdown IPI all exist.
But three single-core assumptions sit underneath and must change first: the paging manager is a global Mutex singleton with scalar active CR3/asid (memory/paging/manager/address_space/switch.rs), the default scheduler uses one global run queue not the per-CPU queues, and an online AP idles until an explicit reschedule IPI (smp/ap.rs:60) rather than pulling work.
Widening order: wire the feature into a shipping profile, make the paging manager per-CPU-safe, move dispatch onto the per-CPU queues with timer-driven work-stealing, then prove the IPI paths on a real 2+ core boot.
NONOS runs on one core on every real multicore machine because the AP bring-up path is compiled out of every shipped build. The whole path is gated on #[cfg(feature = "nonos-smp")] (kernel_core/init/start_secondary.rs:21), and nonos-smp = [] (Cargo.toml:219) is referenced by no feature list, no Makefile, no mk/*.mk. microkernel-core (the default) does not pull it, so cargo build and every prod image compile start_secondary_cpus to an empty body. All non-BSP cores are left in firmware INIT state.
The SMP code itself is largely real, not stubbed: CPUID+MADT topology (smp/topology/detection.rs), INIT-SIPI-SIPI, a real->protected->long-mode trampoline, per-CPU GDT/IDT/TSS and per-CPU GS base (smp/percpu/operations.rs:68), per-CPU run queues, and a TLB-shootdown IPI all exist.
But three single-core assumptions sit underneath and must change first: the paging manager is a global Mutex singleton with scalar active CR3/asid (memory/paging/manager/address_space/switch.rs), the default scheduler uses one global run queue not the per-CPU queues, and an online AP idles until an explicit reschedule IPI (smp/ap.rs:60) rather than pulling work.
Widening order: wire the feature into a shipping profile, make the paging manager per-CPU-safe, move dispatch onto the per-CPU queues with timer-driven work-stealing, then prove the IPI paths on a real 2+ core boot.