Log on tty (serial and vga)
This commit is contained in:
@@ -1,26 +1,26 @@
|
|||||||
use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut};
|
use crate::io;
|
||||||
|
|
||||||
#[path = "unsupported.rs"]
|
#[path = "unsupported.rs"]
|
||||||
mod unsupported;
|
mod unsupported;
|
||||||
pub use self::unsupported::{STDIN_BUF_SIZE, Stderr, Stdin, is_ebadf};
|
pub use self::unsupported::{STDIN_BUF_SIZE, Stderr, is_ebadf};
|
||||||
|
|
||||||
pub struct Stdout;
|
pub struct Stdout;
|
||||||
// pub struct Stdin;
|
pub struct Stdin;
|
||||||
|
|
||||||
impl Stdout {
|
impl Stdout {
|
||||||
pub const fn new() -> Self {
|
pub const fn new() -> Self {
|
||||||
Self
|
Self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// impl Stdin {
|
impl Stdin {
|
||||||
// pub const fn new() -> Self {
|
pub const fn new() -> Self {
|
||||||
// Self
|
Self
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
impl io::Write for Stdout {
|
impl io::Write for Stdout {
|
||||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||||
unsafe { Ok(write(1, buf) as usize) }
|
Ok(write(1, buf) as usize)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn flush(&mut self) -> io::Result<()> {
|
fn flush(&mut self) -> io::Result<()> {
|
||||||
@@ -29,12 +29,11 @@ impl io::Write for Stdout {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// impl io::Read for Stdin {
|
impl io::Read for Stdin {
|
||||||
// fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||||
// Ok(0)
|
Ok(read(0, buf) as usize)
|
||||||
// // unsafe { Ok(read(0, buf) as usize) }
|
}
|
||||||
// }
|
}
|
||||||
// }
|
|
||||||
|
|
||||||
pub fn panic_output() -> Option<impl io::Write> {
|
pub fn panic_output() -> Option<impl io::Write> {
|
||||||
// Todo, use Stderr
|
// Todo, use Stderr
|
||||||
|
|||||||
@@ -9,18 +9,7 @@ use log::info;
|
|||||||
use shared::syscall::SysCall;
|
use shared::syscall::SysCall;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
boot::sbi::{ExtensionID, TimerFunctionID},
|
boot::sbi::{ExtensionID, TimerFunctionID}, clear_csr, drivers::{keyboard::KBD_DRIVER, mouse::MOUSE_DRIVER}, println, process::{ExecutionContext, exit_process, sleep}, read_csr, riscv::{disable_interrupt, dump_cpu}, scheduler::SCHEDULER, set_csr, syscall, time::{IRQ_M_EXTERNAL, IRQ_M_TIMER, setup_next_timer_interrupt}, virtio::input::HANDLING_INTERRUPT, virtual_fs::{FILE_SYSTEM, VirtualFileSystem}, write_csr
|
||||||
clear_csr,
|
|
||||||
drivers::{keyboard::KBD_DRIVER, mouse::MOUSE_DRIVER},
|
|
||||||
process::{ExecutionContext, exit_process, sleep},
|
|
||||||
read_csr,
|
|
||||||
riscv::{disable_interrupt, dump_cpu},
|
|
||||||
scheduler::SCHEDULER,
|
|
||||||
set_csr, syscall,
|
|
||||||
time::{IRQ_M_EXTERNAL, IRQ_M_TIMER, setup_next_timer_interrupt},
|
|
||||||
virtio::input::HANDLING_INTERRUPT,
|
|
||||||
virtual_fs::{FILE_SYSTEM, VirtualFileSystem},
|
|
||||||
write_csr,
|
|
||||||
};
|
};
|
||||||
use core::{alloc::Layout, arch::naked_asm, time::Duration};
|
use core::{alloc::Layout, arch::naked_asm, time::Duration};
|
||||||
|
|
||||||
@@ -185,6 +174,7 @@ unsafe extern "C" fn supervisor_trap_handler(
|
|||||||
let buf =
|
let buf =
|
||||||
unsafe { core::slice::from_raw_parts_mut(a2 as *mut u8, a3 as usize) };
|
unsafe { core::slice::from_raw_parts_mut(a2 as *mut u8, a3 as usize) };
|
||||||
|
|
||||||
|
|
||||||
let mut scheduler = SCHEDULER.lock();
|
let mut scheduler = SCHEDULER.lock();
|
||||||
let current_process = scheduler.get_current_process();
|
let current_process = scheduler.get_current_process();
|
||||||
let vnode = current_process.fd_table[fd as usize].as_mut().unwrap();
|
let vnode = current_process.fd_table[fd as usize].as_mut().unwrap();
|
||||||
|
|||||||
34
src/io.rs
34
src/io.rs
@@ -2,8 +2,12 @@
|
|||||||
//!
|
//!
|
||||||
//! Provides a lightweight logger implementation routing to UART and helper
|
//! Provides a lightweight logger implementation routing to UART and helper
|
||||||
//! macros for printing from kernel code.
|
//! macros for printing from kernel code.
|
||||||
use crate::println;
|
|
||||||
|
|
||||||
|
use crate::print;
|
||||||
|
use crate::tty::{TTY_INITIALIZED, TTY0};
|
||||||
|
|
||||||
|
use alloc::format;
|
||||||
|
use io::Write;
|
||||||
use log::{Level, Metadata, Record};
|
use log::{Level, Metadata, Record};
|
||||||
use log::{LevelFilter, SetLoggerError};
|
use log::{LevelFilter, SetLoggerError};
|
||||||
|
|
||||||
@@ -14,11 +18,15 @@ use crate::uart::write_uart;
|
|||||||
/// Accepts any type that implements `AsRef<str>` to avoid unnecessary
|
/// Accepts any type that implements `AsRef<str>` to avoid unnecessary
|
||||||
/// allocations at call sites.
|
/// allocations at call sites.
|
||||||
pub(crate) fn print<T: AsRef<str>>(content: T) {
|
pub(crate) fn print<T: AsRef<str>>(content: T) {
|
||||||
write_uart(content);
|
if TTY_INITIALIZED.load(core::sync::atomic::Ordering::Relaxed) {
|
||||||
|
unsafe { TTY0.new_node().write(content.as_ref().as_bytes()).unwrap() };
|
||||||
|
} else {
|
||||||
|
write_uart(&content);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Logger implementation that routes kernel log records to the UART-based console.
|
/// Logger implementation that routes kernel log records to the UART-based console.
|
||||||
struct Logger;
|
pub struct Logger;
|
||||||
|
|
||||||
impl log::Log for Logger {
|
impl log::Log for Logger {
|
||||||
fn enabled(&self, metadata: &Metadata) -> bool {
|
fn enabled(&self, metadata: &Metadata) -> bool {
|
||||||
@@ -27,24 +35,25 @@ impl log::Log for Logger {
|
|||||||
|
|
||||||
fn log(&self, record: &Record) {
|
fn log(&self, record: &Record) {
|
||||||
if self.enabled(record.metadata()) {
|
if self.enabled(record.metadata()) {
|
||||||
if let Some((file, line)) = record.file().zip(record.line()) {
|
let to_print = if let Some((file, line)) = record.file().zip(record.line()) {
|
||||||
println!(
|
format!(
|
||||||
"[{}] at {}:{} - {}",
|
"[{}] at {}:{} - {}\n",
|
||||||
record.level(),
|
record.level(),
|
||||||
file,
|
file,
|
||||||
line,
|
line,
|
||||||
record.args()
|
record.args()
|
||||||
);
|
)
|
||||||
} else {
|
} else {
|
||||||
println!("[{}] - {}", record.level(), record.args());
|
format!("[{}] - {}\n", record.level(), record.args())
|
||||||
}
|
};
|
||||||
|
print!("{to_print}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn flush(&self) {}
|
fn flush(&self) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
static LOGGER: Logger = Logger;
|
pub static LOGGER: Logger = Logger;
|
||||||
|
|
||||||
/// Initialize the kernel logger and set the default level.
|
/// Initialize the kernel logger and set the default level.
|
||||||
///
|
///
|
||||||
@@ -62,10 +71,9 @@ macro_rules! print {
|
|||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! println {
|
macro_rules! println {
|
||||||
() => {
|
() => {
|
||||||
$crate::print!("\n\r")
|
$crate::print!("\n")
|
||||||
};
|
};
|
||||||
($($args:expr),*) => {{
|
($($args:expr),*) => {{
|
||||||
$crate::print!($($args),*);
|
$crate::print!("{}\n", alloc::format!($($args),*));
|
||||||
$crate::println!();
|
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -94,33 +94,33 @@ pub const fn map_keycode(code: u16, state: &KeyboardState) -> KeyType {
|
|||||||
} else {
|
} else {
|
||||||
if state.alt_gr_modifier {
|
if state.alt_gr_modifier {
|
||||||
match code {
|
match code {
|
||||||
// KEY_1 => KeyType::Ascii('—'),
|
// KEY_1 => KeyType::Ascii('—'),
|
||||||
KEY_2 => KeyType::Ascii('<'),
|
KEY_2 => KeyType::Ascii('<'),
|
||||||
KEY_3 => KeyType::Ascii('>'),
|
KEY_3 => KeyType::Ascii('>'),
|
||||||
KEY_4 => KeyType::Ascii('['),
|
KEY_4 => KeyType::Ascii('['),
|
||||||
KEY_5 => KeyType::Ascii(']'),
|
KEY_5 => KeyType::Ascii(']'),
|
||||||
KEY_6 => KeyType::Ascii('^'),
|
KEY_6 => KeyType::Ascii('^'),
|
||||||
KEY_7 => KeyType::Ascii('±'),
|
KEY_7 => KeyType::Ascii('±'),
|
||||||
// KEY_8 => KeyType::Ascii('−'),
|
// KEY_8 => KeyType::Ascii('−'),
|
||||||
KEY_9 => KeyType::Ascii('÷'),
|
KEY_9 => KeyType::Ascii('÷'),
|
||||||
KEY_0 => KeyType::Ascii('×'),
|
KEY_0 => KeyType::Ascii('×'),
|
||||||
// KEY_MINUS => KeyType::Ascii('≠'),
|
KEY_MINUS => KeyType::Ascii('≠'),
|
||||||
// KEY_EQUAL => KeyType::Ascii('‰'),
|
KEY_EQUAL => KeyType::Ascii('‰'),
|
||||||
KEY_Q => KeyType::Ascii('|'),
|
KEY_Q => KeyType::Ascii('|'),
|
||||||
// KEY_W => KeyType::Ascii(''),
|
// KEY_W => KeyType::Ascii(''),
|
||||||
KEY_E => KeyType::Ascii('&'),
|
KEY_E => KeyType::Ascii('&'),
|
||||||
KEY_R => KeyType::Ascii('œ'),
|
KEY_R => KeyType::Ascii('œ'),
|
||||||
// KEY_T => KeyType::Ascii(''),
|
// KEY_T => KeyType::Ascii(''),
|
||||||
KEY_Y => KeyType::Ascii('¡'),
|
KEY_Y => KeyType::Ascii('¡'),
|
||||||
// KEY_U => KeyType::Ascii(''),
|
// KEY_U => KeyType::Ascii(''),
|
||||||
KEY_I => KeyType::Ascii('ð'),
|
KEY_I => KeyType::Ascii('ð'),
|
||||||
// KEY_O => KeyType::Ascii(''),
|
// KEY_O => KeyType::Ascii(''),
|
||||||
KEY_P => KeyType::Ascii('ij'),
|
KEY_P => KeyType::Ascii('ij'),
|
||||||
KEY_A => KeyType::Ascii('æ'),
|
KEY_A => KeyType::Ascii('æ'),
|
||||||
KEY_S => KeyType::Ascii('ù'),
|
KEY_S => KeyType::Ascii('ù'),
|
||||||
// KEY_D => KeyType::Ascii(''),
|
// KEY_D => KeyType::Ascii(''),
|
||||||
// KEY_F => KeyType::Ascii('€'),
|
// KEY_F => KeyType::Ascii('€'),
|
||||||
// KEY_G => KeyType::Ascii('’'),
|
// KEY_G => KeyType::Ascii('’'),
|
||||||
KEY_H => KeyType::Ascii('©'),
|
KEY_H => KeyType::Ascii('©'),
|
||||||
KEY_J => KeyType::Ascii('þ'),
|
KEY_J => KeyType::Ascii('þ'),
|
||||||
KEY_K => KeyType::Ascii('ß'),
|
KEY_K => KeyType::Ascii('ß'),
|
||||||
@@ -128,17 +128,17 @@ pub const fn map_keycode(code: u16, state: &KeyboardState) -> KeyType {
|
|||||||
KEY_Z => KeyType::Ascii('\\'),
|
KEY_Z => KeyType::Ascii('\\'),
|
||||||
KEY_X => KeyType::Ascii('{'),
|
KEY_X => KeyType::Ascii('{'),
|
||||||
KEY_C => KeyType::Ascii('}'),
|
KEY_C => KeyType::Ascii('}'),
|
||||||
// KEY_V => KeyType::Ascii('…'),
|
// KEY_V => KeyType::Ascii('…'),
|
||||||
KEY_B => KeyType::Ascii('~'),
|
KEY_B => KeyType::Ascii('~'),
|
||||||
KEY_N => KeyType::Ascii('¿'),
|
KEY_N => KeyType::Ascii('¿'),
|
||||||
// KEY_M => KeyType::Ascii(''),
|
// KEY_M => KeyType::Ascii(''),
|
||||||
KEY_LEFTBRACE => KeyType::Ascii('ə'),
|
KEY_LEFTBRACE => KeyType::Ascii('ə'),
|
||||||
// KEY_RIGHTBRACE => KeyType::Ascii(''),
|
// KEY_RIGHTBRACE => KeyType::Ascii(''),
|
||||||
// KEY_SEMICOLON => KeyType::Ascii(''),
|
// KEY_SEMICOLON => KeyType::Ascii(''),
|
||||||
// KEY_APOSTROPHE => KeyType::Ascii(''),
|
// KEY_APOSTROPHE => KeyType::Ascii(''),
|
||||||
// KEY_COMMA => KeyType::Ascii(''),
|
// KEY_COMMA => KeyType::Ascii(''),
|
||||||
// KEY_DOT => KeyType::Ascii('†'),
|
// KEY_DOT => KeyType::Ascii('†'),
|
||||||
// KEY_SLASH => KeyType::Ascii(''),
|
// KEY_SLASH => KeyType::Ascii(''),
|
||||||
_ => KeyType::Unknown,
|
_ => KeyType::Unknown,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
29
src/tty.rs
29
src/tty.rs
@@ -1,4 +1,7 @@
|
|||||||
use core::cell::{LazyCell, RefCell};
|
use core::{
|
||||||
|
cell::{LazyCell, RefCell},
|
||||||
|
sync::atomic::AtomicBool,
|
||||||
|
};
|
||||||
|
|
||||||
use alloc::{boxed::Box, rc::Rc};
|
use alloc::{boxed::Box, rc::Rc};
|
||||||
use io::{IoBase, Read, Seek, Write};
|
use io::{IoBase, Read, Seek, Write};
|
||||||
@@ -10,7 +13,12 @@ use crate::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const TTY_BUFFER_SIZE: usize = 4096; // 4Ko
|
pub const TTY_BUFFER_SIZE: usize = 4096; // 4Ko
|
||||||
pub static mut TTY0: LazyCell<Tty> = LazyCell::new(Tty::new);
|
pub static mut TTY0: LazyCell<Tty> = LazyCell::new(|| {
|
||||||
|
let tty = Tty::new();
|
||||||
|
TTY_INITIALIZED.store(true, core::sync::atomic::Ordering::Relaxed);
|
||||||
|
tty
|
||||||
|
});
|
||||||
|
pub static TTY_INITIALIZED: AtomicBool = AtomicBool::new(false);
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Tty {
|
pub struct Tty {
|
||||||
@@ -25,10 +33,13 @@ impl Tty {
|
|||||||
console: RefCell::new(VirtualConsole::new()).into(),
|
console: RefCell::new(VirtualConsole::new()).into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pub fn new_node(&'_ self) -> TtyNode<'_> {
|
||||||
|
TtyNode { tty: self }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct TtyNode<'a> {
|
pub struct TtyNode<'a> {
|
||||||
tty: &'a Tty,
|
tty: &'a Tty,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,7 +51,7 @@ impl VirtualFileSystem for Tty {
|
|||||||
if !path.is_empty() {
|
if !path.is_empty() {
|
||||||
Err(())
|
Err(())
|
||||||
} else {
|
} else {
|
||||||
Ok(Box::new(TtyNode { tty: self }))
|
Ok(Box::new(self.new_node()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -68,10 +79,12 @@ impl Seek for TtyNode<'_> {
|
|||||||
|
|
||||||
impl Write for TtyNode<'_> {
|
impl Write for TtyNode<'_> {
|
||||||
fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
|
fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
|
||||||
self.tty
|
critical_section::with(|_| {
|
||||||
.console
|
self.tty
|
||||||
.borrow_mut()
|
.console
|
||||||
.write_str(str::from_utf8(buf).unwrap());
|
.borrow_mut()
|
||||||
|
.write_str(str::from_utf8(buf).unwrap());
|
||||||
|
});
|
||||||
Ok(buf.len())
|
Ok(buf.len())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
19
src/vga.rs
19
src/vga.rs
@@ -4,7 +4,7 @@
|
|||||||
//! draw text using an embedded font plate.
|
//! draw text using an embedded font plate.
|
||||||
use log::info;
|
use log::info;
|
||||||
|
|
||||||
use crate::draw::{Color, Draw};
|
use crate::draw::{Color, Draw, FONT_HEIGHT};
|
||||||
|
|
||||||
const PCI_ECAM_BASE_ADDRESS: *mut u32 = 0x30000000 as *mut _;
|
const PCI_ECAM_BASE_ADDRESS: *mut u32 = 0x30000000 as *mut _;
|
||||||
const BOCHS_DISPLAY_BASE_ADDRESS: *mut u32 = 0x50000000 as *mut _;
|
const BOCHS_DISPLAY_BASE_ADDRESS: *mut u32 = 0x50000000 as *mut _;
|
||||||
@@ -58,6 +58,23 @@ impl Vga {
|
|||||||
pub unsafe fn write_u8_unsafe(offset: usize, value: u8) {
|
pub unsafe fn write_u8_unsafe(offset: usize, value: u8) {
|
||||||
unsafe { *(VGA_ADDRESS.byte_add(offset) as *mut u8) = value }
|
unsafe { *(VGA_ADDRESS.byte_add(offset) as *mut u8) = value }
|
||||||
}
|
}
|
||||||
|
pub unsafe fn read_u8_unsafe(offset: usize) -> u8 {
|
||||||
|
unsafe { *(VGA_ADDRESS.byte_add(offset) as *mut u8) }
|
||||||
|
}
|
||||||
|
pub fn line_up(&mut self) {
|
||||||
|
unsafe {
|
||||||
|
core::ptr::copy(
|
||||||
|
VGA_ADDRESS.add(self.get_width() * FONT_HEIGHT),
|
||||||
|
VGA_ADDRESS,
|
||||||
|
self.get_width() * (self.get_height() - FONT_HEIGHT),
|
||||||
|
);
|
||||||
|
for y in self.get_height() - FONT_HEIGHT..self.get_height() {
|
||||||
|
for x in 0..self.get_width() {
|
||||||
|
self.write_pixel_unsafe(x as u16, y as u16, Color::BLACK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Draw for Vga {
|
impl Draw for Vga {
|
||||||
|
|||||||
@@ -3,8 +3,9 @@ use io::SeekFrom;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
draw::{Color, Draw, FONT_HEIGHT, FONT_WIDTH},
|
draw::{Color, Draw, FONT_HEIGHT, FONT_WIDTH},
|
||||||
vga::{self, Vga},
|
uart::write_uart,
|
||||||
virtual_fs::{self, FILE_SYSTEM, VirtualFileSystem},
|
vga::Vga,
|
||||||
|
virtual_fs::{self, VGAFileSystem},
|
||||||
};
|
};
|
||||||
|
|
||||||
const TAB_SIZE: u64 = 4;
|
const TAB_SIZE: u64 = 4;
|
||||||
@@ -31,11 +32,12 @@ impl VirtualConsole {
|
|||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
VirtualConsole {
|
VirtualConsole {
|
||||||
cursor: Cursor::new(),
|
cursor: Cursor::new(),
|
||||||
framebuffer: unsafe { FILE_SYSTEM.open("/dev/fb0".as_ref()).unwrap() },
|
framebuffer: Box::new(VGAFileSystem.open_vga()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_str(&mut self, s: &str) {
|
pub fn write_str(&mut self, s: &str) {
|
||||||
|
write_uart(s);
|
||||||
s.chars().for_each(|c| self.write_char(c));
|
s.chars().for_each(|c| self.write_char(c));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,11 +83,11 @@ impl VirtualConsole {
|
|||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
if self.cursor.x as usize * FONT_WIDTH >= vga::WIDTH {
|
if self.cursor.x as usize * FONT_WIDTH >= self.get_width() {
|
||||||
self.cursor.x = 0;
|
self.cursor.x = 0;
|
||||||
self.cursor.y += 1;
|
self.cursor.y += 1;
|
||||||
}
|
}
|
||||||
if self.cursor.y as usize * FONT_HEIGHT >= vga::HEIGHT {
|
if (self.cursor.y + 1) as usize * FONT_HEIGHT >= self.get_height() {
|
||||||
self.line_up();
|
self.line_up();
|
||||||
if last_cursor.y > 0 {
|
if last_cursor.y > 0 {
|
||||||
last_cursor.y -= 1;
|
last_cursor.y -= 1;
|
||||||
@@ -96,7 +98,13 @@ impl VirtualConsole {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn line_up(&mut self) {}
|
fn line_up(&mut self) {
|
||||||
|
// TODO avoid calling Vga directly
|
||||||
|
Vga.line_up();
|
||||||
|
if self.cursor.y > 0 {
|
||||||
|
self.cursor.y -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
fn move_cursor_line(&mut self, _last: Cursor) {}
|
fn move_cursor_line(&mut self, _last: Cursor) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -75,10 +75,16 @@ pub unsafe fn init_file_system() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct VGAFileSystem;
|
pub struct VGAFileSystem;
|
||||||
|
|
||||||
|
impl VGAFileSystem {
|
||||||
|
pub fn open_vga(&self) -> VGAVirtualNode {
|
||||||
|
VGAVirtualNode { position: 0 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct VGAVirtualNode {
|
pub struct VGAVirtualNode {
|
||||||
position: u64,
|
position: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,8 +109,11 @@ impl Seek for VGAVirtualNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Read for VGAVirtualNode {
|
impl Read for VGAVirtualNode {
|
||||||
fn read(&mut self, _buf: &mut [u8]) -> Result<usize, ()> {
|
fn read(&mut self, buf: &mut [u8]) -> Result<usize, ()> {
|
||||||
todo!()
|
buf.iter_mut().for_each(|val| {
|
||||||
|
*val = unsafe { Vga::read_u8_unsafe(self.position as usize) };
|
||||||
|
});
|
||||||
|
Ok(buf.len())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,7 +137,7 @@ impl VirtualFileSystem for VGAFileSystem {
|
|||||||
if !path.is_empty() {
|
if !path.is_empty() {
|
||||||
Err(())
|
Err(())
|
||||||
} else {
|
} else {
|
||||||
Ok(Box::new(VGAVirtualNode { position: 0 }))
|
Ok(Box::new(self.open_vga()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,34 +1,23 @@
|
|||||||
#![allow(unused)]
|
#![allow(unused)]
|
||||||
|
|
||||||
use core::sync::atomic::AtomicUsize;
|
use core::sync::atomic::AtomicUsize;
|
||||||
use io::{Read as Readio, Write};
|
|
||||||
use shared::{fs::File, syscall};
|
use shared::{fs::File, syscall};
|
||||||
use std::io::{Read, Stdin, stdin};
|
use std::io::{Read, Stdin, Write, stdin, stdout};
|
||||||
|
|
||||||
static FOO: AtomicUsize = AtomicUsize::new(0);
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut input = String::new();
|
|
||||||
input.push('a');
|
|
||||||
// let mut file = syscall::open("/dev/fb0");
|
|
||||||
// syscall::seek(&mut file, SeekFrom::End(-3));
|
|
||||||
// syscall::write(&mut file, &[255; 6400 * 50]);
|
|
||||||
// syscall::sleep(Duration::from_secs_f64(2.0));
|
|
||||||
syscall::close(0);
|
syscall::close(0);
|
||||||
let mut tty = unsafe { File::from_raw_fd(syscall::open("/dev/tty0")) };
|
let mut tty = unsafe { File::from_raw_fd(syscall::open("/dev/tty0")) };
|
||||||
syscall::close(1);
|
syscall::close(1);
|
||||||
let _ = syscall::open("/dev/tty0");
|
let _ = syscall::open("/dev/tty0");
|
||||||
println!("test from test_pic");
|
println!("test from test_pic");
|
||||||
tty.write(input.as_bytes()).unwrap();
|
|
||||||
syscall::spawn("/usr/bin/shell");
|
syscall::spawn("/usr/bin/shell");
|
||||||
// panic!("explicit panic");
|
// panic!("explicit panic");
|
||||||
// std::process::abort();
|
// std::process::abort();
|
||||||
unsafe {core::arch::asm!("unimp")};
|
// unsafe {core::arch::asm!("unimp")};
|
||||||
loop {
|
loop {
|
||||||
let mut test = [0; 2];
|
let mut test = [0; 4];
|
||||||
// let len = stdin().read(&mut test);
|
let len = stdin().read(&mut test).unwrap();
|
||||||
let len = tty.read(&mut test).unwrap();
|
print!("{}", str::from_utf8(&test[..len as usize]).unwrap());
|
||||||
tty.write(str::from_utf8(&test[..len as usize]).unwrap().as_bytes())
|
stdout().flush();
|
||||||
.unwrap();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user