Writing an OS in Rust

  • VGA字符模式
  • 格式化宏
  • println! 宏

VGA text mode

0xb8000

vi vga.rs

use core::fmt::{ Write, Result, Arguments };
static mut CURSOR: usize = 0;
struct TextMode {
    w: usize,
    // h: usize,
}
impl Write for TextMode {
    fn write_str(&mut self, s: &str) -> Result {
        let buffer = 0xb8000 as *mut u8;
        for (i, &byte) in s.as_bytes().iter().enumerate() {
            unsafe {
                if b'\n' == byte {
                    CURSOR = CURSOR + self.w - (CURSOR % self.w) - 1;
                } else {
                    let j = (i + CURSOR) as isize;
                    *buffer.offset(j * 2) = byte;
                    *buffer.offset(j * 2 + 1) = 0xf;
                }
            }
        }
        unsafe {
            CURSOR = CURSOR + s.len();
        }
        Ok(())
    }
}

vi vga.rs

#[macro_export]
macro_rules! print {
    ($($arg:tt)*) => ($crate::vga::_print(format_args!($($arg)*)));
}

#[macro_export]
macro_rules! println {
    () => (print!("\n"));
    ($($arg:tt)*) => (print!("{}\n", format_args!($($arg)*)));
}

#[doc(hidden)]
pub fn _print(args: Arguments) {
    let mut writer = TextMode { w: 80 }; //, h: 25
    writer.write_fmt(args).unwrap();
}