feat(userspace): programs in /bin w/o .elf; bin manifests (needs = display) so shell runs snake; Ctrl+C kills foreground via terminal interrupt notification; ctrl keys; sleep

This commit is contained in:
2026-10-27 21:16:00 +01:00
parent 1fc5a54f06
commit 83809bbe94
33 changed files with 608 additions and 121 deletions

View File

@@ -58,7 +58,7 @@ pub fn run() -> ! {
// instead of the desktop, and the last one halts the machine.
let (storage, scratch) = launcher.storage();
if storage
.open(b"smptest.elf")
.open(b"bin/smptest")
.is_ok_and(|h| storage.close(h).is_ok())
{
libkos::println!("init: running the SMP self-test");

View File

@@ -51,19 +51,19 @@ const fn server(name: &'static str, file: &'static [u8], limits: Limits) -> Prog
/// Started on every boot. The log server comes first so the rest can print.
pub const SERVERS: &[Program] = &[
Program { console: true, ..server("log", b"log.elf", SMALL) },
Program { device: Some(Device::Input), ..server("input", b"input.elf", Limits { regions: 4, ..SMALL }) },
Program { console: true, ..server("log", b"bin/log", SMALL) },
Program { device: Some(Device::Input), ..server("input", b"bin/input", Limits { regions: 4, ..SMALL }) },
// The input server's only client: it passes input on to the app in focus.
Program {
device: Some(Device::Gpu),
uses: &["input"],
// The framebuffer alone is ~1000 pages at 1280x800.
..server("display", b"display.elf", Limits { pages: 1280, regions: 4, ..SMALL })
..server("display", b"bin/display", Limits { pages: 1280, regions: 4, ..SMALL })
},
// Text on the display, lines from the keyboard (it takes input focus).
Program { uses: &["display"], ..server("terminal", b"terminal.elf", SMALL) },
server("permis", b"permis.elf", SMALL),
server("session", b"session.elf", SMALL),
Program { uses: &["display"], ..server("terminal", b"bin/terminal", SMALL) },
server("permission", b"bin/permission", SMALL),
server("session", b"bin/session", SMALL),
];
/// Run on the test image after the SMP self-test, instead of the desktop:
@@ -73,14 +73,15 @@ pub const TESTS: &[Program] = &[Program {
uses: &["storage"],
spawns: Some(Limits { pages: 128, endpoints: 2, notifications: 2, regions: 2 }),
system_control: true,
..server("spawntest", b"spawntst.elf", SMALL)
..server("spawntest", b"bin/spawntest", SMALL)
}];
/// The desktop; the test image runs the SMP self-test instead.
pub const APPS: &[Program] = &[Program {
serves: false,
uses: &["terminal", "storage"],
// The display only to hand on, to programs whose manifest asks for it.
uses: &["terminal", "storage", "display"],
// Room for one program at a time, the way the shell runs them.
spawns: Some(Limits { pages: 256, endpoints: 2, notifications: 2, regions: 2 }),
..server("shell", b"shell.elf", SMALL)
..server("shell", b"bin/shell", SMALL)
}];

View File

@@ -1,4 +1,4 @@
//! SMP self-test, run when the disk carries `smptest.elf`: after revoking a
//! SMP self-test, run when the disk carries `bin/smptest`: after revoking a
//! spinner's page or killing it, no spinner counter may move on any hart.
use core::sync::atomic::{AtomicUsize, Ordering};
@@ -40,7 +40,7 @@ fn start_spinner(storage: &mut Storage, scratch: &mut [u8], page: CapSlot) -> Re
for i in 0..=THREADS {
word(i).store(0, Ordering::SeqCst);
}
let spinner = crate::load::load_binary(storage, scratch, b"smptest.elf", crate::manifest::SMALL).ok_or("cannot load smptest.elf")?;
let spinner = crate::load::load_binary(storage, scratch, b"bin/smptest", crate::manifest::SMALL).ok_or("cannot load bin/smptest")?;
let rw = PermissionSet::empty()
.with(Permission::Read)
.with(Permission::Write)