diff --git a/Cargo.lock b/Cargo.lock index 6038381..6fae98a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -32,6 +32,12 @@ dependencies = [ "serde", ] +[[package]] +name = "bit_field" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61" + [[package]] name = "bitflags" version = "1.3.2" @@ -107,9 +113,9 @@ checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" [[package]] name = "conquer-once" -version = "0.3.2" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c6d3a9775a69f6d1fe2cc888999b67ed30257d3da4d2af91984e722f2ec918a" +checksum = "5d008a441c0f269f36ca13712528069a86a3e60dffee1d98b976eb3b0b2160b4" dependencies = [ "conquer-util", ] @@ -217,6 +223,8 @@ dependencies = [ "log", "noto-sans-mono-bitmap", "spinning_top", + "uart_16550", + "x86_64", ] [[package]] @@ -274,9 +282,9 @@ checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" [[package]] name = "noto-sans-mono-bitmap" -version = "0.2.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a27daf9557165efe1d09b52f97393bf6283cadb0a76fbe64a1061e15553a994a" +checksum = "1064d564ae026ae123bf5d607318b42a5b31d70a3c48e6ea7ee44cce4cdb095e" [[package]] name = "once_cell" @@ -320,6 +328,15 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" +[[package]] +name = "raw-cpuid" +version = "10.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c297679cb867470fa8c9f67dbba74a78d78e3e98d7cf2b08d6d71540f797332" +dependencies = [ + "bitflags 1.3.2", +] + [[package]] name = "rustix" version = "1.0.8" @@ -394,9 +411,9 @@ dependencies = [ [[package]] name = "spinning_top" -version = "0.2.5" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b9eb1a2f4c41445a3a0ff9abc5221c5fcd28e1f13cd7c0397706f9ac938ddb0" +checksum = "d96d2d1d716fb500937168cc09353ffdc7a012be8475ac7308e1bdf0e3923300" dependencies = [ "lock_api", ] @@ -451,6 +468,17 @@ dependencies = [ "syn", ] +[[package]] +name = "uart_16550" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e492212ac378a5e00da953718dafb1340d9fbaf4f27d6f3c5cab03d931d1c049" +dependencies = [ + "bitflags 2.9.1", + "rustversion", + "x86", +] + [[package]] name = "unicode-ident" version = "1.0.18" @@ -468,6 +496,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "volatile" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "442887c63f2c839b346c192d047a7c87e73d0689c9157b00b53dcc27dd5ea793" + [[package]] name = "wasi" version = "0.14.2+wasi-0.2.4" @@ -698,3 +732,26 @@ checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" dependencies = [ "tap", ] + +[[package]] +name = "x86" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2781db97787217ad2a2845c396a5efe286f87467a5810836db6d74926e94a385" +dependencies = [ + "bit_field", + "bitflags 1.3.2", + "raw-cpuid", +] + +[[package]] +name = "x86_64" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f042214de98141e9c8706e8192b73f56494087cc55ebec28ce10f26c5c364ae" +dependencies = [ + "bit_field", + "bitflags 2.9.1", + "rustversion", + "volatile", +] diff --git a/kernel/Cargo.toml b/kernel/Cargo.toml index 153370e..1390c03 100644 --- a/kernel/Cargo.toml +++ b/kernel/Cargo.toml @@ -10,12 +10,14 @@ publish.workspace = true [dependencies] bootloader_api = { version = "0.11.10" } -conquer-once = { version = "0.3.2", default-features = false } +conquer-once = { version = "0.4.0", default-features = false } log = "0.4.17" -spinning_top = "0.2.4" +spinning_top = "0.3.0" +uart_16550 = "0.3.2" +x86_64 = "0.15.2" [dependencies.noto-sans-mono-bitmap] -version = "0.2.0" +version = "0.3.1" default-features = false features = [ "regular", diff --git a/kernel/src/logger/logger.rs b/kernel/src/logger/logger.rs index 32cdeca..8eda707 100644 --- a/kernel/src/logger/logger.rs +++ b/kernel/src/logger/logger.rs @@ -11,6 +11,7 @@ static LOGGER: OnceCell = OnceCell::uninit(); /// A logger instance protected by a spinlock. struct LockedLogger { framebuffer: Option>, + serial: Option> } 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) {} diff --git a/kernel/src/logger/mod.rs b/kernel/src/logger/mod.rs index fe29c1a..9773871 100644 --- a/kernel/src/logger/mod.rs +++ b/kernel/src/logger/mod.rs @@ -1,4 +1,5 @@ pub mod logger; mod framebuffer; +mod serial; pub use logger::*; diff --git a/kernel/src/logger/serial.rs b/kernel/src/logger/serial.rs new file mode 100644 index 0000000..8435c8e --- /dev/null +++ b/kernel/src/logger/serial.rs @@ -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(()) + } +} diff --git a/kernel/src/main.rs b/kernel/src/main.rs index 4526e9c..e76a697 100644 --- a/kernel/src/main.rs +++ b/kernel/src/main.rs @@ -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 {} }