From 106e907438228de19ef97818b0ea7bde7d2c22e4 Mon Sep 17 00:00:00 2001 From: Julien CLEMENT Date: Thu, 2 Dec 2021 22:29:56 +0100 Subject: [PATCH] feat(serial): add external serial driver Signed-off-by: Julien CLEMENT --- Cargo.lock | 43 ++++++++++++++++++++++++++++++++++++++++++- Cargo.toml | 2 ++ Makefile | 2 +- src/lib.rs | 6 +++--- src/serial.rs | 34 ++++++++++++++++++++++++++++++++++ src/vga.rs | 11 +++++------ 6 files changed, 87 insertions(+), 11 deletions(-) create mode 100644 src/serial.rs diff --git a/Cargo.lock b/Cargo.lock index 329d2c2..8a032a8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,13 +2,27 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "bit_field" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcb6dd1c2376d2e096796e234a70e17e94cc2d5d54ff8ce42b28cef1d0d359a4" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + [[package]] name = "julios" version = "0.1.0" dependencies = [ "lazy_static", "spin", - "volatile", + "uart_16550", + "volatile 0.2.7", + "x86_64", ] [[package]] @@ -26,8 +40,35 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" +[[package]] +name = "uart_16550" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65ad019480ef5ff8ffe66d6f6a259cd87cf317649481394981db1739d844f374" +dependencies = [ + "bitflags", + "x86_64", +] + [[package]] name = "volatile" version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6b06ad3ed06fef1713569d547cdbdb439eafed76341820fb0e0344f29a41945" + +[[package]] +name = "volatile" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4c2dbd44eb8b53973357e6e207e370f0c1059990df850aca1eca8947cf464f0" + +[[package]] +name = "x86_64" +version = "0.14.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbc6ed1ed2cd4536b083c34041aff7b84448ee25ac4aa5e9d54802ce226f9815" +dependencies = [ + "bit_field", + "bitflags", + "volatile 0.4.4", +] diff --git a/Cargo.toml b/Cargo.toml index 17eda98..fbf9c29 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,8 @@ crate-type = ["staticlib"] [dependencies] volatile = "0.2.6" spin = "0.5.2" +x86_64 = "0.14.2" +uart_16550 = "0.2.0" [dependencies.lazy_static] version = "1.0" diff --git a/Makefile b/Makefile index 337f6f3..345464a 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,7 @@ GRUB_CFG = grub/grub.cfg all: $(ISO) run: $(ISO) - qemu-system-x86_64 -cdrom $< + qemu-system-x86_64 -cdrom $< -serial stdio debug: $(ISO) bochs -q diff --git a/src/lib.rs b/src/lib.rs index 78e2898..a8e4050 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,6 +2,7 @@ #![no_main] mod vga; +mod serial; use core::panic::PanicInfo; use vga::Color; @@ -12,11 +13,10 @@ fn panic_handler(info: &PanicInfo) -> ! { loop {} } - #[no_mangle] pub extern "C" fn julios_main() -> ! { println!("Hello World!"); println!("{}", "***JuliOS***"); - panic!("Test panic"); - loop {} + serial_println!("Test serial"); + panic!("Kernel end of flow"); } diff --git a/src/serial.rs b/src/serial.rs new file mode 100644 index 0000000..e8073d9 --- /dev/null +++ b/src/serial.rs @@ -0,0 +1,34 @@ +use uart_16550::SerialPort; +use spin::Mutex; +use lazy_static::lazy_static; + +lazy_static! { + pub static ref SERIAL1: Mutex = { + let mut serial_port = unsafe { SerialPort::new(0x3F8) }; + serial_port.init(); + Mutex::new(serial_port) + }; +} + +#[doc(hidden)] +pub fn _print(args: ::core::fmt::Arguments) { + use core::fmt::Write; + SERIAL1.lock().write_fmt(args).expect("Printing to serial failed"); +} + +/// Prints to the host through the serial interface. +#[macro_export] +macro_rules! serial_print { + ($($arg:tt)*) => { + $crate::serial::_print(format_args!($($arg)*)); + }; +} + +/// Prints to the host through the serial interface, appending a newline. +#[macro_export] +macro_rules! serial_println { + () => ($crate::serial_print!("\n")); + ($fmt:expr) => ($crate::serial_print!(concat!($fmt, "\n"))); + ($fmt:expr, $($arg:tt)*) => ($crate::serial_print!( + concat!($fmt, "\n"), $($arg)*)); +} diff --git a/src/vga.rs b/src/vga.rs index fb15e34..e2c38a4 100644 --- a/src/vga.rs +++ b/src/vga.rs @@ -1,7 +1,7 @@ -use volatile::Volatile; use core::fmt; use lazy_static::lazy_static; use spin::Mutex; +use volatile::Volatile; const BUFFER_HEIGHT: usize = 25; const BUFFER_WIDTH: usize = 80; @@ -9,7 +9,7 @@ const BUFFER_WIDTH: usize = 80; lazy_static! { pub static ref WRITER: Mutex = Mutex::new(Writer { column: 0, - color_code: ColorCode::new(Color::LightBlue, Color::Black), + color_code: ColorCode::new(Color::LightGreen, Color::Black), buffer: unsafe { &mut *(0xb8000 as *mut VgaBuffer) } }); } @@ -34,7 +34,6 @@ pub fn change_color(fg: Color, bg: Color) { WRITER.lock().change_color(ColorCode::new(fg, bg)) } - #[allow(dead_code)] #[derive(Debug, Clone, Copy, PartialEq, Eq)] #[repr(u8)] @@ -90,7 +89,7 @@ impl Writer { for byte in s.bytes() { match byte { 0x20..=0x7e | b'\n' => self.write_byte(byte), - _ => self.write_byte(0xfe) + _ => self.write_byte(0xfe), } } } @@ -109,7 +108,7 @@ impl Writer { let color_code = self.color_code; self.buffer.chars[row][col].write(VgaChar { character: byte, - color_code + color_code, }); self.column += 1; } @@ -130,7 +129,7 @@ impl Writer { fn clear_row(&mut self, row: usize) { let blank = VgaChar { character: b' ', - color_code: self.color_code + color_code: self.color_code, }; for col in 0..BUFFER_WIDTH { self.buffer.chars[row][col].write(blank);