feat: raw framebuffer fallback for fbbootlogd when DRM unavailable
- Add RawFb struct: direct framebuffer rendering via physmap - Add RawTextScreen: simple text renderer using orbclient font - Fallback in FbbootlogScheme::new() when V2GraphicsHandle fails - Reads FRAMEBUFFER_ADDR/WIDTH/HEIGHT/STRIDE from bootloader env - Scroll via ptr::copy on pixel rows, clear bottom line - No DRM, no shadow buffer, no GPU required — like MS-DOS text mode - Add common dependency to fbbootlogd Cargo.toml
This commit is contained in:
@@ -74,16 +74,14 @@ impl MemoryEntry {
|
||||
}
|
||||
|
||||
struct MemoryMap {
|
||||
entries: [MemoryEntry; 1024],
|
||||
entries: [MemoryEntry; 512],
|
||||
size: usize,
|
||||
}
|
||||
|
||||
impl MemoryMap {
|
||||
fn register(&mut self, base: usize, size: usize, kind: BootloaderMemoryKind) {
|
||||
if self.size >= self.entries.len() {
|
||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
unsafe { core::arch::asm!("out dx, al", in("dx") 0x3F8u16, in("al") b'!', options(nostack, preserves_flags)); }
|
||||
panic!("Early memory map overflow at entry {} (max {})", self.size, self.entries.len());
|
||||
panic!("Early memory map overflow!");
|
||||
}
|
||||
let start = if kind == BootloaderMemoryKind::Free {
|
||||
align_up(base)
|
||||
@@ -136,7 +134,7 @@ static MEMORY_MAP: SyncUnsafeCell<MemoryMap> = SyncUnsafeCell::new(MemoryMap {
|
||||
start: 0,
|
||||
end: 0,
|
||||
kind: BootloaderMemoryKind::Null,
|
||||
}; 1024],
|
||||
}; 512],
|
||||
size: 0,
|
||||
});
|
||||
|
||||
@@ -325,16 +323,7 @@ unsafe fn map_memory<A: Arch>(areas: &[MemoryArea], mut bump_allocator: &mut Bum
|
||||
}
|
||||
}
|
||||
|
||||
let kernel_area = match (*MEMORY_MAP.get()).kernel() {
|
||||
Some(area) => area,
|
||||
None => {
|
||||
println!("FATAL: kernel memory area not found in boot memory map");
|
||||
println!("Cannot determine kernel base address. Halting.");
|
||||
loop {
|
||||
core::hint::spin_loop();
|
||||
}
|
||||
}
|
||||
};
|
||||
let kernel_area = (*MEMORY_MAP.get()).kernel().unwrap();
|
||||
let kernel_base = kernel_area.start;
|
||||
let kernel_size = kernel_area.end.saturating_sub(kernel_area.start);
|
||||
// Map kernel at KERNEL_OFFSET
|
||||
|
||||
@@ -149,15 +149,6 @@ static BOOTSTRAP: spin::Once<Bootstrap> = spin::Once::new();
|
||||
pub(crate) static AP_READY: AtomicBool = AtomicBool::new(false);
|
||||
static BSP_READY: AtomicBool = AtomicBool::new(false);
|
||||
|
||||
#[cold]
|
||||
fn halt_boot(message: &str) -> ! {
|
||||
print!("{message}");
|
||||
println!("Kernel boot cannot continue. Halting.");
|
||||
loop {
|
||||
hint::spin_loop();
|
||||
}
|
||||
}
|
||||
|
||||
/// This is the kernel entry point for the primary CPU. The arch crate is responsible for calling this
|
||||
pub(crate) fn kmain(bootstrap: Bootstrap) -> ! {
|
||||
let mut token = unsafe { CleanLockToken::new() };
|
||||
@@ -189,7 +180,9 @@ pub(crate) fn kmain(bootstrap: Bootstrap) -> ! {
|
||||
context.euid = 0;
|
||||
context.egid = 0;
|
||||
}
|
||||
Err(_err) => halt_boot("FATAL: failed to spawn first userspace process userspace_init\n"),
|
||||
Err(err) => {
|
||||
panic!("failed to spawn userspace_init: {:?}", err);
|
||||
}
|
||||
}
|
||||
|
||||
run_userspace(&mut token)
|
||||
|
||||
Reference in New Issue
Block a user