From e70cac58c85f1b3bf90b1a01c62a3dd8b9159bf4 Mon Sep 17 00:00:00 2001 From: WangRunji Date: Sat, 16 Mar 2019 13:15:16 +0800 Subject: [PATCH] refactor x86_64 VGA using console-traits crate --- kernel/Cargo.lock | 7 ++ kernel/Cargo.toml | 6 +- kernel/src/arch/x86_64/driver/vga.rs | 108 +++++++++++++++++++-------- 3 files changed, 85 insertions(+), 36 deletions(-) diff --git a/kernel/Cargo.lock b/kernel/Cargo.lock index 785fb39..9ea4fbc 100644 --- a/kernel/Cargo.lock +++ b/kernel/Cargo.lock @@ -104,6 +104,11 @@ name = "cfg-if" version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "console-traits" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "deque" version = "0.3.2" @@ -259,6 +264,7 @@ dependencies = [ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "bootloader 0.3.14 (git+https://github.com/wangrunji0408/bootloader)", "cc 1.0.30 (registry+https://github.com/rust-lang/crates.io-index)", + "console-traits 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "device_tree 1.0.3 (git+https://github.com/jiegec/device_tree-rs)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "linked_list_allocator 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -537,6 +543,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb" "checksum cc 1.0.30 (registry+https://github.com/rust-lang/crates.io-index)" = "d01c69d08ff207f231f07196e30f84c70f1c815b04f980f8b7b01ff01f05eb92" "checksum cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11d43355396e872eefb45ce6342e4374ed7bc2b3a502d1b28e36d6e23c05d1f4" +"checksum console-traits 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f711b3d1d5c3f7ae7d6428901c0f3e5d5f5c800fcfac86bf0252e96373a2cec6" "checksum deque 0.3.2 (git+https://github.com/wangrunji0408/deque.git?branch=no_std)" = "" "checksum device_tree 1.0.3 (git+https://github.com/jiegec/device_tree-rs)" = "" "checksum fixedvec 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7c6c16d316ccdac21a4dd648e314e76facbbaf316e83ca137d0857a9c07419d0" diff --git a/kernel/Cargo.toml b/kernel/Cargo.toml index b8b5d68..c978b56 100644 --- a/kernel/Cargo.toml +++ b/kernel/Cargo.toml @@ -37,9 +37,6 @@ link_user = [] # MUST >= 1 : Enable RVO to avoid stack overflow opt-level = 1 -[profile.release] -debug = true - [dependencies] log = "0.4" spin = "0.5" @@ -48,9 +45,10 @@ xmas-elf = "0.6" bitflags = "1.0" bit_field = "0.9" volatile = "0.2" +console-traits = "0.3" linked_list_allocator = "0.6" device_tree = { git = "https://github.com/jiegec/device_tree-rs" } -lazy_static = { version = "1.2", features = ["spin_no_std"] } +lazy_static = { version = "1.3", features = ["spin_no_std"] } smoltcp = { version = "0.5.0", default-features = false, features = ["alloc", "log", "proto-ipv4", "proto-igmp", "socket-icmp", "socket-udp", "socket-tcp", "socket-raw"] } bit-allocator = { path = "../crate/bit-allocator" } rcore-memory = { path = "../crate/memory" } diff --git a/kernel/src/arch/x86_64/driver/vga.rs b/kernel/src/arch/x86_64/driver/vga.rs index 11f79d7..1ea7e8e 100644 --- a/kernel/src/arch/x86_64/driver/vga.rs +++ b/kernel/src/arch/x86_64/driver/vga.rs @@ -5,6 +5,7 @@ use lazy_static::lazy_static; use x86_64::instructions::port::Port; use crate::logging::Color; use crate::consts::KERNEL_OFFSET; +use console_traits::*; #[derive(Debug, Clone, Copy)] struct ColorCode(u8); @@ -74,44 +75,60 @@ lazy_static! { } pub struct VgaWriter { - column_position: usize, + pos: Position, color: Color, + ctrl_char_mode: ControlCharMode, + esc_char_mode: EscapeCharMode, buffer: &'static mut VgaBuffer, } -impl VgaWriter { - fn new(buffer: &'static mut VgaBuffer) -> Self { - buffer.clear(); - VgaWriter { - column_position: 0, - color: Color::LightGray, - buffer, - } +impl BaseConsole for VgaWriter { + type Error = (); + + fn get_width(&self) -> Col { + Col(BUFFER_WIDTH as u8 - 1) } - pub fn set_color(&mut self, color: Color) { - self.color = color; + fn get_height(&self) -> Row { + Row(BUFFER_HEIGHT as u8 - 1) + } + + fn set_col(&mut self, col: Col) -> Result<(), Self::Error> { + self.pos.col = col; + Ok(()) } - 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(); - } + fn set_row(&mut self, row: Row) -> Result<(), Self::Error> { + self.pos.row = row; + Ok(()) + } - let row = BUFFER_HEIGHT - 1; - let col = self.column_position; + fn set_pos(&mut self, pos: Position) -> Result<(), Self::Error> { + self.pos = pos; + Ok(()) + } - self.buffer.write(row, col, ScreenChar::new(byte, self.color, Color::Black)); - self.column_position += 1; - self.buffer.set_cursor_at(row, col); - } - } + fn get_pos(&self) -> Position { + self.pos } - fn new_line(&mut self) { + fn set_control_char_mode(&mut self, mode: ControlCharMode) { + self.ctrl_char_mode = mode; + } + + fn get_control_char_mode(&self) -> ControlCharMode { + self.ctrl_char_mode + } + + fn set_escape_char_mode(&mut self, mode: EscapeCharMode) { + self.esc_char_mode = mode; + } + + fn get_escape_char_mode(&self) -> EscapeCharMode { + self.esc_char_mode + } + + fn scroll_screen(&mut self) -> Result<(), Self::Error> { for row in 1..BUFFER_HEIGHT { for col in 0..BUFFER_WIDTH { let screen_char = self.buffer.read(row, col); @@ -122,16 +139,43 @@ impl VgaWriter { for col in 0..BUFFER_WIDTH { self.buffer.write(BUFFER_HEIGHT - 1, col, blank); } - self.column_position = 0; self.buffer.set_cursor_at(BUFFER_HEIGHT - 1, 0); + Ok(()) + } +} + +impl AsciiConsole for VgaWriter { + fn write_char_at(&mut self, ch: u8, pos: Position) -> Result<(), Self::Error> { + self.buffer.write(pos.row.0 as usize, pos.col.0 as usize, ScreenChar::new(ch, self.color, Color::Black)); + self.buffer.set_cursor_at(pos.row.0 as usize, pos.col.0 as usize); + Ok(()) + } + + fn handle_escape(&mut self, escaped_char: u8) -> bool { + true + } +} + +impl VgaWriter { + fn new(buffer: &'static mut VgaBuffer) -> Self { + buffer.clear(); + VgaWriter { + pos: Position::origin(), + color: Color::LightGray, + ctrl_char_mode: ControlCharMode::Interpret, + esc_char_mode: EscapeCharMode::Waiting, + buffer, + } + } + + pub fn set_color(&mut self, color: Color) { + self.color = color; } } impl fmt::Write for VgaWriter { fn write_str(&mut self, s: &str) -> fmt::Result { - for byte in s.bytes() { - self.write_byte(byte) - } - Ok(()) + self.write_string(s.as_bytes()) + .map_err(|_| fmt::Error) } -} \ No newline at end of file +}