feat(userspace): log server sole console holder; init boots from manifest; adapter loads only init+storage
This commit is contained in:
@@ -8,7 +8,14 @@ pub mod server;
|
||||
mod tests;
|
||||
|
||||
pub fn run() -> ! {
|
||||
let mut srv = server::LogServer::new();
|
||||
let console = libkos::start::console();
|
||||
let mut srv = server::LogServer::with_output(|bytes: &[u8]| {
|
||||
if let Some(console) = console {
|
||||
for &b in bytes {
|
||||
libkos::syscall::debug_putchar(console, b);
|
||||
}
|
||||
}
|
||||
});
|
||||
let ep = types::bounded::CapSlot::new(0).unwrap();
|
||||
server_framework::serve(&mut srv, ep)
|
||||
}
|
||||
|
||||
@@ -13,6 +13,8 @@ pub enum LogRequest {
|
||||
Write { level: LogLevel, tag: u16, payload: usize },
|
||||
GetCount,
|
||||
GetEntry { index: usize },
|
||||
/// Console text (`types::log`): `len` bytes of `bytes`.
|
||||
Text { bytes: [u8; types::log::TEXT_BYTES], len: usize },
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
@@ -50,6 +52,7 @@ impl Encode for LogRequest {
|
||||
}
|
||||
LogRequest::GetCount => [1, 0, 0, 0],
|
||||
LogRequest::GetEntry { index } => [2, *index, 0, 0],
|
||||
LogRequest::Text { bytes, len } => types::log::text_words(&bytes[..*len]),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -64,7 +67,7 @@ impl Decode for LogRequest {
|
||||
}
|
||||
1 => Some(LogRequest::GetCount),
|
||||
2 => Some(LogRequest::GetEntry { index: words[1] }),
|
||||
_ => None,
|
||||
_ => types::log::text_of(words).map(|(bytes, len)| LogRequest::Text { bytes, len }),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,18 +10,28 @@ struct LogEntry {
|
||||
payload: usize,
|
||||
}
|
||||
|
||||
pub struct LogServer {
|
||||
/// Holds the console: every process's text goes out through `out`.
|
||||
pub struct LogServer<O: FnMut(&[u8]) = fn(&[u8])> {
|
||||
entries: [Option<LogEntry>; MAX_ENTRIES],
|
||||
count: usize,
|
||||
write_pos: usize,
|
||||
out: O,
|
||||
}
|
||||
|
||||
impl LogServer {
|
||||
/// Text goes nowhere.
|
||||
pub fn new() -> Self {
|
||||
Self::with_output(|_| {})
|
||||
}
|
||||
}
|
||||
|
||||
impl<O: FnMut(&[u8])> LogServer<O> {
|
||||
pub fn with_output(out: O) -> Self {
|
||||
Self {
|
||||
entries: [const { None }; MAX_ENTRIES],
|
||||
count: 0,
|
||||
write_pos: 0,
|
||||
out,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +40,7 @@ impl LogServer {
|
||||
}
|
||||
}
|
||||
|
||||
impl Server for LogServer {
|
||||
impl<O: FnMut(&[u8])> Server for LogServer<O> {
|
||||
type Request = LogRequest;
|
||||
type Response = LogResponse;
|
||||
|
||||
@@ -44,6 +54,10 @@ impl Server for LogServer {
|
||||
}
|
||||
LogResponse::Ok
|
||||
}
|
||||
LogRequest::Text { bytes, len } => {
|
||||
(self.out)(&bytes[..len.min(bytes.len())]);
|
||||
LogResponse::Ok
|
||||
}
|
||||
LogRequest::GetCount => LogResponse::Count(self.count),
|
||||
LogRequest::GetEntry { index } => {
|
||||
if index >= self.count {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use crate::protocol::*;
|
||||
use crate::server::LogServer;
|
||||
use server_framework::Server;
|
||||
use server_framework::{Decode, Server};
|
||||
|
||||
#[test]
|
||||
fn empty_server_has_zero_count() {
|
||||
@@ -41,3 +41,20 @@ fn ring_buffer_wraps() {
|
||||
}
|
||||
assert_eq!(server.count(), 128);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn text_goes_out_through_the_console() {
|
||||
let mut seen = [0u8; 64];
|
||||
let mut n = 0;
|
||||
{
|
||||
let mut server = LogServer::with_output(|b: &[u8]| {
|
||||
seen[n..n + b.len()].copy_from_slice(b);
|
||||
n += b.len();
|
||||
});
|
||||
for chunk in [&b"init: "[..], b"started\n"] {
|
||||
let words = types::log::text_words(chunk);
|
||||
server.handle(LogRequest::decode(words).unwrap());
|
||||
}
|
||||
}
|
||||
assert_eq!(&seen[..n], b"init: started\n");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user