Draw on VESA for console using ransid
This commit is contained in:
parent
53c71d9183
commit
d7d61f82af
|
@ -9,7 +9,6 @@ crate-type = ["staticlib"]
|
|||
|
||||
[dependencies]
|
||||
bitflags = "*"
|
||||
ransid = "*"
|
||||
spin = "*"
|
||||
|
||||
[dependencies.goblin]
|
||||
|
|
|
@ -5,6 +5,7 @@ version = "0.1.0"
|
|||
[dependencies]
|
||||
bitflags = "*"
|
||||
hole_list_allocator = { path = "../../alloc/hole_list_allocator"}
|
||||
ransid = "*"
|
||||
spin = "*"
|
||||
|
||||
[dependencies.x86]
|
||||
|
|
26
arch/x86_64/src/console.rs
Normal file
26
arch/x86_64/src/console.rs
Normal 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)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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() }
|
||||
|
|
Loading…
Reference in a new issue