diff --git a/ableos/Cargo.toml b/ableos/Cargo.toml index aafb66b1..194afcc7 100644 --- a/ableos/Cargo.toml +++ b/ableos/Cargo.toml @@ -52,7 +52,6 @@ bitflags = "1.2.1" linked_list_allocator = "0.9.0" lliw = "0.2.0" spin = "0.9" -log = "0.4.17" pretty-hex = "0.2.1" unicode-width = "0.1.7" picorand = "0.1.0" @@ -64,6 +63,12 @@ axel = { git = "https://git.ablecorp.us/able/aos_userland" } versioning = { git = "https://git.ablecorp.us/able/aos_userland" } # embedded-graphics = "*" pc-keyboard = "0.5" +# mini-backtrace = "0.1" + +[dependencies.log] +version = "0.4.17" +default-features = false + [dependencies.logos] version = "0.12" diff --git a/ableos/debug.log b/ableos/debug.log new file mode 100644 index 00000000..e69de29b diff --git a/ableos/src/arch/x86_64/drivers/serial.rs b/ableos/src/arch/x86_64/drivers/serial.rs index fb5eb18f..64eee688 100644 --- a/ableos/src/arch/x86_64/drivers/serial.rs +++ b/ableos/src/arch/x86_64/drivers/serial.rs @@ -10,10 +10,12 @@ pub static SERIAL1: Lazy> = Lazy::new(|| { #[doc(hidden)] pub fn _print(args: ::core::fmt::Arguments) { use core::fmt::Write; + // /* SERIAL1 .lock() .write_fmt(args) .expect("Printing to serial failed"); + // */ } /// Prints to the host through the serial interface. diff --git a/ableos/src/arch/x86_64/drivers/vga.rs b/ableos/src/arch/x86_64/drivers/vga.rs index 3fcde939..8b137891 100644 --- a/ableos/src/arch/x86_64/drivers/vga.rs +++ b/ableos/src/arch/x86_64/drivers/vga.rs @@ -1,162 +1 @@ -use core::fmt; -use spin::{Lazy, Mutex}; -use volatile::Volatile; -const BUFFER_HEIGHT: usize = 25; -const BUFFER_WIDTH: usize = 80; - -#[allow(dead_code)] -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -#[repr(u8)] -pub enum Color { - Black = 0, - Blue = 1, - Green = 2, - Cyan = 3, - Red = 4, - Magenta = 5, - Brown = 6, - LightGray = 7, - DarkGray = 8, - LightBlue = 9, - LightGreen = 10, - LightCyan = 11, - LightRed = 12, - Pink = 13, - Yellow = 14, - White = 15, -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -#[repr(transparent)] -struct ColorCode(u8); -impl ColorCode { - const fn new(foreground: Color, background: Color) -> ColorCode { - ColorCode((background as u8) << 4 | (foreground as u8)) - } -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -#[repr(C)] -struct ScreenChar { - ascii_character: u8, - color_code: ColorCode, -} - -#[repr(transparent)] -struct Buffer { - chars: [[Volatile; BUFFER_WIDTH]; BUFFER_HEIGHT], -} - -pub struct Writer { - column_position: usize, - color_code: ColorCode, - buffer: &'static mut Buffer, -} - -impl Writer { - 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(); - } - let row = BUFFER_HEIGHT - 1; - let col = self.column_position; - let color_code = self.color_code; - self.buffer.chars[row][col].write(ScreenChar { - ascii_character: byte, - color_code, - }); - self.column_position += 1; - } - } - } - - pub fn write_string(&mut self, s: &str) { - for byte in s.bytes() { - match byte { - // printable ASCII byte or newline - 0x20..=0x7e | b'\n' => self.write_byte(byte), - // not part of printable ASCII range - _ => self.write_byte(0xfe), - } - } - } - - fn new_line(&mut self) { - for row in 1..BUFFER_HEIGHT { - for col in 0..BUFFER_WIDTH { - let character = self.buffer.chars[row][col].read(); - self.buffer.chars[row - 1][col].write(character); - } - } - self.clear_row(BUFFER_HEIGHT - 1); - self.column_position = 0; - } - - fn clear_row(&mut self, row: usize) { - let blank = ScreenChar { - ascii_character: b' ', - color_code: self.color_code, - }; - for col in 0..BUFFER_WIDTH { - self.buffer.chars[row][col].write(blank); - } - } - - pub fn backspace(&mut self) { - let col_pos = self.column_position; - if col_pos == 0 { - } else { - self.column_position -= 1; - - let blank = ScreenChar { - ascii_character: b' ', - color_code: self.color_code, - }; - - self.buffer.chars[BUFFER_HEIGHT - 1][col_pos - 1].write(blank); - } - } -} - -impl fmt::Write for Writer { - fn write_str(&mut self, s: &str) -> fmt::Result { - self.write_string(s); - Ok(()) - } -} - -pub static WRITER: Lazy> = Lazy::new(|| { - Mutex::new(Writer { - column_position: 0, - color_code: ColorCode::new(Color::White, Color::Black), - buffer: unsafe { &mut *(0xb8000 as *mut Buffer) }, - }) -}); - -#[macro_export] -macro_rules! kprint { - ($($arg:tt)*) => ($crate::arch::drivers::vga::_kprint(format_args!($($arg)*))); -} - -#[macro_export] -macro_rules! kprintln { - () => ($crate::kprint!("\n")); - ($($arg:tt)*) => ($crate::kprint!("{}\n", format_args!($($arg)*))); -} - -#[doc(hidden)] -pub fn _kprint(args: fmt::Arguments) { - use core::fmt::Write; - use x86_64::instructions::interrupts; - interrupts::without_interrupts(|| { - WRITER.lock().write_fmt(args).unwrap(); - }); -} - -pub fn set_vga_color(fg: Color, bg: Color) { - WRITER.lock().color_code = ColorCode::new(fg, bg); -} diff --git a/ableos/src/arch/x86_64/init.rs b/ableos/src/arch/x86_64/init.rs index f8df89ed..8ecb29b7 100644 --- a/ableos/src/arch/x86_64/init.rs +++ b/ableos/src/arch/x86_64/init.rs @@ -1,6 +1,6 @@ // #![allow(clippy::print_literal)] use super::{drivers::serial, gdt, interrupts}; -use crate::{logger, serial_println}; +use crate::{logger, serial_println, TERM}; /// x86_64 initialization pub fn init() { @@ -17,8 +17,12 @@ pub fn init() { Err(err) => serial_println!("{}", err), } - /* - */ + let mut term = TERM.lock(); + // term.initialize(); + term.set_dirty(true); + term.draw_term(); + drop(term); + gdt::init(); interrupts::init_idt(); diff --git a/ableos/src/arch/x86_64/interrupts.rs b/ableos/src/arch/x86_64/interrupts.rs index 5c5328de..2f5d3896 100644 --- a/ableos/src/arch/x86_64/interrupts.rs +++ b/ableos/src/arch/x86_64/interrupts.rs @@ -1,12 +1,8 @@ use core::panic::PanicInfo; use crate::{ - arch::{drivers::vga::WRITER, gdt}, - image::mono_bitmap::bruh, - kernel_state::KERNEL_STATE, - print, println, - rhai_shell::KEYBUFF, - VgaBuffer, SCREEN_BUFFER, + arch::gdt, image::mono_bitmap::bruh, kernel_state::KERNEL_STATE, print, println, + rhai_shell::KEYBUFF, VgaBuffer, SCREEN_BUFFER, }; use cpuio::outb; use pic8259::ChainedPics; @@ -133,8 +129,9 @@ extern "x86-interrupt" fn keyboard_interrupt_handler(_stack_frame: InterruptStac // Backspace '\u{8}' => { // TODO: Fix this and apply to new term - // WRITER.lock().backspace(); + KEYBUFF.lock().push(8.into()); + print!("\u{8}"); } // '^' => KERNEL_STATE.lock().shutdown(), chr => { diff --git a/ableos/src/kmain.rs b/ableos/src/kmain.rs index fb78a468..4b609ac4 100644 --- a/ableos/src/kmain.rs +++ b/ableos/src/kmain.rs @@ -30,16 +30,18 @@ pub static KERNEL_CONF: Lazy = Lazy::new(KernelConfig::new); pub fn kernel_main() -> ! { init::init(); + // /* if KERNEL_CONF.logging.enabled { log::set_max_level(KERNEL_CONF.log_level()); } else { log::set_max_level(log::LevelFilter::Off); } - let mut term = TERM.lock(); - term.initialize(); - term.set_dirty(true); - term.draw_term(); - drop(term); + // */ + // let mut term = TERM.lock(); + // term.initialize(); + // term.set_dirty(true); + // term.draw_term(); + // drop(term); /* x86_64::instructions::interrupts::without_interrupts(|| { @@ -71,15 +73,19 @@ pub fn kernel_main() -> ! { // for abc in list() { // trace!("{:?}", abc); // } + /* log_version_data(); x86_64::instructions::interrupts::without_interrupts(|| { let mut scheduler = SCHEDULER.lock(); // comment this out to resume normal use // scheduler.enqueue_spawn(traceloop); - scheduler.enqueue_spawn(scratchpad); + // scheduler.enqueue_spawn(scratchpad); }); + // */ + scratchpad(); + sloop() } @@ -141,8 +147,6 @@ pub static TICK: AtomicU64 = AtomicU64::new(0); pub fn tick() { x86_64::instructions::interrupts::without_interrupts(|| { - trace!("ticking time"); - let mut term = TERM.lock(); term.draw_term(); @@ -152,6 +156,5 @@ pub fn tick() { data = data.wrapping_add(1); TICK.store(data, Relaxed); - trace!("time ticked"); }); } diff --git a/ableos/src/print.rs b/ableos/src/print.rs index 3687ee0f..04cac19f 100644 --- a/ableos/src/print.rs +++ b/ableos/src/print.rs @@ -21,8 +21,23 @@ impl core::fmt::Write for Stdout { } #[cfg(target_arch = "x86_64")] fn write_str(&mut self, s: &str) -> Result<(), Error> { + // use mini_backtrace::Backtrace; + use crate::TERM; + // Capture up to 16 frames. This is returned using an ArrayVec that doesn't + // perform any dynamic memory allocation. + /* + let bt = Backtrace::<16>::capture(); + trace!("Backtrace:"); + for frame in bt.frames { + trace!(" {:#x}", frame); + } + if bt.frames_omitted { + trace!(" ... "); + } + */ + trace!("printing"); // x86_64::instructions::interrupts::without_interrupts(|| { let mut term = TERM.lock(); diff --git a/ableos/src/scratchpad.rs b/ableos/src/scratchpad.rs index cf65c57a..818e0b30 100644 --- a/ableos/src/scratchpad.rs +++ b/ableos/src/scratchpad.rs @@ -10,6 +10,7 @@ use crate::handle::Handle; use crate::ipc::IPC; use crate::rhai_shell::shell; use crate::rhai_shell::KEYBUFF; +use crate::unicode_utils::LAMBDA; use crate::vterm::Term; use crate::wasm_jumploader::run_program; use crate::{vgai, SCREEN_BUFFER}; @@ -93,11 +94,13 @@ pub fn acpi() { } pub fn real_shell() { + let prompt = "-> "; + let _current_dir = "/".to_string(); let current_user = "able".to_string(); let mut buf = String::new(); - print!("> "); + print!("{}", prompt); loop { match x86_64::instructions::interrupts::without_interrupts(|| KEYBUFF.lock().pop()) { @@ -112,7 +115,7 @@ pub fn real_shell() { } buf.clear(); - print!("> "); + print!("{}", prompt); } Some('\u{0008}') => { buf.pop(); diff --git a/ableos/src/vterm.rs b/ableos/src/vterm.rs index 4b931723..d955456d 100644 --- a/ableos/src/vterm.rs +++ b/ableos/src/vterm.rs @@ -11,10 +11,14 @@ const CURSOR_COLOR: Color16 = Color16::Cyan; pub struct Term { dirty: bool, term: [char; 80 * 60], - x: usize, + x: u8, } impl Term { pub fn new() -> Self { + let mode = VGAE.lock(); + mode.set_mode(); + drop(mode); + Self { dirty: false, x: 0, @@ -31,12 +35,30 @@ impl Term { pub fn print(&mut self, data: String) { for c in data.chars() { - if self.x == 79 || c == '\n' { + if self.x == 79 { self.move_up(); - self.x = 0; - } else { - self.term[TERM_MINUS_ONE_LINE + self.x] = c; - self.x += 1; + return; + } + + match c { + '\u{08}' => { + if self.x == 0 { + warn!("IMPOSSIBLE BACKSPACE"); + } else { + trace!("BACKSPACE"); + self.x -= 1; + self.term[TERM_MINUS_ONE_LINE + (self.x as usize)] = '\0'; + } + } + '\n' => { + self.move_up(); + self.x = 0; + } + + c => { + self.term[TERM_MINUS_ONE_LINE + (self.x as usize)] = c; + self.x += 1; + } } } } @@ -45,12 +67,13 @@ impl Term { for x in 0..80 { self.term[TERM_MINUS_ONE_LINE + x] = '\0'; } + self.x = 0; } - pub fn initialize(&self) { - let mode = VGAE.lock(); - mode.set_mode(); - drop(mode); - } + // pub fn initialize(&self) { + // let mode = VGAE.lock(); + // mode.set_mode(); + // drop(mode); + // } pub fn draw_term(&mut self) { if self.is_dirty() { @@ -85,7 +108,6 @@ impl Term { for c in self.term { mode.draw_character(x * 8, y * 8, c, Color16::White); - if x == 79 { y += 1; x = 0; diff --git a/repbuild/src/main.rs b/repbuild/src/main.rs index 895e0165..e816ba38 100644 --- a/repbuild/src/main.rs +++ b/repbuild/src/main.rs @@ -54,13 +54,14 @@ fn main() -> anyhow::Result<()> { } => { let _dir = xshell::pushd("./ableos"); - let _debug_log: &[&str] = match debug { + let debug_log: &[&str] = match debug { true => &["-D", "debug.log"], false => &[], }; match machine.unwrap_or(MachineType::X86) { MachineType::X86 => { - xshell::cmd!("cargo run --release").run()?; + // export RUSTFLAGS=\"-Cforce-unwind-tables -Clink-arg=-Wl,eh_frame.ld\" && + xshell::cmd!("cargo run --release -- -D debug.log").run()?; if profile { xshell::cmd!("python qprofiler.py --path=qmp-sock --filename=target/x86_64-ableos/release/ableos").run()?; }