Files
RedBear-OS/recipes/drivers/graphics/fbbootlogd/src/main.rs
T
vasilito 15d0707e74 feat: USB storage read/write proof + full Red Bear OS tree sync
Add redbear-usb-storage-check in-guest binary that validates USB mass
storage read and write I/O: discovers /scheme/disk/ devices, writes a
test pattern to sector 2048, reads it back, verifies match, restores
original content. Updates test-usb-storage-qemu.sh with write-proof
verification step.

Includes all accumulated Red Bear OS work: kernel patches, relibc
patches, driver infrastructure, DRM/GPU, KDE recipes, firmware,
validation tooling, build system hardening, and documentation.
2026-05-03 23:03:24 +01:00

116 lines
3.9 KiB
Rust

//! Fbbootlogd renders the boot log and presents it on VT1.
//!
//! While fbbootlogd is superficially similar to fbcond, the major difference is:
//!
//! * Fbbootlogd doesn't accept input coming from the keyboard. It only allows getting written to.
//!
//! In the future fbbootlogd may also pull from logd as opposed to have logd push logs to it. And it
//! it could display a boot splash like plymouth instead of a boot log when booting in quiet mode.
use std::ops::ControlFlow;
use std::os::fd::AsRawFd;
use event::EventQueue;
use inputd::ConsumerHandleEvent;
use orbclient::Event;
use redox_scheme::Socket;
use scheme_utils::Blocking;
use crate::scheme::FbbootlogScheme;
mod scheme;
fn main() {
daemon::SchemeDaemon::new(daemon);
}
fn daemon(daemon: daemon::SchemeDaemon) -> ! {
let event_queue = EventQueue::new().expect("fbbootlogd: failed to create event queue");
event::user_data! {
enum Source {
Scheme,
Input,
}
}
let socket = Socket::nonblock().expect("fbbootlogd: failed to create fbbootlog scheme");
let mut scheme = FbbootlogScheme::new();
let mut handler = Blocking::new(&socket, 16);
event_queue
.subscribe(
socket.inner().raw(),
Source::Scheme,
event::EventFlags::READ,
)
.expect("fbbootlogd: failed to subscribe to scheme events");
event_queue
.subscribe(
scheme.input_handle.event_handle().as_raw_fd() as usize,
Source::Input,
event::EventFlags::READ,
)
.expect("fbbootlogd: failed to subscribe to scheme events");
{
let log_fd = socket
.create_this_scheme_fd(0, 0, 0, 0)
.expect("fbbootlogd: failed to create log fd");
// Add ourself as log sink
let log_file = libredox::Fd::open(
"/scheme/log/add_sink",
libredox::flag::O_WRONLY | libredox::flag::O_CLOEXEC,
0,
)
.expect("fbbootlogd: failed to open log/add_sink");
log_file
.call_wo(&log_fd.to_ne_bytes(), syscall::CallFlags::FD, &[])
.expect("fbbootlogd: failed to send log fd to log scheme.");
}
let _ = daemon.ready_sync_scheme(&socket, &mut scheme);
// This is not possible for now as fbbootlogd needs to open new displays at runtime for graphics
// driver handoff. In the future inputd may directly pass a handle to the display instead.
//libredox::call::setrens(0, 0).expect("fbbootlogd: failed to enter null namespace");
for event in event_queue {
match event.expect("fbbootlogd: failed to get event").user_data {
Source::Scheme => loop {
match handler
.process_requests_nonblocking(&mut scheme)
.expect("fbbootlogd: failed to process requests")
{
ControlFlow::Continue(()) => {}
ControlFlow::Break(()) => break,
}
},
Source::Input => {
let mut events = [Event::new(); 16];
loop {
match scheme
.input_handle
.read_events(&mut events)
.expect("fbbootlogd: error while reading events")
{
ConsumerHandleEvent::Events(&[]) => break,
ConsumerHandleEvent::Events(events) => {
for event in events {
scheme.handle_input(&event);
}
}
ConsumerHandleEvent::Handoff => {
eprintln!("fbbootlogd: handoff requested");
scheme.handle_handoff();
}
}
}
}
}
}
std::process::exit(0);
}