diff --git a/Cargo.lock b/Cargo.lock index 568608fe..01b48c70 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -31,6 +31,7 @@ dependencies = [ "axel", "bitflags", "bootloader", + "clparse", "cpuio", "ext2", "externc-libm", @@ -161,6 +162,16 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "clparse" +version = "0.1.0" +source = "git+https://git.ablecorp.us/able/core_utils#46a97f827bd11f3cea8dcab797b9697d9485c4b3" +dependencies = [ + "hashbrown", + "log", + "toml", +] + [[package]] name = "colored" version = "2.0.0" @@ -726,12 +737,15 @@ dependencies = [ [[package]] name = "vga" version = "0.2.7" -source = "git+https://git.ablecorp.us/able/vga.git#9e72fa603927983e359c8a7c56cb110a81eb161e" +source = "git+https://git.ablecorp.us/able/vga.git#fd41943bb05ca90414e84cff3def1ffe72a62efe" dependencies = [ + "ab_glyph", "bitflags", "conquer-once", "font8x8", + "log", "num-traits", + "spin 0.9.4", "spinning_top", "x86_64", ] diff --git a/ableos/Cargo.toml b/ableos/Cargo.toml index b3ae1f4f..665889b5 100644 --- a/ableos/Cargo.toml +++ b/ableos/Cargo.toml @@ -22,9 +22,19 @@ run-args = [ "-soundhw", "pcspk", + + + # "-device", + # "VGA", + # "-device", + # "virtio-gpu-pci", + "-device", - "VGA", - # "-device", "virtio-gpu-pci", + "vmware-svga", + + "-device", + "sb16", + # "-machine", "pcspk-audiodev=0", @@ -49,7 +59,6 @@ test-args = [ lazy_static = { version = "1.4.0", features = ["spin_no_std"] } qrcode = { path = "../qrcode-rust" } bitflags = "1.2.1" -linked_list_allocator = "0.9.0" lliw = "0.2.0" spin = "0.9" pretty-hex = "0.2.1" @@ -62,7 +71,12 @@ versioning = { git = "https://git.ablecorp.us/able/aos_userland" } # embedded-graphics = "*" pc-keyboard = "0.5" # mini-backtrace = "0.1" +clparse = { git = "https://git.ablecorp.us/able/core_utils", default-features = false } + +[dependencies.linked_list_allocator] +version = "0.9.0" +features = ["use_spin_nightly"] [dependencies.log] version = "0.4.17" default-features = false @@ -144,3 +158,4 @@ x86_64 = "0.14.8" pc-beeper = { git = "https://github.com/AbleOS/pc-beeper" } acpi = "4.1.0" vga = { git = "https://git.ablecorp.us:443/able/vga.git" } +# vga = { path = "../../vga" } diff --git a/ableos/assets/kernel.toml b/ableos/assets/kernel.toml index d32fcd6e..efcb00c0 100644 --- a/ableos/assets/kernel.toml +++ b/ableos/assets/kernel.toml @@ -6,8 +6,8 @@ user_processes = ["shell"] enabled = true level = "Trace" log_to_serial = true -filter = [] -# "ableos::vterm"] +log_to_vterm = false +filter = ["ableos::ps2_mouse", "ableos::vterm"] [tests] diff --git a/ableos/src/arch/x86_64/interrupts.rs b/ableos/src/arch/x86_64/interrupts.rs index f18cd7aa..54459cd6 100644 --- a/ableos/src/arch/x86_64/interrupts.rs +++ b/ableos/src/arch/x86_64/interrupts.rs @@ -1,6 +1,12 @@ +/* +* Copyright (c) 2022, able +* +* SPDX-License-Identifier: MPL-2.0 +*/ + use core::panic::PanicInfo; -use crate::{arch::gdt, print, println, rhai_shell::KEYBUFF}; +use crate::{arch::gdt, println, rhai_shell::KEYBUFF}; use cpuio::outb; use pic8259::ChainedPics; use qrcode::QrCode; @@ -134,7 +140,6 @@ extern "x86-interrupt" fn keyboard_interrupt_handler(_stack_frame: InterruptStac DecodedKey::Unicode(chr) => match chr { '\n' => { KEYBUFF.lock().push('\n'); - trace!("ENTER"); } // Backspace '\u{8}' => { diff --git a/ableos/src/arch/x86_64/mod.rs b/ableos/src/arch/x86_64/mod.rs index 9ee80a9b..6ebf783d 100644 --- a/ableos/src/arch/x86_64/mod.rs +++ b/ableos/src/arch/x86_64/mod.rs @@ -1,3 +1,9 @@ +/* +* Copyright (c) 2022, able +* +* SPDX-License-Identifier: MPL-2.0 +*/ + pub mod drivers; pub mod gdt; pub mod init; @@ -10,7 +16,10 @@ use crate::arch::drivers::allocator; use bootloader::{entry_point, BootInfo}; use x86_64::{instructions::hlt, VirtAddr}; +#[cfg(not(test))] entry_point![start]; + +#[cfg(not(test))] #[no_mangle] pub fn start(boot_info: &'static BootInfo) -> ! { let phys_mem_offset = VirtAddr::new(boot_info.physical_memory_offset); diff --git a/ableos/src/boot_conf.rs b/ableos/src/boot_conf.rs index 87f6530b..f3248c2a 100644 --- a/ableos/src/boot_conf.rs +++ b/ableos/src/boot_conf.rs @@ -52,6 +52,7 @@ impl Default for KernelConfig { pub struct LoggingConfig { pub enabled: bool, pub log_to_serial: bool, + pub log_to_vterm: bool, pub level: LogLevel, pub filter: Vec, } diff --git a/ableos/src/devices/pci/devices.rs b/ableos/src/devices/pci/devices.rs new file mode 100644 index 00000000..a10f97f4 --- /dev/null +++ b/ableos/src/devices/pci/devices.rs @@ -0,0 +1,20 @@ +/* +* Copyright (c) 2022, able +* +* SPDX-License-Identifier: MPL-2.0 +*/ + +use super::vendors::Vendor::{self, *}; +#[derive(PartialEq, Clone, Eq, Debug)] +pub struct DeviceID { + pub vendor: Vendor, + pub id: u16, +} +impl DeviceID { + pub const fn new(vendor: Vendor, id: u16) -> Self { + Self { vendor, id } + } +} + +pub const VMWARE_SVGA2: DeviceID = DeviceID::new(VMware, 0x0405); +pub const S3INC_TRIO64V2: DeviceID = DeviceID::new(S3Inc, 0x8900); diff --git a/ableos/src/devices/pci/enums.rs b/ableos/src/devices/pci/enums.rs index f238bc84..1c1fe671 100644 --- a/ableos/src/devices/pci/enums.rs +++ b/ableos/src/devices/pci/enums.rs @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2022, able +* +* SPDX-License-Identifier: MPL-2.0 +*/ + +use core::fmt::Display; + /// The major class specification for a PCI device. #[allow(dead_code)] #[derive(Debug, Clone, Copy, PartialEq, Hash)] @@ -176,3 +184,63 @@ impl From for PciFullClass { Self::from_u16(n) } } + +impl Display for PciFullClass { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + write!(f, " Class: ")?; + + match self { + PciFullClass::Unclassified_NonVgaCompatible => write!(f, "\0LIGHTBLUE\0")?, + PciFullClass::Unclassified_VgaCompatible => write!(f, "\0LIGHTBLUE\0")?, + PciFullClass::MassStorage_ScsiBus => write!(f, "\0CYAN\0")?, + PciFullClass::MassStorage_IDE => write!(f, "\0CYAN\0")?, + PciFullClass::MassStorage_Floppy => write!(f, "\0CYAN\0")?, + PciFullClass::MassStorage_IpiBus => write!(f, "\0CYAN\0")?, + PciFullClass::MassStorage_RAID => write!(f, "\0CYAN\0")?, + PciFullClass::MassStorage_ATA => write!(f, "\0CYAN\0")?, + PciFullClass::MassStorage_SATA => write!(f, "\0CYAN\0")?, + PciFullClass::MassStorage_SerialSCSI => write!(f, "\0CYAN\0")?, + PciFullClass::MassStorage_NVM => write!(f, "\0CYAN\0")?, + PciFullClass::MassStorage_Other => write!(f, "\0CYAN\0")?, + PciFullClass::Network_Ethernet => write!(f, "\0MAGENTA\0")?, + PciFullClass::Network_TokenRing => write!(f, "\0MAGENTA\0")?, + PciFullClass::Network_FDDI => write!(f, "\0MAGENTA\0")?, + PciFullClass::Network_ATM => write!(f, "\0MAGENTA\0")?, + PciFullClass::Network_ISDN => write!(f, "\0MAGENTA\0")?, + PciFullClass::Network_WorldFlip => write!(f, "\0MAGENTA\0")?, + PciFullClass::Network_PICMG => write!(f, "\0MAGENTA\0")?, + PciFullClass::Network_Infiniband => write!(f, "\0MAGENTA\0")?, + PciFullClass::Network_Fabric => write!(f, "\0MAGENTA\0")?, + PciFullClass::Network_Other => write!(f, "\0MAGENTA\0")?, + PciFullClass::Display_VGA => write!(f, "\0YELLOW\0")?, + PciFullClass::Display_XGA => write!(f, "\0YELLOW\0")?, + PciFullClass::Display_3D => write!(f, "\0YELLOW\0")?, + PciFullClass::Display_Other => write!(f, "\0YELLOW\0")?, + PciFullClass::Multimedia_Video => write!(f, "\0LIGHTBLUE\0")?, + PciFullClass::Multimedia_AudioController => write!(f, "\0LIGHTBLUE\0")?, + PciFullClass::Multimedia_Telephony => write!(f, "\0LIGHTBLUE\0")?, + PciFullClass::Multimedia_AudioDevice => write!(f, "\0LIGHTBLUE\0")?, + PciFullClass::Multimedia_Other => write!(f, "\0LIGHTBLUE\0")?, + PciFullClass::Memory_RAM => write!(f, "\0BLUE\0")?, + PciFullClass::Memory_Flash => write!(f, "\0WHITE\0")?, + PciFullClass::Memory_Other => write!(f, "\0LIGHTGREY\0")?, + PciFullClass::Bridge_Host => write!(f, "\0GREEN\0")?, + PciFullClass::Bridge_ISA => write!(f, "\0GREEN\0")?, + PciFullClass::Bridge_EISA => write!(f, "\0GREEN\0")?, + PciFullClass::Bridge_MCA => write!(f, "\0GREEN\0")?, + PciFullClass::Bridge_PciToPci => write!(f, "\0GREEN\0")?, + PciFullClass::Bridge_PCMCIA => write!(f, "\0GREEN\0")?, + PciFullClass::Bridge_NuBus => write!(f, "\0GREEN\0")?, + PciFullClass::Bridge_CardBus => write!(f, "\0GREEN\0")?, + PciFullClass::Bridge_RACEway => write!(f, "\0GREEN\0")?, + PciFullClass::Bridge_PciToPciSemiTransparent => write!(f, "\0GREEN\0")?, + PciFullClass::Bridge_InfinibandToPci => write!(f, "\0GREEN\0")?, + PciFullClass::Bridge_Other => write!(f, "\0GREEN\0")?, + PciFullClass::Unknown => write!(f, "\0RED\0")?, + } + + write!(f, "{:?} ({:#06X})\0RESET\0", self, self.as_u16())?; + + Ok(()) + } +} diff --git a/ableos/src/devices/pci/mod.rs b/ableos/src/devices/pci/mod.rs index 6d087b0b..1afb0c27 100644 --- a/ableos/src/devices/pci/mod.rs +++ b/ableos/src/devices/pci/mod.rs @@ -10,12 +10,17 @@ use core::fmt::{Display, Error, Formatter}; #[macro_use] extern crate serde; +pub mod devices; mod enums; +pub mod support; +pub mod vendors; pub use enums::*; pub mod port; use port::*; +use self::devices::DeviceID; + // PciDeviceInfo /////////////////////////////////////////////////////////////// #[allow(dead_code)] @@ -25,8 +30,7 @@ use port::*; pub struct PciDeviceInfo { pub device: u8, pub bus: u8, - pub device_id: u16, - pub vendor_id: u16, + pub device_id: DeviceID, pub full_class: PciFullClass, pub header_type: u8, pub bars: [u32; 6], @@ -46,18 +50,13 @@ impl PciDeviceInfo { } impl Display for PciDeviceInfo { fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> { - let vendor_name = name_for_vendor_id(self.vendor_id); + let vendor_name = &self.device_id.vendor; writeln!( f, - "Device {:X} | Bus {:X} | Vendor: {}", + "Device {} | Bus {:X} | Vendor: {}", self.device, self.bus, vendor_name )?; - writeln!( - f, - " Class: {:?} ({:#06X})", - self.full_class, - self.full_class.as_u16() - )?; + writeln!(f, "{}", self.full_class)?; writeln!(f, " Header type: {:X}", self.header_type)?; write!(f, " Supported functions: 0")?; for (i, b) in self.supported_fns.iter().enumerate().skip(1) { @@ -86,15 +85,6 @@ impl Display for PciDeviceInfo { // Public functions //////////////////////////////////////////////////////////// -/// Converts a u16 vendor id into a human-readable name. -pub fn name_for_vendor_id(vendor_id: u16) -> String { - match vendor_id { - 0x8086 => "Intel Corp. (0x8086)".into(), - 0x1234 => "QEMU (0x1234)".into(), - _ => format!("Unknown({:#06X})", vendor_id), - } -} - /// Brute force scans for devices 0-31 on buses 0-255. pub fn brute_force_scan() -> Vec { let mut infos = Vec::new(); @@ -152,8 +142,11 @@ fn check_device(bus: u8, device: u8) -> Option { Some(PciDeviceInfo { device, bus, - device_id, - vendor_id, + device_id: DeviceID { + vendor: vendor_id.into(), + id: device_id, + }, + // vendor_id, full_class: pci_class, header_type, bars, diff --git a/ableos/src/devices/pci/support.rs b/ableos/src/devices/pci/support.rs new file mode 100644 index 00000000..793074f9 --- /dev/null +++ b/ableos/src/devices/pci/support.rs @@ -0,0 +1,15 @@ +/* +* Copyright (c) 2022, able +* +* SPDX-License-Identifier: MPL-2.0 +*/ + +use super::devices::*; + +pub fn check_pci_support(device_id: DeviceID) -> bool { + match device_id { + VMWARE_SVGA2 => true, + S3INC_TRIO64V2 => true, + _ => false, + } +} diff --git a/ableos/src/devices/pci/vendors.rs b/ableos/src/devices/pci/vendors.rs new file mode 100644 index 00000000..04454c53 --- /dev/null +++ b/ableos/src/devices/pci/vendors.rs @@ -0,0 +1,68 @@ +/* +* Copyright (c) 2022, able +* +* SPDX-License-Identifier: MPL-2.0 +*/ + +use core::fmt::Display; + +#[derive(PartialEq, Debug, Clone, Eq)] +#[repr(u16)] +pub enum Vendor { + Qemu = 0x1234, + VMware = 0x15AD, + VirtIO = 0x1AF4, + Ati = 1002, + Intel = 0x8086, + S3Inc = 0x5333, + Unknown(u16), +} + +impl From for Vendor { + fn from(vendor_id: u16) -> Self { + use Vendor::*; + match vendor_id { + 0x15AD => VMware, + 0x8086 => Intel, + 1002 => Ati, + id => Unknown(id), + } + } +} + +impl Into for Vendor { + fn into(self) -> u16 { + use Vendor::*; + match self { + VMware => 0x15AD, + Ati => 1002, + Qemu => 0x1234, + VirtIO => 0x1AF4, + Intel => 0x8086, + S3Inc => 0x5333, + Unknown(id) => id, + } + } +} + +impl Display for Vendor { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + use Vendor::*; + + let mut ret: String = match self { + Qemu => "\0PINK\0QEMU (0x1234)".into(), + VirtIO => "\0PINK\0VirtIO (0x1AF4)".into(), + VMware => "\0PINK\0VMWARE (0x15AD)".into(), + S3Inc => "\0YELLOW\0S3 Incorporated (0x5333)".into(), + Intel => "\0BLUE\0Intel Corp. (0x8086)".into(), + Ati => "\0RED\0ATI (0x1002)".into(), + + Unknown(id) => format!("\0RED\0Unknown ({:#6})", id), + }; + + ret.push_str("\0RESET\0"); + + write!(f, "{}", ret)?; + Ok(()) + } +} diff --git a/ableos/src/lib.rs b/ableos/src/lib.rs index 0c917e21..97f12a6e 100644 --- a/ableos/src/lib.rs +++ b/ableos/src/lib.rs @@ -1,3 +1,9 @@ +/* + * Copyright (c) 2022, Able + * + * SPDX-License-Identifier: MPL-2.0 + */ + //! main library for the AbleOS kernel. //! exposing all the kernel functionality to the rest of the kernel. //! @@ -11,6 +17,10 @@ naked_functions, prelude_import, )] +#![feature(arbitrary_enum_discriminant)] +#![feature(custom_test_frameworks)] +#![reexport_test_harness_main = "test_main"] +#![test_runner(crate::test_runner)] #[macro_use] pub extern crate log; @@ -74,8 +84,8 @@ pub mod ipc; pub mod panic; mod unicode_utils; pub mod vga_e; -// pub mod vgai; pub mod vterm; +// pub mod vgai; #[prelude_import] pub use prelude::rust_2021::*; @@ -94,3 +104,12 @@ pub use scratchpad::*; pub use utils::*; pub use virtio::*; pub use wasm::*; + +#[cfg(test)] +pub mod tests; + +#[cfg(test)] +pub use tests::test_kernel_main; + +#[cfg(test)] +use crate::tests::test_runner; diff --git a/ableos/src/logger.rs b/ableos/src/logger.rs index 8bc0fd69..1dd878ea 100644 --- a/ableos/src/logger.rs +++ b/ableos/src/logger.rs @@ -1,3 +1,9 @@ +/* + * Copyright (c) 2022, Able + * + * SPDX-License-Identifier: MPL-2.0 + */ + use crate::{kmain::KERNEL_CONF, time::fetch_time}; use lliw::Fg; use log::{Level, LevelFilter, Metadata, Record, SetLoggerError}; @@ -18,22 +24,13 @@ impl log::Log for SimpleLogger { use Fg::*; let color = match record.level() { - log::Level::Error => (Fg::Red, "$RED$"), - log::Level::Warn => (Fg::LightYellow, "$LIGHTYELLOW$"), - log::Level::Info => (Fg::LightWhite, "$LIGHTGRAY$"), - log::Level::Debug => (Fg::Blue, "$BLUE$"), - log::Level::Trace => (Fg::Yellow, "$YELLOW$"), + log::Level::Error => (Fg::Red, "\0RED\0"), + log::Level::Warn => (Fg::LightYellow, "\0LIGHTYELLOW\0"), + log::Level::Info => (Fg::LightWhite, "\0LIGHTGREY\0"), + log::Level::Debug => (Fg::Blue, "\0BLUE\0"), + log::Level::Trace => (Fg::Yellow, "\0YELLOW\0"), }; - /* - let msg = format!( - "[{}{}$RESET$][$GREEN${}$RESET$]{}\n", - color.1, - record.level(), - time_float, - record.args() - ); - */ let mod_path = match record.module_path() { Some(p) => { if KERNEL_CONF.logging.filter.contains(&p.to_string()) { @@ -50,16 +47,31 @@ impl log::Log for SimpleLogger { None => 0, }; + if KERNEL_CONF.logging.log_to_vterm { + let msg = format!( + // "[{}{}$RESET$][$GREEN${}$RESET$]{}\n", + "[{}{:05}\0RESET\0][\0GREEN\0{}\0RESET\0][\0BLUE\0{}@{}\0RESET\0] {}", + color.1, + record.level(), + time_float, + mod_path, + line, + record.args(), + ); + + println!("{msg}"); + } + if KERNEL_CONF.logging.log_to_serial { serial_println!( - "[{}{}{}][{}{}{}][{}{}@{}{}] {}", + "[{}{:05}{}][{}{}{}][{}{}@{}{}] {}", color.0, record.level(), - Fg::Reset, - Fg::Green, + Reset, + Green, time_float, Reset, - Fg::Blue, + Blue, mod_path, line, Reset, diff --git a/ableos/src/panic.rs b/ableos/src/panic.rs index d2a79384..41b08378 100644 --- a/ableos/src/panic.rs +++ b/ableos/src/panic.rs @@ -1,8 +1,14 @@ +/* +* Copyright (c) 2022, able +* +* SPDX-License-Identifier: MPL-2.0 +*/ + use core::panic::PanicInfo; use log::error; use crate::arch::interrupts::{bsod, BSODSource}; - +#[cfg(not(test))] #[panic_handler] fn panic_handler(info: &PanicInfo) -> ! { error!("{:?}", info); diff --git a/ableos/src/scratchpad.rs b/ableos/src/scratchpad.rs index 88a4aa70..2948cc9f 100644 --- a/ableos/src/scratchpad.rs +++ b/ableos/src/scratchpad.rs @@ -1,10 +1,17 @@ +/* + * Copyright (c) 2022, Able + * + * SPDX-License-Identifier: MPL-2.0 + */ + use crate::arch::drivers::sysinfo::master; use crate::arch::interrupts::{reset_pit_for_cpu, set_pit_2}; -use crate::image::mono_bitmap::bruh; +use crate::devices::pci::brute_force_scan; use crate::systeminfo::{KERNEL_VERSION, RELEASE_TYPE}; use crate::time::fetch_time; +use crate::KERNEL_STATE; use crate::{ - arch::shutdown, filesystem::FILE_SYSTEM, rhai_shell::KEYBUFF, vterm::Term, + arch::shutdown, filesystem::FILE_SYSTEM, rhai_shell::KEYBUFF, vterm::VTerm, wasm_jumploader::run_program, }; @@ -38,7 +45,7 @@ impl acpi::AcpiHandler for AcpiStruct { } } -pub static TERM: Lazy> = Lazy::new(|| spin::Mutex::new(Term::new())); +pub static TERM: Lazy> = Lazy::new(|| spin::Mutex::new(VTerm::new())); #[derive(Debug)] pub struct Path { @@ -64,12 +71,18 @@ pub fn scratchpad() { // bruh(); // panic!(":>"); - println!("\0RED\0OHNO\0RESET\0"); + // for c in 0..144_697 { + // trace!("{:?}", char::from_u32(c)); + // } // bruh(); + for x in brute_force_scan() { + println!("{}", x); + } disable(); let tick_time = fetch_time(); + let hostname = &KERNEL_STATE.lock().hostname; let allocator = ALLOCATOR.lock(); let size = allocator.size(); @@ -80,9 +93,9 @@ pub fn scratchpad() { println!( "{} ,-------. OS: \0BLUE\0AbleOS\0RESET\0 - ,'\\ _ _`. Host: None + ,'\\ _ _`. Host: \0PINK\0{}\0RESET\0 / \\)_)-)_)-\\ Kernel: \0RED\0AKern-{}-v{}\0RESET\0 -: : Uptime: {} +: : Uptime: \0GREEN\0{}\0RESET\0 \\ / Packages: None \\ / Shell: BuiltinShell `. ,' Resolution: 640x480 @@ -94,6 +107,7 @@ pub fn scratchpad() { // include_str!("../assets/balloon.txt"), // kstate.hostname, BANNER_WIDTH, + hostname, RELEASE_TYPE, KERNEL_VERSION, tick_time, @@ -156,7 +170,7 @@ pub fn real_shell() { } Some('\u{8}') => { print!("\u{8}"); - trace!(""); + buf.pop(); } @@ -189,6 +203,21 @@ pub fn command_parser(user: String, command: String) { let bin_name = iter.next().unwrap(); + let mut strin = String::new(); + for stri in iter { + trace!("{}", stri); + strin.push_str(stri); + } + let conf_args; + match clparse::Arguments::parse_from_string(strin) { + Ok(ok) => conf_args = ok, + Err(err) => { + println!("ERROR: {}", err); + error!("{}", err); + return; + } + }; + match bin_name { // note: able asked for rhaish to stay in the repo but will be removed // in the future so just comment it out for now @@ -202,9 +231,12 @@ pub fn command_parser(user: String, command: String) { } } - "echo" => { - echo_file(iter.next().unwrap().to_string(), fs); - } + "echo" => match conf_args.1.arguments.get("p") { + Some(path) => echo_file(path.to_string(), fs), + + None => println!("No path provided"), + }, + "test" => {} "quit" => shutdown(), @@ -237,8 +269,8 @@ pub fn command_parser(user: String, command: String) { let mut binary = vec![]; file.read_to_end(&mut binary).unwrap(); - let args = iter.collect::>(); - println!("{:?}", args); + // let args = iter.collect::>(); + // println!("{:?}", args); run_program(&binary); } } diff --git a/ableos/src/tests/mod.rs b/ableos/src/tests/mod.rs new file mode 100644 index 00000000..d01f45f0 --- /dev/null +++ b/ableos/src/tests/mod.rs @@ -0,0 +1,70 @@ +/* +* Copyright (c) 2022, able +* +* SPDX-License-Identifier: MPL-2.0 +*/ + +use core::panic::PanicInfo; + +use kernel::arch::arch::sloop; +pub trait Testable { + fn run(&self) -> (); +} + +impl Testable for T +where + T: Fn(), +{ + fn run(&self) { + serial_print!("{}...\t", core::any::type_name::()); + self(); + serial_println!("[ok]"); + } +} + +pub fn test_runner(tests: &[&dyn Testable]) { + serial_println!("Running {} tests", tests.len()); + for test in tests { + test.run(); + } + exit_qemu(QemuExitCode::Success); +} + +pub fn test_panic_handler(info: &PanicInfo) -> ! { + serial_println!("[failed]\n"); + serial_println!("Error: {}\n", info); + exit_qemu(QemuExitCode::Failed); +} + +#[panic_handler] +fn panic(info: &PanicInfo) -> ! { + test_panic_handler(info); +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[repr(u32)] +pub enum QemuExitCode { + Success = 0x10, + Failed = 0x11, +} + +pub fn exit_qemu(exit_code: QemuExitCode) -> ! { + use x86_64::instructions::port::Port; + + unsafe { + let mut port = Port::new(0xf4); + port.write(exit_code as u32); + } + loop {} +} + +entry_point!(test_kernel_main); +/// Entry point for `cargo test` +pub fn test_kernel_main(boot_info: &'static BootInfo) -> ! { + // init(boot_info.physical_memory_offset); + test_main(); + loop {} +} +use bootloader::{entry_point, BootInfo}; + +use crate::test_main; diff --git a/ableos/src/tests.rs b/ableos/src/tests/old_tests.rs similarity index 98% rename from ableos/src/tests.rs rename to ableos/src/tests/old_tests.rs index ae6177f5..08131570 100644 --- a/ableos/src/tests.rs +++ b/ableos/src/tests/old_tests.rs @@ -1,3 +1,9 @@ +/* +* Copyright (c) 2022, able +* +* SPDX-License-Identifier: MPL-2.0 +*/ + use crate::{ kmain::KERNEL_CONF, network::socket::{SimpleSock, Socket, SocketReturns}, diff --git a/ableos/src/vterm.rs b/ableos/src/vterm.rs index 6ed775dc..2ebc75b8 100644 --- a/ableos/src/vterm.rs +++ b/ableos/src/vterm.rs @@ -1,19 +1,31 @@ +/* + * Copyright (c) 2022, Able + * + * SPDX-License-Identifier: MPL-2.0 + */ +#![deny(missing_docs)] +//! The VTerm is a terminal with nice + use crate::{hardware::MOUSE, vga_e::VGAE}; +use ab_glyph::{Font, FontRef, Glyph}; use logos::{Lexer, Logos}; +use spin::Lazy; use vga::{colors::Color16, writers::GraphicsWriter}; const TERM_MINUS_ONE_LINE: usize = 4720; const CURSOR_COLOR: Color16 = Color16::Cyan; #[derive(Debug)] -pub struct Term { +/// A VTerm +pub struct VTerm { dirty: bool, color: Color16, term: [(char, Color16); 80 * 60], back_buffer: [u8; 640 * 480], x: u8, } -impl Term { +impl VTerm { + /// Construct a new VTerm pub fn new() -> Self { let mode = VGAE.lock(); mode.set_mode(); @@ -24,18 +36,21 @@ impl Term { dirty: false, x: 0, back_buffer: [0; 640 * 480], - term: [('\0', Color16::LightGrey); 80 * 60], + term: [('\0', Color16::DarkGrey); 80 * 60], color: Color16::White, } } + /// Check the dirty state of the VTerm pub fn is_dirty(&self) -> bool { self.dirty } + /// Set the dirty state of the VTerm pub fn set_dirty(&mut self, dirty: bool) { self.dirty = dirty } + /// Append a &str to the VTerm pub fn print(&mut self, data: &str) { let mut lex = Token::lexer(data); @@ -61,23 +76,29 @@ impl Term { Token::TPink => self.color = Color16::Pink, Token::TYellow => self.color = Color16::Yellow, Token::TWhite => self.color = Color16::White, - Token::Space => { - self.term[TERM_MINUS_ONE_LINE + (self.x as usize)] = (' ', self.color); - self.x += 1; - } + // Token::Space => { + // self.term[TERM_MINUS_ONE_LINE + (self.x as usize)] = (' ', self.color); + // self.x += 1; + // } Token::Text(st) => { for c in st.chars() { if self.x == 80 { + // trace!("X too big moving up"); self.move_up(); } // trace!("C"); match c { + '\0' => { + self.term[TERM_MINUS_ONE_LINE + (self.x as usize)] = + (c, self.color); + self.x += 1; + } + '\u{08}' => { if self.x == 0 { trace!("IMPOSSIBLE BACKSPACE"); return; } - trace!("BACKSPACE"); self.x -= 1; self.term[TERM_MINUS_ONE_LINE + (self.x as usize)] = ('\0', Color16::LightGrey); @@ -99,19 +120,16 @@ impl Term { } } + /// Move the VTerm up by one line pub fn move_up(&mut self) { self.term.rotate_left(80); for x in 0..80 { - self.term[TERM_MINUS_ONE_LINE + x] = ('\0', Color16::LightGrey); + self.term[TERM_MINUS_ONE_LINE + x] = ('\0', Color16::DarkGrey); } self.x = 0; } - // pub fn initialize(&self) { - // let mode = VGAE.lock(); - // mode.set_mode(); - // drop(mode); - // } + /// Redraw the VTerm to the VGA buffer pub fn draw_term(&mut self) { if self.is_dirty() { // trace!("Redrawing"); @@ -123,8 +141,10 @@ impl Term { for c in self.term { mode.draw_character(x * 8, y * 8, c.0, c.1); + // mode.draw_unicode_char(x, y, c.0, c.1); if x == 79 { y += 1; + x = 0; } else { x += 1 @@ -155,6 +175,30 @@ impl Term { ); } + drop(mode); + + /* + let mut x = 0; + let mut y = 0; + for c in ['b'; 80 * 60] + // "abcdefghijklmnopqrstuvwxyzabcdefghijk\nabcd jkjhgkjhgkjhgefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz12" + // .chars() + { + if c == '\n' { + y += 1; + x = 0; + continue; + } + + self.draw_char(x, y, c, Color16::Red); + if x == 80 { + y += 1; + x = 1; + } else { + x += 1; + } + } + */ self.set_dirty(false); // trace!("Finished drawing"); } @@ -162,7 +206,7 @@ impl Term { } #[derive(Logos, Debug, Clone, PartialEq)] -pub enum Token { +enum Token { #[regex(r"", logos::skip)] #[error] Error, @@ -203,10 +247,11 @@ pub enum Token { #[token("\0WHITE\0", priority = 10)] TWhite, - #[token(" ")] - Space, + // #[token(" ")] - #[regex("[\t\n\u{8}█!-~]+", text_lex, priority = 0)] + // Space, + #[regex("[\t\n\u{8}█!-\u{10FFFF} ]+", text_lex, priority = 0)] + /// A printable string Text(String), } diff --git a/repbuild/src/main.rs b/repbuild/src/main.rs index 9a455324..768acd68 100644 --- a/repbuild/src/main.rs +++ b/repbuild/src/main.rs @@ -1,8 +1,9 @@ /* - * Copyright (c) 2022, Umut İnan Erdoğan - * - * SPDX-License-Identifier: MPL-2.0 - */ +* Copyright (c) 2022, Umut İnan Erdoğan +* Copyright (c) 2022, able +* +* SPDX-License-Identifier: MPL-2.0 +*/ use std::{fs, process::Command}; @@ -18,6 +19,8 @@ enum Subcommand { Help, Run, Empty, + /// Run all tests for all architectures + Test, Unknown(String), } @@ -27,6 +30,7 @@ impl Subcommand { "doc" => Subcommand::Doc, "help" => Subcommand::Help, "run" => Subcommand::Run, + "test" => Subcommand::Test, "" => Subcommand::Empty, unknown => Subcommand::Unknown(unknown.to_string()), } @@ -44,6 +48,15 @@ fn main() { let options = options(); match options.subcommand { + Subcommand::Test => { + Command::new("cargo") + .args(["test", "--target=json_targets/x86_64-ableos.json"]) + .current_dir(fs::canonicalize("./ableos").unwrap()) + .status() + .unwrap(); + + // panic!("Test Infrastructure missing"); + } Subcommand::Doc => { let machine_text = options .arguments