feat(userspace): log server sole console holder; init boots from manifest; adapter loads only init+storage
This commit is contained in:
@@ -4,8 +4,13 @@ struct Writer;
|
||||
|
||||
impl fmt::Write for Writer {
|
||||
fn write_str(&mut self, s: &str) -> fmt::Result {
|
||||
// Without a console capability, output goes nowhere.
|
||||
if let Some(console) = crate::start::console() {
|
||||
// The log server first; a process without either prints nothing.
|
||||
// A call, not a send: the text is out before the caller goes on.
|
||||
if let Some(log) = crate::start::log() {
|
||||
for chunk in s.as_bytes().chunks(types::log::TEXT_BYTES) {
|
||||
let _ = crate::syscall::call(log, types::log::text_words(chunk), None);
|
||||
}
|
||||
} else if let Some(console) = crate::start::console() {
|
||||
for &b in s.as_bytes() {
|
||||
crate::syscall::debug_putchar(console, b);
|
||||
}
|
||||
|
||||
@@ -8,8 +8,9 @@ use types::start_arg;
|
||||
#[unsafe(no_mangle)]
|
||||
static LIBKOS_START_ARG: AtomicUsize = AtomicUsize::new(0);
|
||||
|
||||
/// Overrides the start argument's console once set; `NONE` drops output.
|
||||
/// Override the start argument's slots once set; `NONE` means none.
|
||||
static CONSOLE: AtomicUsize = AtomicUsize::new(UNSET);
|
||||
static LOG: AtomicUsize = AtomicUsize::new(UNSET);
|
||||
const UNSET: usize = usize::MAX;
|
||||
const NONE: usize = usize::MAX - 1;
|
||||
|
||||
@@ -19,18 +20,31 @@ fn arg() -> usize {
|
||||
|
||||
/// The console capability this process prints through, if any.
|
||||
pub fn console() -> Option<CapSlot> {
|
||||
match CONSOLE.load(Ordering::Relaxed) {
|
||||
UNSET => start_arg::console(arg()),
|
||||
v => CapSlot::new(u8::try_from(v).ok()?),
|
||||
}
|
||||
read(&CONSOLE, start_arg::console)
|
||||
}
|
||||
|
||||
/// For a process that gets its console some other way (init, from BootInfo).
|
||||
pub fn set_console(slot: Option<CapSlot>) {
|
||||
CONSOLE.store(slot.map_or(NONE, |s| s.value() as usize), Ordering::Relaxed);
|
||||
write(&CONSOLE, slot);
|
||||
}
|
||||
|
||||
/// The log server endpoint this process was given, if any.
|
||||
/// The log server endpoint this process prints to, if any.
|
||||
pub fn log() -> Option<CapSlot> {
|
||||
start_arg::log(arg())
|
||||
read(&LOG, start_arg::log)
|
||||
}
|
||||
|
||||
/// For a process given its log endpoint after it started.
|
||||
pub fn set_log(slot: Option<CapSlot>) {
|
||||
write(&LOG, slot);
|
||||
}
|
||||
|
||||
fn read(cell: &AtomicUsize, from_arg: fn(usize) -> Option<CapSlot>) -> Option<CapSlot> {
|
||||
match cell.load(Ordering::Relaxed) {
|
||||
UNSET => from_arg(arg()),
|
||||
v => CapSlot::new(u8::try_from(v).ok()?),
|
||||
}
|
||||
}
|
||||
|
||||
fn write(cell: &AtomicUsize, slot: Option<CapSlot>) {
|
||||
cell.store(slot.map_or(NONE, |s| s.value() as usize), Ordering::Relaxed);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user