diff --git a/kernel-rs/Cargo.toml b/kernel-rs/Cargo.toml index 6a7f203c..acbbad72 100644 --- a/kernel-rs/Cargo.toml +++ b/kernel-rs/Cargo.toml @@ -6,7 +6,7 @@ authors = ["Jack Halford ", "William Escande ! { + vga_buffer::clear_screen(); + println!("Kernel startup..."); + + loop { + + } +} + +#[lang = "eh_personality"] #[no_mangle] +pub extern fn eh_personality() { } -#[lang = "panic_fmt"] -extern fn rust_begin_panic() -> ! { +#[lang = "panic_fmt"] #[no_mangle] +pub extern fn panic_fmt( + fmt: core::fmt::Arguments, + file: &'static str, + line: u32) +-> ! { + println!("\n\nPANIC in {} at line {}:", file, line); + println!(" {}", fmt); loop {} } - -#[no_mangle] -pub extern fn kmain() -> ! { - unsafe { - let vga = 0xb8000 as *mut u32; - - *vga = 0x2f592f412f; - - }; - - loop { } - -} diff --git a/kernel-rs/src/vga_buffer.rs b/kernel-rs/src/vga_buffer.rs new file mode 100644 index 00000000..d35903bb --- /dev/null +++ b/kernel-rs/src/vga_buffer.rs @@ -0,0 +1,152 @@ +// Copyright 2016 Philipp Oppermann. See the README.md +// file at the top-level directory of this distribution. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use core::ptr::Unique; +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), +}); + +macro_rules! println { + ($fmt:expr) => (print!(concat!($fmt, "\n"))); + ($fmt:expr, $($arg:tt)*) => (print!(concat!($fmt, "\n"), $($arg)*)); +} + +macro_rules! print { + ($($arg:tt)*) => ({ + $crate::vga_buffer::print(format_args!($($arg)*)); + }); +} + +pub fn print(args: fmt::Arguments) { + use core::fmt::Write; + WRITER.lock().write_fmt(args).unwrap(); +} + +pub fn clear_screen() { + for _ in 0..BUFFER_HEIGHT { + println!(""); + } +} + +#[allow(dead_code)] +#[derive(Debug, Clone, Copy)] +#[repr(u8)] +pub enum Color { + Black = 0, + Blue = 1, + Green = 2, + Cyan = 3, + Red = 4, + Magenta = 5, + Brown = 6, + LightGray = 7, + DarkGray = 8, + LightBlue = 9, + LightGreen = 10, + LightCyan = 11, + LightRed = 12, + Pink = 13, + Yellow = 14, + 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); + +impl ColorCode { + const fn new(foreground: Color, background: Color) -> ColorCode { + ColorCode((background as u8) << 4 | (foreground as u8)) + } +} + +#[derive(Debug, Clone, Copy)] +#[repr(C)] +struct ScreenChar { + ascii_character: u8, + color_code: ColorCode, +} diff --git a/kernel-rs/x86-bluesnow.json b/kernel-rs/x86-bluesnow.json index 73bedb92..6be11f62 100644 --- a/kernel-rs/x86-bluesnow.json +++ b/kernel-rs/x86-bluesnow.json @@ -10,6 +10,6 @@ "target-pointer-width": "32", "target-c-int-width": "32", "features": "-mmx,-fxsr,-sse,-sse2,+soft-float", - "eliminate-frame-pointer": false - + "eliminate-frame-pointer": false, + "panic-strategy": "abort" }