diff --git a/moon/Cargo.lock b/moon/Cargo.lock index 41cd94e9..3ba98207 100644 --- a/moon/Cargo.lock +++ b/moon/Cargo.lock @@ -5,3 +5,12 @@ version = 3 [[package]] name = "moon" version = "0.1.0" +dependencies = [ + "spin", +] + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" diff --git a/moon/Cargo.toml b/moon/Cargo.toml index ed44c50e..a17e3710 100644 --- a/moon/Cargo.toml +++ b/moon/Cargo.toml @@ -16,3 +16,4 @@ strip = "debuginfo" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +spin = "0.5.2" \ No newline at end of file diff --git a/moon/src/arch/io.rs b/moon/src/arch/io.rs new file mode 100644 index 00000000..7d679bfc --- /dev/null +++ b/moon/src/arch/io.rs @@ -0,0 +1,34 @@ +#[cfg(target_arch = "x86_64")] +pub use super::x86_64::io::*; + +pub mod serial { + #[cfg(target_arch = "x86_64")] + pub use super::super::x86_64::io::*; + + pub fn write(s: &str) -> () { + for byte in s.bytes() { + match byte { + 0x20..=0x7e | b'\n' => serial::putchar(byte), + _ => serial::putchar(0xfe), + } + } + } +} + +use core::fmt; + +pub struct Serial +{ + +} + +impl fmt::Write for Serial { + fn write_str(&mut self, s: &str) -> fmt::Result { + serial::write(s); + Ok(()) + } +} + +use spin::Mutex; + +pub static SERIAL: Mutex = Mutex::new(Serial {}); \ No newline at end of file diff --git a/moon/src/arch/mod.rs b/moon/src/arch/mod.rs index a704f875..bc24dc5f 100644 --- a/moon/src/arch/mod.rs +++ b/moon/src/arch/mod.rs @@ -1,4 +1,5 @@ pub mod cpu; +pub mod io; #[cfg(target_arch = "x86_64")] mod x86_64; \ No newline at end of file diff --git a/moon/src/arch/x86_64/io.rs b/moon/src/arch/x86_64/io.rs new file mode 100644 index 00000000..cfde91f5 --- /dev/null +++ b/moon/src/arch/x86_64/io.rs @@ -0,0 +1,35 @@ +#![cfg(target_arch = "x86_64")] +#![allow(dead_code)] + +pub const COM1: u16 = 0x3f8; + +use core::arch::asm; + +pub unsafe fn outportb(port: u16, value: u8) -> () { + asm!("out dx, al", in("al") value, in("dx") port); +} + +pub unsafe fn inportb(port: u16) -> u8 { + let value: u8; + asm!("in al, dx", out("al") value, in("dx") port); + return value; +} + +pub unsafe fn io_delay() -> () { + outportb(0x80,0); +} + +pub mod serial { + use super::*; + + unsafe fn wait() -> () { + while (inportb(COM1 + 5) & 0x20) == 0 { + asm!("pause"); + } + } + + pub fn putchar(c: u8) -> () { + unsafe { wait(); } + unsafe { outportb(COM1, c); } + } +} \ No newline at end of file diff --git a/moon/src/arch/x86_64/mod.rs b/moon/src/arch/x86_64/mod.rs index 374e8ae6..1d6586c5 100644 --- a/moon/src/arch/x86_64/mod.rs +++ b/moon/src/arch/x86_64/mod.rs @@ -1 +1,3 @@ -pub mod cpu; \ No newline at end of file +#![cfg(target_arch = "x86_64")] +pub mod cpu; +pub mod io; \ No newline at end of file diff --git a/moon/src/log.rs b/moon/src/log.rs new file mode 100644 index 00000000..711ed888 --- /dev/null +++ b/moon/src/log.rs @@ -0,0 +1,19 @@ +use crate::arch::io::SERIAL; +use core::fmt; + +#[macro_export] +macro_rules! print { + ($($arg:tt)*) => ($crate::log::_print(format_args!($($arg)*))); +} + +#[macro_export] +macro_rules! println { + () => ($crate::print!("\n")); + ($($arg:tt)*) => ($crate::print!("{}\n", format_args!($($arg)*))); +} + +#[doc(hidden)] +pub fn _print(args: fmt::Arguments) { + use core::fmt::Write; + SERIAL.lock().write_fmt(args).unwrap(); +} \ No newline at end of file diff --git a/moon/src/main.rs b/moon/src/main.rs index ece63c74..d2a845fe 100644 --- a/moon/src/main.rs +++ b/moon/src/main.rs @@ -9,6 +9,7 @@ mod panic; mod util; mod init; mod arch; +mod log; use arch::cpu; @@ -21,6 +22,8 @@ pub extern "C" fn _start() -> ! { init::check_magic(); video::clear(Color::White); + + println!("Hello, world!"); cpu::halt(); diff --git a/moon/src/panic.rs b/moon/src/panic.rs index a5f300c2..91cafe83 100644 --- a/moon/src/panic.rs +++ b/moon/src/panic.rs @@ -1,6 +1,9 @@ use core::panic::PanicInfo; +use crate::println; + #[panic_handler] -fn panic(_info: &PanicInfo) -> ! { +fn panic(info: &PanicInfo) -> ! { + println!("Kernel {}", info); loop {} } \ No newline at end of file