From d7d61f82af51aad14348a171a2f4c68e8d6cb4ad Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Thu, 1 Sep 2016 11:51:33 -0600 Subject: [PATCH] Draw on VESA for console using ransid --- Cargo.toml | 1 - arch/x86_64/Cargo.toml | 1 + arch/x86_64/src/console.rs | 26 +++++++++++++++++ arch/x86_64/src/device/display.rs | 47 ++++++++++++++++++++++++++----- arch/x86_64/src/device/serial.rs | 8 ------ arch/x86_64/src/lib.rs | 7 ++++- arch/x86_64/src/start.rs | 22 ++++++--------- kernel/console.rs | 15 ---------- kernel/context/mod.rs | 2 +- kernel/lib.rs | 10 +++---- 10 files changed, 87 insertions(+), 52 deletions(-) create mode 100644 arch/x86_64/src/console.rs delete mode 100644 kernel/console.rs diff --git a/Cargo.toml b/Cargo.toml index 661a78f..9817d48 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,6 @@ crate-type = ["staticlib"] [dependencies] bitflags = "*" -ransid = "*" spin = "*" [dependencies.goblin] diff --git a/arch/x86_64/Cargo.toml b/arch/x86_64/Cargo.toml index d1eabb3..c9f00e0 100644 --- a/arch/x86_64/Cargo.toml +++ b/arch/x86_64/Cargo.toml @@ -5,6 +5,7 @@ version = "0.1.0" [dependencies] bitflags = "*" hole_list_allocator = { path = "../../alloc/hole_list_allocator"} +ransid = "*" spin = "*" [dependencies.x86] diff --git a/arch/x86_64/src/console.rs b/arch/x86_64/src/console.rs new file mode 100644 index 0000000..62bd79e --- /dev/null +++ b/arch/x86_64/src/console.rs @@ -0,0 +1,26 @@ +use core::fmt::{self, Write}; +use spin::Mutex; + +use device::display::DISPLAY; +use device::serial::COM1; + +pub static CONSOLE: Mutex = Mutex::new(Console::new()); + +pub struct Console; + +impl Console { + const fn new() -> Self { + Console + } +} + +impl Write for Console { + fn write_str(&mut self, s: &str) -> Result<(), fmt::Error> { + if let Some(ref mut display) = *DISPLAY.lock() { + display.write(s.as_bytes()); + Ok(()) + } else { + COM1.lock().write_str(s) + } + } +} diff --git a/arch/x86_64/src/device/display.rs b/arch/x86_64/src/device/display.rs index 22542a1..2ce458c 100644 --- a/arch/x86_64/src/device/display.rs +++ b/arch/x86_64/src/device/display.rs @@ -1,6 +1,8 @@ use core::{cmp, slice}; +use ransid::Console; use spin::Mutex; +use externs::memset; use memory::Frame; use paging::{ActivePageTable, PhysicalAddress, entry}; @@ -63,11 +65,7 @@ pub unsafe fn init(active_table: &mut ActivePageTable) { } } - for i in 0..size { - let c = ((i * 256)/size) as u32 & 0xFF; - *(start as *mut u32).offset(i as isize) = (c << 16) | (c << 8) | c; - } - //memset(start as *mut u8, 0, size * 4); + memset(start as *mut u8, 0, size * 4); *DISPLAY.lock() = Some(Display::new(width, height, slice::from_raw_parts_mut(start as *mut u32, size))); } @@ -98,6 +96,7 @@ pub struct Display { pub width: usize, pub height: usize, pub data: &'static mut [u32], + console: Console, } impl Display { @@ -106,11 +105,12 @@ impl Display { width: width, height: height, data: data, + console: Console::new(width/8, height/16) } } /// Draw a rectangle - pub fn rect(&mut self, x: usize, y: usize, w: usize, h: usize, color: u32) { + fn rect(&mut self, x: usize, y: usize, w: usize, h: usize, color: u32) { let start_y = cmp::min(self.height - 1, y); let end_y = cmp::min(self.height, y + h); @@ -127,7 +127,7 @@ impl Display { } /// Draw a character - pub fn char(&mut self, x: usize, y: usize, character: char, color: u32) { + fn char(&mut self, x: usize, y: usize, character: char, color: u32) { if x + 8 <= self.width && y + 16 <= self.height { let mut offset = y * self.width + x; @@ -146,4 +146,37 @@ impl Display { } } } + + pub fn write(&mut self, bytes: &[u8]) { + self.console.write(bytes); + if self.console.redraw { + self.console.redraw = false; + + for y in 0..self.console.h { + if self.console.changed[y] { + self.console.changed[y] = false; + + for x in 0..self.console.w { + let block = self.console.display[y * self.console.w + x]; + + let (bg, fg) = if self.console.cursor && self.console.y == y && self.console.x == x { + (block.fg.data, block.bg.data) + }else{ + (block.bg.data, block.fg.data) + }; + + self.rect(x * 8, y * 16, 8, 16, bg); + + if block.c != ' ' { + self.char(x * 8, y * 16, block.c, fg); + } + + if block.underlined { + self.rect(x * 8, y * 16 + 14, 8, 1, fg); + } + } + } + } + } + } } diff --git a/arch/x86_64/src/device/serial.rs b/arch/x86_64/src/device/serial.rs index 4ebc922..872fad1 100644 --- a/arch/x86_64/src/device/serial.rs +++ b/arch/x86_64/src/device/serial.rs @@ -104,11 +104,3 @@ impl Write for SerialPort { Ok(()) } } - -pub struct SerialConsole; - -impl Write for SerialConsole { - fn write_str(&mut self, s: &str) -> Result<(), fmt::Error> { - COM1.lock().write_str(s) - } -} diff --git a/arch/x86_64/src/lib.rs b/arch/x86_64/src/lib.rs index f99030b..ca9d995 100644 --- a/arch/x86_64/src/lib.rs +++ b/arch/x86_64/src/lib.rs @@ -4,6 +4,7 @@ #![feature(concat_idents)] #![feature(const_fn)] #![feature(core_intrinsics)] +#![feature(drop_types_in_const)] #![feature(lang_items)] #![feature(naked_functions)] #![feature(thread_local)] @@ -13,6 +14,7 @@ extern crate hole_list_allocator as allocator; #[macro_use] extern crate bitflags; +extern crate ransid; extern crate spin; extern crate x86; @@ -21,7 +23,7 @@ extern crate x86; macro_rules! print { ($($arg:tt)*) => ({ use core::fmt::Write; - let _ = write!($crate::device::serial::SerialConsole, $($arg)*); + let _ = write!($crate::console::CONSOLE.lock(), $($arg)*); }); } @@ -119,6 +121,9 @@ macro_rules! interrupt_error { /// ACPI table parsing pub mod acpi; +/// Console handling +pub mod console; + /// Context switching pub mod context; diff --git a/arch/x86_64/src/start.rs b/arch/x86_64/src/start.rs index 1988f77..94b6487 100644 --- a/arch/x86_64/src/start.rs +++ b/arch/x86_64/src/start.rs @@ -92,17 +92,11 @@ pub unsafe extern fn kstart() -> ! { assert_eq!(TDATA_TEST_NONZERO, 0xFFFFFFFFFFFFFFFE); } - // Initialize devices - device::init(&mut active_table); - // Reset AP variables AP_COUNT.store(0, Ordering::SeqCst); BSP_READY.store(false, Ordering::SeqCst); HEAP_FRAME.store(0, Ordering::SeqCst); - // Read ACPI tables, starts APs - acpi::init(&mut active_table); - // Map heap { let heap_start_page = Page::containing_address(VirtualAddress::new(HEAP_START)); @@ -129,6 +123,12 @@ pub unsafe extern fn kstart() -> ! { } } + // Initialize devices + device::init(&mut active_table); + + // Read ACPI tables, starts APs + acpi::init(&mut active_table); + BSP_READY.store(true, Ordering::SeqCst); } @@ -165,9 +165,6 @@ pub unsafe extern fn kstart_ap(stack_start: usize, stack_end: usize) -> ! { assert_eq!(TDATA_TEST_NONZERO, 0xFFFFFFFFFFFFFFFE); } - // Init devices for AP - device::init_ap(&mut active_table); - // Map heap { let heap_start_page = Page::containing_address(VirtualAddress::new(HEAP_START)); @@ -187,6 +184,9 @@ pub unsafe extern fn kstart_ap(stack_start: usize, stack_end: usize) -> ! { entry.set(frame, entry::PRESENT | entry::WRITABLE); } } + + // Init devices for AP + device::init_ap(&mut active_table); } let ap_number = AP_COUNT.fetch_add(1, Ordering::SeqCst); @@ -195,9 +195,5 @@ pub unsafe extern fn kstart_ap(stack_start: usize, stack_end: usize) -> ! { interrupt::pause(); } - if let Some(ref mut display) = *device::display::DISPLAY.lock() { - display.char(0, ap_number * 16, (ap_number as u8 + b'0') as char, 0xFF00); - } - kmain_ap(ap_number); } diff --git a/kernel/console.rs b/kernel/console.rs deleted file mode 100644 index d2dfeca..0000000 --- a/kernel/console.rs +++ /dev/null @@ -1,15 +0,0 @@ -use ransid::Console; -use spin::{Once, Mutex, MutexGuard}; - -/// Console -static CONSOLE: Once> = Once::new(); - -/// Initialize console, called if needed -fn init_console() -> Mutex { - Mutex::new(Console::new(0, 0)) -} - -/// Get the global console -pub fn console() -> MutexGuard<'static, Console> { - CONSOLE.call_once(init_console).lock() -} diff --git a/kernel/context/mod.rs b/kernel/context/mod.rs index c5daab2..a706b2f 100644 --- a/kernel/context/mod.rs +++ b/kernel/context/mod.rs @@ -80,7 +80,7 @@ impl ContextList { } context.arch.set_stack(stack.as_ptr() as usize + offset); context.kstack = Some(stack); - print!("{}", format!("{}: {:X}\n", context.id, func as usize)); + println!("{}: {:X}", context.id, func as usize); } Ok(context_lock) } diff --git a/kernel/lib.rs b/kernel/lib.rs index 9aae7c1..8291035 100644 --- a/kernel/lib.rs +++ b/kernel/lib.rs @@ -97,12 +97,8 @@ extern crate collections; #[macro_use] extern crate bitflags; extern crate goblin; -extern crate ransid; extern crate spin; -/// Console -pub mod console; - /// Context management pub mod context; @@ -134,7 +130,8 @@ pub extern fn context_test() { pub extern fn kmain() { context::init(); - print!("{}", format!("BSP: {:?}\n", syscall::getpid())); + let pid = syscall::getpid(); + println!("BSP: {:?}", pid); if let Ok(_context_lock) = context::contexts_mut().spawn(context_test) { print!("Spawned context\n"); @@ -153,7 +150,8 @@ pub extern fn kmain() { pub extern fn kmain_ap(id: usize) { context::init(); - print!("{}", format!("AP {}: {:?}\n", id, syscall::getpid())); + let pid = syscall::getpid(); + println!("AP {}: {:?}", id, pid); loop { unsafe { interrupt::enable_and_halt() }