Draw on VESA for console using ransid

This commit is contained in:
Jeremy Soller 2016-09-01 11:51:33 -06:00
parent 53c71d9183
commit d7d61f82af
10 changed files with 87 additions and 52 deletions

View file

@ -9,7 +9,6 @@ crate-type = ["staticlib"]
[dependencies] [dependencies]
bitflags = "*" bitflags = "*"
ransid = "*"
spin = "*" spin = "*"
[dependencies.goblin] [dependencies.goblin]

View file

@ -5,6 +5,7 @@ version = "0.1.0"
[dependencies] [dependencies]
bitflags = "*" bitflags = "*"
hole_list_allocator = { path = "../../alloc/hole_list_allocator"} hole_list_allocator = { path = "../../alloc/hole_list_allocator"}
ransid = "*"
spin = "*" spin = "*"
[dependencies.x86] [dependencies.x86]

View file

@ -0,0 +1,26 @@
use core::fmt::{self, Write};
use spin::Mutex;
use device::display::DISPLAY;
use device::serial::COM1;
pub static CONSOLE: Mutex<Console> = 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)
}
}
}

View file

@ -1,6 +1,8 @@
use core::{cmp, slice}; use core::{cmp, slice};
use ransid::Console;
use spin::Mutex; use spin::Mutex;
use externs::memset;
use memory::Frame; use memory::Frame;
use paging::{ActivePageTable, PhysicalAddress, entry}; use paging::{ActivePageTable, PhysicalAddress, entry};
@ -63,11 +65,7 @@ pub unsafe fn init(active_table: &mut ActivePageTable) {
} }
} }
for i in 0..size { memset(start as *mut u8, 0, size * 4);
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);
*DISPLAY.lock() = Some(Display::new(width, height, slice::from_raw_parts_mut(start as *mut u32, size))); *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 width: usize,
pub height: usize, pub height: usize,
pub data: &'static mut [u32], pub data: &'static mut [u32],
console: Console,
} }
impl Display { impl Display {
@ -106,11 +105,12 @@ impl Display {
width: width, width: width,
height: height, height: height,
data: data, data: data,
console: Console::new(width/8, height/16)
} }
} }
/// Draw a rectangle /// 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 start_y = cmp::min(self.height - 1, y);
let end_y = cmp::min(self.height, y + h); let end_y = cmp::min(self.height, y + h);
@ -127,7 +127,7 @@ impl Display {
} }
/// Draw a character /// 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 { if x + 8 <= self.width && y + 16 <= self.height {
let mut offset = y * self.width + x; 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);
}
}
}
}
}
}
} }

View file

@ -104,11 +104,3 @@ impl Write for SerialPort {
Ok(()) Ok(())
} }
} }
pub struct SerialConsole;
impl Write for SerialConsole {
fn write_str(&mut self, s: &str) -> Result<(), fmt::Error> {
COM1.lock().write_str(s)
}
}

View file

@ -4,6 +4,7 @@
#![feature(concat_idents)] #![feature(concat_idents)]
#![feature(const_fn)] #![feature(const_fn)]
#![feature(core_intrinsics)] #![feature(core_intrinsics)]
#![feature(drop_types_in_const)]
#![feature(lang_items)] #![feature(lang_items)]
#![feature(naked_functions)] #![feature(naked_functions)]
#![feature(thread_local)] #![feature(thread_local)]
@ -13,6 +14,7 @@
extern crate hole_list_allocator as allocator; extern crate hole_list_allocator as allocator;
#[macro_use] #[macro_use]
extern crate bitflags; extern crate bitflags;
extern crate ransid;
extern crate spin; extern crate spin;
extern crate x86; extern crate x86;
@ -21,7 +23,7 @@ extern crate x86;
macro_rules! print { macro_rules! print {
($($arg:tt)*) => ({ ($($arg:tt)*) => ({
use core::fmt::Write; 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 /// ACPI table parsing
pub mod acpi; pub mod acpi;
/// Console handling
pub mod console;
/// Context switching /// Context switching
pub mod context; pub mod context;

View file

@ -92,17 +92,11 @@ pub unsafe extern fn kstart() -> ! {
assert_eq!(TDATA_TEST_NONZERO, 0xFFFFFFFFFFFFFFFE); assert_eq!(TDATA_TEST_NONZERO, 0xFFFFFFFFFFFFFFFE);
} }
// Initialize devices
device::init(&mut active_table);
// Reset AP variables // Reset AP variables
AP_COUNT.store(0, Ordering::SeqCst); AP_COUNT.store(0, Ordering::SeqCst);
BSP_READY.store(false, Ordering::SeqCst); BSP_READY.store(false, Ordering::SeqCst);
HEAP_FRAME.store(0, Ordering::SeqCst); HEAP_FRAME.store(0, Ordering::SeqCst);
// Read ACPI tables, starts APs
acpi::init(&mut active_table);
// Map heap // Map heap
{ {
let heap_start_page = Page::containing_address(VirtualAddress::new(HEAP_START)); 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); 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); assert_eq!(TDATA_TEST_NONZERO, 0xFFFFFFFFFFFFFFFE);
} }
// Init devices for AP
device::init_ap(&mut active_table);
// Map heap // Map heap
{ {
let heap_start_page = Page::containing_address(VirtualAddress::new(HEAP_START)); 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); 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); 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(); 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); kmain_ap(ap_number);
} }

View file

@ -1,15 +0,0 @@
use ransid::Console;
use spin::{Once, Mutex, MutexGuard};
/// Console
static CONSOLE: Once<Mutex<Console>> = Once::new();
/// Initialize console, called if needed
fn init_console() -> Mutex<Console> {
Mutex::new(Console::new(0, 0))
}
/// Get the global console
pub fn console() -> MutexGuard<'static, Console> {
CONSOLE.call_once(init_console).lock()
}

View file

@ -80,7 +80,7 @@ impl ContextList {
} }
context.arch.set_stack(stack.as_ptr() as usize + offset); context.arch.set_stack(stack.as_ptr() as usize + offset);
context.kstack = Some(stack); context.kstack = Some(stack);
print!("{}", format!("{}: {:X}\n", context.id, func as usize)); println!("{}: {:X}", context.id, func as usize);
} }
Ok(context_lock) Ok(context_lock)
} }

View file

@ -97,12 +97,8 @@ extern crate collections;
#[macro_use] #[macro_use]
extern crate bitflags; extern crate bitflags;
extern crate goblin; extern crate goblin;
extern crate ransid;
extern crate spin; extern crate spin;
/// Console
pub mod console;
/// Context management /// Context management
pub mod context; pub mod context;
@ -134,7 +130,8 @@ pub extern fn context_test() {
pub extern fn kmain() { pub extern fn kmain() {
context::init(); 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) { if let Ok(_context_lock) = context::contexts_mut().spawn(context_test) {
print!("Spawned context\n"); print!("Spawned context\n");
@ -153,7 +150,8 @@ pub extern fn kmain() {
pub extern fn kmain_ap(id: usize) { pub extern fn kmain_ap(id: usize) {
context::init(); context::init();
print!("{}", format!("AP {}: {:?}\n", id, syscall::getpid())); let pid = syscall::getpid();
println!("AP {}: {:?}", id, pid);
loop { loop {
unsafe { interrupt::enable_and_halt() } unsafe { interrupt::enable_and_halt() }