Files
k-os/crates/init/src/manifest.rs

126 lines
4.5 KiB
Rust

//! What init starts, in order: the system's boot policy, as data.
use types::budget::Limits;
/// A board device init hands to a program over its endpoint.
#[derive(Clone, Copy, PartialEq, Eq)]
pub enum Device {
Gpu,
Input,
Keystore,
Random,
}
/// A storage grant: a folder (or the whole disk, `b""`) and whether it may
/// be changed.
#[derive(Clone, Copy)]
pub struct Scope {
pub path: &'static [u8],
pub write: bool,
}
pub struct Program {
pub name: &'static str,
pub file: &'static [u8],
pub limits: Limits,
/// Serves an endpoint, which it finds in slot 0.
pub serves: bool,
/// Handed over in this order, after it starts.
pub devices: &'static [Device],
/// Authenticates the owner: init waits for the master key before
/// starting anything that touches user data.
pub unlocks: bool,
/// Earlier programs' endpoints it may call, in its next slots; each
/// program's copy carries its own badge, so a server can tell them apart.
pub uses: &'static [&'static str],
/// Storage it may reach, in the slot after `uses`.
pub storage: Option<Scope>,
/// Takes the console over from init; everyone else prints through it.
pub console: bool,
/// May have init spawn programs, whose limits together stay within this.
pub spawns: Option<Limits>,
/// May halt the machine.
pub system_control: bool,
}
/// Enough for a small program: its image, stack and a little heap.
pub const SMALL: Limits = Limits {
pages: 64,
endpoints: 2,
notifications: 2,
regions: 2,
};
const fn server(name: &'static str, file: &'static [u8], limits: Limits) -> Program {
Program {
name,
file,
limits,
serves: true,
devices: &[],
unlocks: false,
uses: &[],
storage: None,
console: false,
spawns: None,
system_control: false,
}
}
/// Started on every boot. The log server comes first so the rest can print.
pub const SERVERS: &[Program] = &[
Program { console: true, ..server("log", b"bin/log", SMALL) },
Program { devices: &[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 {
devices: &[Device::Gpu],
uses: &["input"],
// The framebuffer alone is ~1000 pages at 1280x800.
..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"bin/terminal", SMALL) },
// Nothing that touches user data starts before the owner is in. It
// holds the screen (through the terminal), its keystore and randomness,
// and exits once it has handed over the key.
Program {
uses: &["terminal"],
devices: &[Device::Keystore, Device::Random],
unlocks: true,
// argon2's 16 MiB, its image and a little more.
..server("gatekeeper", b"bin/gatekeeper", Limits { pages: 4096 + 160, regions: 6, ..SMALL })
},
// The only one that equips apps (docs/apps.md): it reaches every app's
// files and the owner's decisions, and runs apps through init.
Program {
uses: &["terminal", "display"],
storage: Some(Scope { path: b"", write: true }),
// Room for a few apps at a time.
spawns: Some(Limits { pages: 512, endpoints: 8, notifications: 8, regions: 8 }),
..server("permission", b"bin/permission", Limits { pages: 96, ..SMALL })
},
server("session", b"bin/session", SMALL),
];
/// Run on the test image after the SMP self-test, instead of the desktop:
/// spawns through init, then reports and halts.
pub const TESTS: &[Program] = &[Program {
serves: false,
// The permission manager, to run an app the way the shell does.
uses: &["permission"],
storage: Some(Scope { path: b"", write: true }),
spawns: Some(Limits { pages: 128, endpoints: 2, notifications: 2, regions: 2 }),
system_control: true,
..server("spawntest", b"bin/spawntest", SMALL)
}];
/// The desktop; the test image runs the SMP self-test instead. The shell
/// holds the owner's files and asks the permission manager to run apps;
/// it holds nothing to give them beyond that.
pub const DESKTOP: &[Program] = &[Program {
serves: false,
uses: &["terminal", "permission"],
storage: Some(Scope { path: b"home", write: true }),
..server("shell", b"bin/shell", SMALL)
}];