From 56c937e6207503d2d5c7e76c3ab85d3d828f7424 Mon Sep 17 00:00:00 2001 From: Jack Halford Date: Fri, 9 Feb 2018 14:50:07 +0100 Subject: [PATCH] vga --- kernel-rs/README.md | 11 +-- kernel-rs/src/lib.rs | 23 ++++- kernel-rs/src/vga_buffer.rs | 168 +++++++++++++++++++----------------- 3 files changed, 111 insertions(+), 91 deletions(-) diff --git a/kernel-rs/README.md b/kernel-rs/README.md index 33b89b5f..833c270a 100644 --- a/kernel-rs/README.md +++ b/kernel-rs/README.md @@ -21,18 +21,9 @@ rustup component add rust-src cargo install xargo ``` -### docker -a standard development environment can be invoked: - -``` -docker run jzck/arch-kernel -it /usr/bin/zsh -``` - -clone the repo and `make iso` - # running -`make run` in your host operating system to launch qemu gtk window +`make run` runs the OS + a tmux split for the qemu terminal # References diff --git a/kernel-rs/src/lib.rs b/kernel-rs/src/lib.rs index 6c05c06a..168d3651 100644 --- a/kernel-rs/src/lib.rs +++ b/kernel-rs/src/lib.rs @@ -12,11 +12,28 @@ mod vga_buffer; #[no_mangle] pub extern fn kmain() -> ! { - vga_buffer::clear_screen(); - println!("Kernel startup..."); + use vga_buffer::WRITER; + use vga_buffer::Color; + use vga_buffer::ColorCode; + + WRITER.lock().reset_screen(); + println!(">> Kernel startup..."); + println!(">> Kernel startup..."); + + WRITER.lock().color_code = ColorCode::new(Color::Blue, Color::Yellow); + println!(">> Kernel startup..."); + println!(">> Kernel startup..."); + println!(">> Kernel startup..."); + + WRITER.lock().color_code = ColorCode::new(Color::Red, Color::Green); + println!(">> Kernel startup..."); + println!(">> Kernel startup..."); + println!(">> Kernel startup..."); + + WRITER.lock().color_code = ColorCode::new(Color::White, Color::Black); loop { - + } } diff --git a/kernel-rs/src/vga_buffer.rs b/kernel-rs/src/vga_buffer.rs index d35903bb..6b65d081 100644 --- a/kernel-rs/src/vga_buffer.rs +++ b/kernel-rs/src/vga_buffer.rs @@ -12,26 +12,27 @@ use core::fmt; use spin::Mutex; use volatile::Volatile; -struct Buffer { - chars: [[Volatile; BUFFER_WIDTH]; BUFFER_HEIGHT], -} - const BUFFER_HEIGHT: usize = 25; const BUFFER_WIDTH: usize = 80; -static mut VGA_BUFFER: Unique = unsafe { - Unique::new_unchecked(0xb8000 as *mut _) -}; - -fn vga_buffer() -> &'static mut Buffer { - unsafe { VGA_BUFFER.as_mut() } -} - pub static WRITER: Mutex = Mutex::new(Writer { column_position: 0, - color_code: ColorCode::new(Color::LightGreen, Color::Black), + color_code: ColorCode::new(Color::White, Color::Black), + vgabuffer: unsafe { Unique::new_unchecked(0xb8000 as *mut _) }, }); +pub struct Writer { + column_position: usize, + pub color_code: ColorCode, + vgabuffer: Unique, +} + +struct VScreen { + column_position: usize, + pub color_code: ColorCode, + buffer: Buffer, +} + macro_rules! println { ($fmt:expr) => (print!(concat!($fmt, "\n"))); ($fmt:expr, $($arg:tt)*) => (print!(concat!($fmt, "\n"), $($arg)*)); @@ -39,7 +40,7 @@ macro_rules! println { macro_rules! print { ($($arg:tt)*) => ({ - $crate::vga_buffer::print(format_args!($($arg)*)); + $crate::vga_buffer::print(format_args!($($arg)*)); }); } @@ -48,9 +49,75 @@ pub fn print(args: fmt::Arguments) { WRITER.lock().write_fmt(args).unwrap(); } -pub fn clear_screen() { - for _ in 0..BUFFER_HEIGHT { - println!(""); +impl Writer { + pub fn reset_screen(&mut self) + { + let color_code = self.color_code; + for row in 1..BUFFER_HEIGHT { + for col in 0..BUFFER_WIDTH { + self.buffer().chars[row][col].write(ScreenChar { + ascii_character: b' ', + color_code, + }); + } + } + self.column_position = 0; + } + + pub fn write_byte(&mut self, byte: u8) { + match byte { + b'\n' => self.new_line(), + byte => { + if self.column_position >= BUFFER_WIDTH { + self.new_line(); + } + let row = BUFFER_HEIGHT - 1; + let col = self.column_position; + + let color_code = self.color_code; + + self.buffer().chars[row][col].write(ScreenChar { + ascii_character: byte, + color_code: color_code, + }); + self.column_position += 1; + } + } + } + + fn buffer(&mut self) -> &mut Buffer { + unsafe { self.vgabuffer.as_mut() } + } + + fn new_line(&mut self) { + for row in 1..BUFFER_HEIGHT { + for col in 0..BUFFER_WIDTH { + let buffer = self.buffer(); + let character = buffer.chars[row][col].read(); + buffer.chars[row - 1][col].write(character); + } + } + self.clear_row(BUFFER_HEIGHT - 1); + self.column_position = 0; + } + + fn clear_row(&mut self, row: usize) { + let blank = ScreenChar { + ascii_character: b' ', + color_code: ColorCode::new(Color::White, Color::Black), + }; + for col in 0..BUFFER_WIDTH { + self.buffer().chars[row][col].write(blank); + } + } +} + +impl fmt::Write for Writer { + fn write_str(&mut self, s: &str) -> ::core::fmt::Result { + for byte in s.bytes() { + self.write_byte(byte) + } + Ok(()) } } @@ -76,70 +143,11 @@ pub enum Color { White = 15, } -pub struct Writer { - column_position: usize, - color_code: ColorCode, -} - -impl Writer { - pub fn write_byte(&mut self, byte: u8) { - match byte { - b'\n' => self.new_line(), - byte => { - if self.column_position >= BUFFER_WIDTH { - self.new_line(); - } - let row = BUFFER_HEIGHT - 1; - let col = self.column_position; - - let color_code = self.color_code; - - vga_buffer().chars[row][col].write(ScreenChar { - ascii_character: byte, - color_code: color_code, - }); - self.column_position += 1; - } - } - } - - fn new_line(&mut self) { - for row in 1..BUFFER_HEIGHT { - for col in 0..BUFFER_WIDTH { - let buffer = vga_buffer(); - let character = buffer.chars[row][col].read(); - buffer.chars[row - 1][col].write(character); - } - } - self.clear_row(BUFFER_HEIGHT - 1); - self.column_position = 0; - } - - fn clear_row(&mut self, row: usize) { - let blank = ScreenChar { - ascii_character: b' ', - color_code: self.color_code, - }; - for col in 0..BUFFER_WIDTH { - vga_buffer().chars[row][col].write(blank); - } - } -} - -impl fmt::Write for Writer { - fn write_str(&mut self, s: &str) -> ::core::fmt::Result { - for byte in s.bytes() { - self.write_byte(byte) - } - Ok(()) - } -} - #[derive(Debug, Clone, Copy)] -struct ColorCode(u8); +pub struct ColorCode(u8); impl ColorCode { - const fn new(foreground: Color, background: Color) -> ColorCode { + pub const fn new(foreground: Color, background: Color) -> ColorCode { ColorCode((background as u8) << 4 | (foreground as u8)) } } @@ -150,3 +158,7 @@ struct ScreenChar { ascii_character: u8, color_code: ColorCode, } + +struct Buffer { + chars: [[Volatile; BUFFER_WIDTH]; BUFFER_HEIGHT], +}