diff --git a/kernel-rs/src/cpuio.rs b/kernel-rs/src/cpuio.rs index 30821f39..148ee020 100644 --- a/kernel-rs/src/cpuio.rs +++ b/kernel-rs/src/cpuio.rs @@ -1,7 +1,3 @@ -//! Rust wrappers around the x86-family I/O instructions. -//! this cmodule uses inline assembly so you need to add -//! `#![feature(asm)]` to yourcrate attributes - #![allow(dead_code)] /// Read a `u8`-sized value from `port`. diff --git a/kernel-rs/src/keyboard.rs b/kernel-rs/src/keyboard.rs index acc65937..e9832de5 100644 --- a/kernel-rs/src/keyboard.rs +++ b/kernel-rs/src/keyboard.rs @@ -2,7 +2,6 @@ extern crate core; use cpuio; use context::CONTEXT; -// use vga::color::{Color, ColorCode}; const MAX_KEYS: usize = 59; const KEYMAP_US: [[u8;2]; MAX_KEYS] = [ diff --git a/kernel-rs/src/lib.rs b/kernel-rs/src/lib.rs index b47e56e6..6ecbf2ee 100644 --- a/kernel-rs/src/lib.rs +++ b/kernel-rs/src/lib.rs @@ -10,11 +10,16 @@ extern crate rlibc; #[macro_use] -mod vga; // 80x25 screen and terminal -mod context; // kernel init and environment -mod keyboard; // PS/2 detection and processing -mod console; // vga terminal commands -mod cpuio; // asm wrapper to cpu i/o +/// 80x25 screen and simplistic terminal driver +pub mod vga; +/// kernel init and environment +pub mod context; +/// PS/2 detection and processing +pub mod keyboard; +/// simplisitc kernel commands +pub mod console; +/// wrappers around the x86-family I/O instructions. +pub mod cpuio; use context::CONTEXT; use vga::{Color, ColorCode}; diff --git a/kernel-rs/src/vga/buffer.rs b/kernel-rs/src/vga/buffer.rs deleted file mode 100644 index 65724e7d..00000000 --- a/kernel-rs/src/vga/buffer.rs +++ /dev/null @@ -1,188 +0,0 @@ -// 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 super::{Color, ColorCode}; -use ::context::CONTEXT; -use cpuio; -use ::console; - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -struct ScreenChar { - ascii_character: u8, - color_code: ColorCode, -} - -macro_rules! print { - ($($arg:tt)*) => ({ - $crate::vga::buffer::print(format_args!($($arg)*)); - }); -} - -macro_rules! println { - ($fmt:expr) => (print!(concat!($fmt, "\n"))); - ($fmt:expr, $($arg:tt)*) => (print!(concat!($fmt, "\n"), $($arg)*)); -} - -pub fn print(args: fmt::Arguments) { - use core::fmt::Write; - unsafe { CONTEXT.current_term().write_fmt(args).unwrap() }; - unsafe { CONTEXT.current_term().flush() }; -} - -extern crate core; - -const BUFFER_ROWS: usize = 25; -const BUFFER_COLS: usize = 80 * 2; - -pub struct Writer { - pub buffer_pos: usize, - pub color_code: ColorCode, - buffer: [u8; BUFFER_ROWS * BUFFER_COLS], - command: [u8; 10], - command_len: usize, -} - -impl Writer { - pub const fn new() -> Writer { - Writer { - buffer_pos: 0, - color_code: ColorCode::new(Color::White, Color::Black), - buffer: [0; BUFFER_ROWS * BUFFER_COLS], - command: [b'\0'; 10], - command_len: 0, - } - } - - pub fn prompt(&mut self) { - let color_code_save = self.color_code; - self.color_code = ColorCode::new(Color::Blue, Color::Black); - self.write_str("> "); - self.color_code = color_code_save; - } - - pub fn backspace(&mut self) { - if self.command_len > 0 { - self.command_len -= 1; - self.erase_byte(); - } - } - - pub fn keypress(&mut self, ascii: u8) { - match ascii { - b'\n' => { - self.write_byte(b'\n'); - { - let command: &str = &core::str::from_utf8(&self.command).unwrap()[..self.command_len]; - match command { - "shutdown" | "halt" => console::shutdown(), - "reboot" => console::reboot(), - "stack" => console::print_kernel_stack(), - _ => { - let color_code_save = self.color_code; - self.color_code = ColorCode::new(Color::Red, Color::Black); - println!("`{}': Command unknown ", command); - self.color_code = color_code_save; - } - } - } - self.command_len = 0; - self.prompt(); - } - byte => { - if self.command_len >= 10 { return }; - - self.command[self.command_len] = byte; - self.write_byte(byte); - self.command_len += 1; - } - } - self.flush(); - } - - pub fn erase_byte(&mut self) { - self.buffer_pos -= 2; - let i = self.buffer_pos; - self.buffer[i] = b' '; - self.buffer[i + 1] = 0; - self.flush(); - } - - pub fn write_byte(&mut self, byte: u8) { - let i = self.buffer_pos; - - match byte { - - b'\n' => { - let current_line = self.buffer_pos / (BUFFER_COLS); - self.buffer_pos = (current_line + 1) * BUFFER_COLS; - } - byte => { - self.buffer[i] = byte; - self.buffer[i + 1] = self.color_code.0; - self.buffer_pos += 2; - } - } - - if self.buffer_pos >= self.buffer.len() { - self.scroll(); - } - } - - fn write_str(&mut self, s: &str) { - for byte in s.bytes() { - self.write_byte(byte) - } - } - - fn flush_cursor(&self) - { - let cursor_position = self.buffer_pos / 2; - // 14 awaits the rightmost 8bits - cpuio::outb(14, 0x3D4); - cpuio::outb((cursor_position >> 8) as u8, 0x3D5); - // 15 awaits the leftmost 8bits - cpuio::outb(15, 0x3D4); - cpuio::outb((cursor_position >> 0) as u8 & 0x00ff, 0x3D5); - } - - pub fn flush(&mut self) { - let slice = unsafe { core::slice::from_raw_parts_mut(0xb8000 as *mut u8, 4000) }; - slice.as_mut().clone_from_slice(&self.buffer); - self.flush_cursor(); - } - - fn scroll(&mut self) { - - for row in 1..BUFFER_ROWS { - for col in 0..BUFFER_COLS { - let prev_position = ((row - 1) * BUFFER_COLS) + col; - let current_position = (row * BUFFER_COLS) + col; - self.buffer[prev_position] = self.buffer[current_position]; - } - } - - for col in 0..BUFFER_COLS/2 { - self.buffer[((BUFFER_ROWS - 1) * BUFFER_COLS) + (col * 2)] = b' '; - } - - self.buffer_pos = (BUFFER_ROWS - 1) * BUFFER_COLS; - } -} - -// trait needed by formatting macros -use core::fmt; -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(()) - } -} diff --git a/kernel-rs/src/vga/mod.rs b/kernel-rs/src/vga/mod.rs index 6d491ba0..f1f95742 100644 --- a/kernel-rs/src/vga/mod.rs +++ b/kernel-rs/src/vga/mod.rs @@ -5,22 +5,182 @@ pub mod color; pub use self::color::{Color, ColorCode}; pub use self::buffer::{Writer}; -// use self::buffer::Writer; -// use core::fmt; -// use core::ptr::Unique; +use super::{Color, ColorCode}; +use ::context::CONTEXT; +use cpuio; +use ::console; -// macro_rules! println { -// ($fmt:expr) => (print!(concat!($fmt, "\n"))); -// ($fmt:expr, $($arg:tt)*) => (print!(concat!($fmt, "\n"), $($arg)*)); -// } +#[derive(Debug, Clone, Copy)] +#[repr(C)] +struct ScreenChar { + ascii_character: u8, + color_code: ColorCode, +} -// macro_rules! print { -// ($($arg:tt)*) => ({ -// $crate::vga::print(format_args!($($arg)*)); -// }); -// } +macro_rules! print { + ($($arg:tt)*) => ({ + $crate::vga::buffer::print(format_args!($($arg)*)); + }); +} -// pub fn print(args: fmt::Arguments) { -// use core::fmt::Write; -// self::WRITER.write_fmt(args).unwrap(); -// } +macro_rules! println { + ($fmt:expr) => (print!(concat!($fmt, "\n"))); + ($fmt:expr, $($arg:tt)*) => (print!(concat!($fmt, "\n"), $($arg)*)); +} + +pub fn print(args: fmt::Arguments) { + use core::fmt::Write; + unsafe { CONTEXT.current_term().write_fmt(args).unwrap() }; + unsafe { CONTEXT.current_term().flush() }; +} + +extern crate core; + +const BUFFER_ROWS: usize = 25; +const BUFFER_COLS: usize = 80 * 2; + +pub struct Writer { + pub buffer_pos: usize, + pub color_code: ColorCode, + buffer: [u8; BUFFER_ROWS * BUFFER_COLS], + command: [u8; 10], + command_len: usize, +} + +impl Writer { + pub const fn new() -> Writer { + Writer { + buffer_pos: 0, + color_code: ColorCode::new(Color::White, Color::Black), + buffer: [0; BUFFER_ROWS * BUFFER_COLS], + command: [b'\0'; 10], + command_len: 0, + } + } + + pub fn prompt(&mut self) { + let color_code_save = self.color_code; + self.color_code = ColorCode::new(Color::Blue, Color::Black); + self.write_str("> "); + self.color_code = color_code_save; + } + + pub fn backspace(&mut self) { + if self.command_len > 0 { + self.command_len -= 1; + self.erase_byte(); + } + } + + pub fn keypress(&mut self, ascii: u8) { + match ascii { + b'\n' => { + self.write_byte(b'\n'); + { + let command: &str = &core::str::from_utf8(&self.command).unwrap()[..self.command_len]; + match command { + "shutdown" | "halt" => console::shutdown(), + "reboot" => console::reboot(), + "stack" => console::print_kernel_stack(), + _ => { + let color_code_save = self.color_code; + self.color_code = ColorCode::new(Color::Red, Color::Black); + println!("`{}': Command unknown ", command); + self.color_code = color_code_save; + } + } + } + self.command_len = 0; + self.prompt(); + } + byte => { + if self.command_len >= 10 { return }; + + self.command[self.command_len] = byte; + self.write_byte(byte); + self.command_len += 1; + } + } + self.flush(); + } + + pub fn erase_byte(&mut self) { + self.buffer_pos -= 2; + let i = self.buffer_pos; + self.buffer[i] = b' '; + self.buffer[i + 1] = 0; + self.flush(); + } + + pub fn write_byte(&mut self, byte: u8) { + let i = self.buffer_pos; + + match byte { + + b'\n' => { + let current_line = self.buffer_pos / (BUFFER_COLS); + self.buffer_pos = (current_line + 1) * BUFFER_COLS; + } + byte => { + self.buffer[i] = byte; + self.buffer[i + 1] = self.color_code.0; + self.buffer_pos += 2; + } + } + + if self.buffer_pos >= self.buffer.len() { + self.scroll(); + } + } + + fn write_str(&mut self, s: &str) { + for byte in s.bytes() { + self.write_byte(byte) + } + } + + fn flush_cursor(&self) + { + let cursor_position = self.buffer_pos / 2; + // 14 awaits the rightmost 8bits + cpuio::outb(14, 0x3D4); + cpuio::outb((cursor_position >> 8) as u8, 0x3D5); + // 15 awaits the leftmost 8bits + cpuio::outb(15, 0x3D4); + cpuio::outb((cursor_position >> 0) as u8 & 0x00ff, 0x3D5); + } + + pub fn flush(&mut self) { + let slice = unsafe { core::slice::from_raw_parts_mut(0xb8000 as *mut u8, 4000) }; + slice.as_mut().clone_from_slice(&self.buffer); + self.flush_cursor(); + } + + fn scroll(&mut self) { + + for row in 1..BUFFER_ROWS { + for col in 0..BUFFER_COLS { + let prev_position = ((row - 1) * BUFFER_COLS) + col; + let current_position = (row * BUFFER_COLS) + col; + self.buffer[prev_position] = self.buffer[current_position]; + } + } + + for col in 0..BUFFER_COLS/2 { + self.buffer[((BUFFER_ROWS - 1) * BUFFER_COLS) + (col * 2)] = b' '; + } + + self.buffer_pos = (BUFFER_ROWS - 1) * BUFFER_COLS; + } +} + +// trait needed by formatting macros +use core::fmt; +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(()) + } +}