@@ -11,6 +11,7 @@ static LOGGER: OnceCell<LockedLogger> = OnceCell::uninit();
|
||||
/// A logger instance protected by a spinlock.
|
||||
struct LockedLogger {
|
||||
framebuffer: Option<Spinlock<framebuffer::FrameBufferWriter>>,
|
||||
serial: Option<Spinlock<serial::SerialPort>>
|
||||
}
|
||||
|
||||
impl LockedLogger {
|
||||
@@ -20,9 +21,11 @@ impl LockedLogger {
|
||||
info: FrameBufferInfo,
|
||||
) -> Self {
|
||||
let framebuffer = Some(Spinlock::new(framebuffer::FrameBufferWriter::new(framebuffer, info)));
|
||||
let serial = Some(Spinlock::new(unsafe { serial::SerialPort::init() }));
|
||||
|
||||
LockedLogger {
|
||||
framebuffer,
|
||||
serial
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +37,10 @@ impl LockedLogger {
|
||||
if let Some(framebuffer) = &self.framebuffer {
|
||||
unsafe { framebuffer.force_unlock() };
|
||||
}
|
||||
|
||||
if let Some(serial) = &self.serial {
|
||||
unsafe { serial.force_unlock() };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,6 +54,11 @@ impl log::Log for LockedLogger {
|
||||
let mut framebuffer = framebuffer.lock();
|
||||
writeln!(framebuffer, "{:5}: {}", record.level(), record.args()).unwrap();
|
||||
}
|
||||
|
||||
if let Some(serial) = &self.serial {
|
||||
let mut serial = serial.lock();
|
||||
writeln!(serial, "{:5}: {}", record.level(), record.args()).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
fn flush(&self) {}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
pub mod logger;
|
||||
mod framebuffer;
|
||||
mod serial;
|
||||
|
||||
pub use logger::*;
|
||||
|
28
kernel/src/logger/serial.rs
Normal file
28
kernel/src/logger/serial.rs
Normal file
@@ -0,0 +1,28 @@
|
||||
use core::fmt;
|
||||
|
||||
pub struct SerialPort {
|
||||
port: uart_16550::SerialPort,
|
||||
}
|
||||
|
||||
impl SerialPort {
|
||||
/// # Safety
|
||||
///
|
||||
/// unsafe because this function must only be called once
|
||||
pub unsafe fn init() -> Self {
|
||||
let mut port = unsafe { uart_16550::SerialPort::new(0x3F8) };
|
||||
port.init();
|
||||
Self { port }
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Write for SerialPort {
|
||||
fn write_str(&mut self, s: &str) -> fmt::Result {
|
||||
for char in s.bytes() {
|
||||
match char {
|
||||
b'\n' => self.port.write_str("\r\n").unwrap(),
|
||||
byte => self.port.send(byte),
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
@@ -23,6 +23,8 @@ fn kernel_main(boot_info: &'static mut BootInfo) -> ! {
|
||||
logger::init_logger(buffer, info);
|
||||
|
||||
log::info!("Hello World from KERNEL");
|
||||
|
||||
// Endless loop as the kernel must stay running
|
||||
loop {}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user