diff --git a/ableos/Cargo.lock b/ableos/Cargo.lock index a8ffee7..0bf25e4 100644 --- a/ableos/Cargo.lock +++ b/ableos/Cargo.lock @@ -39,6 +39,7 @@ dependencies = [ "linked_list_allocator", "lliw", "log", + "pc-beeper", "pic8259", "picorand", "pretty-hex", @@ -49,6 +50,7 @@ dependencies = [ "shadeable", "smoltcp", "spin 0.5.2", + "tinypci", "uart_16550", "unicode-width", "vga", @@ -83,9 +85,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "bit_field" @@ -183,7 +185,7 @@ checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" [[package]] name = "ext2" version = "0.1.1" -source = "git+https://git.ablecorp.us/able/ext2-rs.git#220f66a156bfd5033eecac20372368860749c304" +source = "git+https://git.ablecorp.us/able/ext2-rs.git#15bcf9f72e2523e7ebe2a8d09c1231ca9139f326" dependencies = [ "bitflags", "genfs", @@ -264,15 +266,15 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.112" +version = "0.2.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125" +checksum = "e74d72e0f9b65b5b4ca49a346af3976df0f9c61d550727f349ecd559f251a26c" [[package]] name = "libm" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7d73b3f436185384286bd8098d17ec07c9a7d2388a6599f824d8502b529702a" +checksum = "33a33a362ce288760ec6a508b94caaec573ae7d3bbbd91b87aa0bad4456839db" [[package]] name = "linked_list_allocator" @@ -291,9 +293,9 @@ checksum = "2d502c8bcc35a4f7ca9a7ffb7ac27b15ba30b1b92c2d69a1e4437e2635d73af7" [[package]] name = "lock_api" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712a4d093c9976e24e7dbca41db895dabcbac38eb5f4045393d17a95bdfb1109" +checksum = "88943dd7ef4a2e5a4bfa2753aaab3013e34ce2533d1996fb18ef591e315e2b3b" dependencies = [ "scopeguard", ] @@ -377,6 +379,14 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be5e13c266502aadf83426d87d81a0f5d1ef45b8027f5a471c360abfe4bfae92" +[[package]] +name = "pc-beeper" +version = "0.1.0" +source = "git+https://github.com/AbleOS/pc-beeper#9b61a9d60552a9da4285f5ceb39ab2cccbb60b4b" +dependencies = [ + "x86_64", +] + [[package]] name = "pic8259" version = "0.10.2" @@ -435,9 +445,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47aa80447ce4daf1717500037052af176af5d38cc3e571d9ec1c7353fc10c87d" +checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145" dependencies = [ "proc-macro2", ] @@ -459,9 +469,9 @@ dependencies = [ [[package]] name = "rhai" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c7433068977c56619bf2b7831da26eb986d0645fe56f2ad9357eda7ae4c435e" +checksum = "898b114d6cfa18af4593393fdc6c7437118e7e624d97f635fba8c75fd5c06f56" dependencies = [ "ahash", "core-error", @@ -487,9 +497,9 @@ dependencies = [ [[package]] name = "rkyv" -version = "0.7.29" +version = "0.7.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49a37de5dfc60bae2d94961dacd03c7b80e426b66a99fa1b17799570dbdd8f96" +checksum = "439655b8d657bcb28264da8e5380d55549e34ffc4149bea9e3521890a122a7bd" dependencies = [ "hashbrown", "ptr_meta", @@ -499,9 +509,9 @@ dependencies = [ [[package]] name = "rkyv_derive" -version = "0.7.29" +version = "0.7.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719d447dd0e84b23cee6cb5b32d97e21efb112a3e3c636c8da36647b938475a1" +checksum = "cded413ad606a80291ca84bedba137093807cf4f5b36be8c60f57a7e790d48f6" dependencies = [ "proc-macro2", "quote", @@ -543,18 +553,18 @@ checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" [[package]] name = "serde" -version = "1.0.133" +version = "1.0.136" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97565067517b60e2d1ea8b268e59ce036de907ac523ad83a0475da04e818989a" +checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.133" +version = "1.0.136" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed201699328568d8d08208fdd080e3ff594e6c422e438b6705905da01005d537" +checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9" dependencies = [ "proc-macro2", "quote", @@ -563,9 +573,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.75" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c059c05b48c5c0067d4b4b2b4f0732dd65feb52daf7e0ea09cd87e7dadc1af79" +checksum = "d23c1ba4cf0efd44be32017709280b32d1cea5c3f1275c3b6d9e8bc54f758085" dependencies = [ "itoa", "ryu", @@ -641,9 +651,9 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "syn" -version = "1.0.85" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a684ac3dcd8913827e18cd09a68384ee66c1de24157e3c556c9ab16d85695fb7" +checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b" dependencies = [ "proc-macro2", "quote", @@ -659,6 +669,11 @@ dependencies = [ "crunchy", ] +[[package]] +name = "tinypci" +version = "0.1.0" +source = "git+https://github.com/trashbyte/tinypci.git#5e1bc4cf7ae4edb8d524a5e7e71a1ace9c4850fc" + [[package]] name = "ttf-parser" version = "0.14.0" @@ -751,9 +766,9 @@ dependencies = [ [[package]] name = "x86_64" -version = "0.14.7" +version = "0.14.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb611915c917c6296d11e23f71ff1ecfe49c5766daba92cd3df52df6b58285b6" +checksum = "958ab3202b01bc43ba2eb832102c4a487ed93151667a2289062e5f2b00058be2" dependencies = [ "bit_field", "bitflags", diff --git a/ableos/Cargo.toml b/ableos/Cargo.toml index 5c74b9e..d83aaa2 100644 --- a/ableos/Cargo.toml +++ b/ableos/Cargo.toml @@ -10,18 +10,15 @@ panic = "abort" [package.metadata.bootimage] run-args = [ "-cpu", - # "kvm64-v1", - # Support for rdrand - # "Broadwell", - "EPYC-v1", - + "Broadwell-v3", "-serial", "stdio", "-smp", "cores=2", - +"-vga", +"qxl", # An example gpu used with ableOS # "-device", # "virtio-gpu", @@ -52,12 +49,19 @@ lliw = "0.2.0" spin = "0.5.2" vga = "*" log = "*" +# tinypci = "0.1.0" + +tinypci = { git = "https://github.com/trashbyte/tinypci.git", default-features = false } + pretty-hex = "0.2.1" unicode-width = "0.1.7" picorand = "*" # watson = "0.4" genfs = "0.1.0" +# pc-beeper = "0.1.0" +pc-beeper = {git = "https://github.com/AbleOS/pc-beeper"} + acpi = "4.1.0" @@ -80,7 +84,7 @@ default-features = false features = ["alloc"] [dependencies.hashbrown] -version = "*" +version = "0.11.2" default-features = false features = ["inline-more"] diff --git a/ableos/src/devices/dev_null.rs b/ableos/src/devices/dev_null.rs new file mode 100644 index 0000000..50b61db --- /dev/null +++ b/ableos/src/devices/dev_null.rs @@ -0,0 +1,23 @@ +use alloc::string::String; + +use crate::character_device::CharacterDevice; + +pub struct DevNull; + +impl CharacterDevice for DevNull { + fn can_read(&self) -> bool { + true + } + + fn can_write(&self) -> bool { + true + } + + fn read_char(&mut self) -> Option { + Some(0x00 as char) + } + + fn write_char(&mut self, _: char) -> bool { + true + } +} diff --git a/ableos/src/devices/dev_unicode.rs b/ableos/src/devices/dev_unicode.rs new file mode 100644 index 0000000..908ee0a --- /dev/null +++ b/ableos/src/devices/dev_unicode.rs @@ -0,0 +1,38 @@ +use crate::character_device::CharacterDevice; + +pub struct DevUnicode { + pub next_write_char: char, + pub next_read_char: char, +} + +impl CharacterDevice for DevUnicode { + fn can_read(&self) -> bool { + true + } + + fn can_write(&self) -> bool { + true + } + + fn read_char(&mut self) -> Option { + let c = self.next_read_char; + self.next_read_char = add1_char(c); + + Some(c) + } + + fn write_char(&mut self, c: char) -> bool { + if self.next_write_char != c { + return false; + } + + true + } +} + +fn add1_char(c: char) -> char { + if c == char::MAX { + return 0x00 as char; + } + char::from_u32(c as u32 + 1).unwrap() +} diff --git a/ableos/src/devices/dev_zero.rs b/ableos/src/devices/dev_zero.rs new file mode 100644 index 0000000..ec717d9 --- /dev/null +++ b/ableos/src/devices/dev_zero.rs @@ -0,0 +1,21 @@ +use crate::character_device::CharacterDevice; + +pub struct DevZero; + +impl CharacterDevice for DevZero { + fn can_read(&self) -> bool { + true + } + + fn can_write(&self) -> bool { + true + } + + fn read_char(&mut self) -> Option { + Some(0 as char) + } + + fn write_char(&mut self, _: char) -> bool { + true + } +} diff --git a/ableos/src/devices/mod.rs b/ableos/src/devices/mod.rs new file mode 100644 index 0000000..d2a3836 --- /dev/null +++ b/ableos/src/devices/mod.rs @@ -0,0 +1,36 @@ +use alloc::{ + boxed::Box, + string::{String, ToString}, +}; +use hashbrown::HashMap; + +use crate::character_device::CharacterDevice; + +pub mod dev_null; +pub mod dev_unicode; +pub mod dev_zero; + +// FIXME: This is a hack to hold a device. +pub enum Device { + CharacterDevice(Box), + // BlockDevice, +} +unsafe impl Sync for Device {} +unsafe impl Send for Device {} + +pub struct DeviceTable { + pub devices: HashMap, +} +use self::dev_null::DevNull; +pub use self::Device::*; +impl DeviceTable { + pub fn new() -> Self { + let mut table: HashMap = HashMap::new(); + table.insert("null".to_string(), CharacterDevice(Box::new(DevNull))); + DeviceTable { devices: table } + } +} + +lazy_static::lazy_static!( + static ref DEVICE_TABLE: DeviceTable = DeviceTable::new(); +); diff --git a/ableos/src/driver_traits/character_device.rs b/ableos/src/driver_traits/character_device.rs new file mode 100644 index 0000000..d128c72 --- /dev/null +++ b/ableos/src/driver_traits/character_device.rs @@ -0,0 +1,10 @@ +pub trait CharacterDevice { + /// Returns true if the device can be read from. + fn can_read(&self) -> bool; + /// Returns true if the device can be written to + fn can_write(&self) -> bool; + /// Reads a single character from the device + fn read_char(&mut self) -> Option; + /// Writes a single character to the device and returns true if the write was successful + fn write_char(&mut self, c: char) -> bool; +} diff --git a/ableos/src/driver_traits/device.rs b/ableos/src/driver_traits/device.rs deleted file mode 100644 index 58004d0..0000000 --- a/ableos/src/driver_traits/device.rs +++ /dev/null @@ -1,4 +0,0 @@ -pub trait Device { - fn probe(); - fn reset(); -} diff --git a/ableos/src/driver_traits/mod.rs b/ableos/src/driver_traits/mod.rs index b832ebf..ec4063f 100644 --- a/ableos/src/driver_traits/mod.rs +++ b/ableos/src/driver_traits/mod.rs @@ -1,2 +1,4 @@ pub mod graphics; pub mod serial; + +pub mod character_device; diff --git a/ableos/src/filesystem/mod.rs b/ableos/src/filesystem/mod.rs new file mode 100644 index 0000000..b842d64 --- /dev/null +++ b/ableos/src/filesystem/mod.rs @@ -0,0 +1,48 @@ +use { + alloc::{format, string::String, vec::Vec}, + ext2::{ + fs::{ + sync::{Inode, Synced}, + Ext2, + }, + sector::{SectorSize, Size1024}, + volume::Volume, + }, +}; + +fn load_fs() -> Synced>> { + let mut volume = Vec::new(); + volume.extend_from_slice(include_bytes!("../../../userland/root_rs/ext2.img")); + + let fs = Synced::>::new(volume).unwrap(); + + fs +} + +// use serde::__private::from_utf8_lossy; + +pub fn walk<'vol, S: SectorSize, V: Volume>( + fs: &'vol Synced>, + inode: Inode, + name: String, +) { + inode.directory().map(|dir| { + for entry in dir { + assert!(entry.is_ok()); + let entry = entry.unwrap(); + let entry_name = String::from_utf8_lossy(&entry.name); + + println!("{}/{} => {}", name, entry_name, entry.inode,); + if entry_name != "." && entry_name != ".." { + walk( + fs, + fs.inode_nth(entry.inode).unwrap(), + format!("{}/{}", name, entry_name), + ); + } + } + }); +} +lazy_static::lazy_static!( + pub static ref FILE_SYSTEM:spin::Mutex>>>= spin::Mutex::new(load_fs()); +); diff --git a/ableos/src/lib.rs b/ableos/src/lib.rs index 6e6a35c..4af3ba1 100644 --- a/ableos/src/lib.rs +++ b/ableos/src/lib.rs @@ -32,6 +32,7 @@ pub mod arch; #[macro_use] pub mod print; +pub mod wasm_jumploader; #[macro_use] pub extern crate log; @@ -93,3 +94,4 @@ pub use syscalls::*; pub mod scratchpad; pub use scratchpad::*; +pub mod filesystem; diff --git a/ableos/src/scratchpad.rs b/ableos/src/scratchpad.rs index 037e57a..4278997 100644 --- a/ableos/src/scratchpad.rs +++ b/ableos/src/scratchpad.rs @@ -1,67 +1,27 @@ -use alloc::{ - format, - string::{String, ToString}, - vec::Vec, -}; -use ext2::{ - fs::{ - sync::{Inode, Synced}, - Ext2, - }, - sector::{SectorSize, Size1024}, - volume::Volume, -}; +use alloc::{string::String, vec::Vec}; +use genfs::{Fs, OpenOptions}; + +use crate::{filesystem::FILE_SYSTEM, wasm_jumploader::interp}; /// Experimental scratchpad for testing. pub fn scratchpad() { - let mut fs = load_fs(); + let fs = &*FILE_SYSTEM.lock(); + let file = fs + .open(b"/home/able/kernel.md", OpenOptions::new().read(true)) + .unwrap(); - let root = fs.root_inode(); - walk(&fs, fs.root_inode(), String::new()); -} - -fn load_fs() -> Synced>> { - let file = include_bytes!("../../userland/root_rs/ext2.img"); - - let mut volume = Vec::new(); - volume.extend_from_slice(file); - - let fs = Synced::>::new(volume); - assert!( - fs.is_ok(), - "Err({:?})", - fs.err().unwrap_or_else(|| unreachable!()), - ); - - let fs = fs.unwrap(); - - fs -} - -use genfs::{DirOptions, Fs, OpenOptions}; -use serde::__private::from_utf8_lossy; - -use crate::{arch::drivers::serial, serial_println}; - -fn walk<'vol, S: SectorSize, V: Volume>( - fs: &'vol Synced>, - inode: Inode, - name: String, -) { - inode.directory().map(|dir| { - for entry in dir { - assert!(entry.is_ok()); - let entry = entry.unwrap(); - let entry_name = from_utf8_lossy(&entry.name); - - println!("{}/{} => {}", name, entry_name, entry.inode,); - if entry_name != "." && entry_name != ".." { - walk( - fs, - fs.inode_nth(entry.inode).unwrap(), - format!("{}/{}", name, entry_name), - ); - } - } - }); + let mut file_bytes = Vec::new(); + file.read_to_end(&mut file_bytes).unwrap(); + + let string = String::from_utf8_lossy(&file_bytes); + + print!("{}", string); + + let pci_list = tinypci::brute_force_scan(); + + for pci in pci_list { + info!("{}", pci); + } + + interp(); } diff --git a/ableos/src/syscalls/mod.rs b/ableos/src/syscalls/mod.rs index cf5d394..ee26229 100644 --- a/ableos/src/syscalls/mod.rs +++ b/ableos/src/syscalls/mod.rs @@ -22,4 +22,6 @@ pub enum Signals { /// * `pid` - The PID of the process to send the signal to /// * `signal` - The signal to send #[no_mangle] -pub extern "C" fn send_signal(pid: PID, signal: Signals) {} +pub extern "C" fn send_signal(pid: PID, signal: Signals) { + unimplemented!("send_signal"); +} diff --git a/ableos/src/usb/mod.rs b/ableos/src/usb/mod.rs new file mode 100644 index 0000000..b7a2224 --- /dev/null +++ b/ableos/src/usb/mod.rs @@ -0,0 +1,16 @@ +//! +//! +//! +//! +//! + +pub enum UsbSpeed { + /// Super-speed functions operate at up to 5 Gb/s. + Super, + /// High-speed functions operate at up to 480 Mb/s. + High, + /// Full-speed functions operate at up to 12 Mb/s. + Full, + /// Low-speed functions operate at up to 1.5 Mb/s. + Low, +} diff --git a/ableos/src/wasm_jumploader/host_functions.rs b/ableos/src/wasm_jumploader/host_functions.rs new file mode 100644 index 0000000..df34820 --- /dev/null +++ b/ableos/src/wasm_jumploader/host_functions.rs @@ -0,0 +1,66 @@ +use alloc::format; +use wasmi::{ + Error, Externals, FuncInstance, FuncRef, ModuleImportResolver, RuntimeArgs, RuntimeValue, + Signature, Trap, ValueType, +}; + +pub struct HostExternals { + // counter: usize, +} + +const ADD_FUNC_INDEX: usize = 0; + +impl Externals for HostExternals { + fn invoke_index( + &mut self, + index: usize, + args: RuntimeArgs, + ) -> Result, Trap> { + match index { + ADD_FUNC_INDEX => { + let a: u32 = args.nth_checked(0)?; + let b: u32 = args.nth_checked(1)?; + let result = a + b; + + Ok(Some(RuntimeValue::I32(result as i32))) + } + _ => panic!("Unimplemented function at {}", index), + } + } +} + +impl HostExternals { + fn check_signature(&self, index: usize, signature: &Signature) -> bool { + let (params, ret_ty): (&[ValueType], Option) = match index { + ADD_FUNC_INDEX => (&[ValueType::I32, ValueType::I32], Some(ValueType::I32)), + _ => return false, + }; + signature.params() == params && signature.return_type() == ret_ty + } +} + +impl ModuleImportResolver for HostExternals { + fn resolve_func(&self, field_name: &str, signature: &Signature) -> Result { + let index = match field_name { + "add" => ADD_FUNC_INDEX, + _ => { + return Err(Error::Instantiation(format!( + "Export {} not found", + field_name + ))) + } + }; + + if !self.check_signature(index, signature) { + return Err(Error::Instantiation(format!( + "Export {} has a bad signature", + field_name + ))); + } + + Ok(FuncInstance::alloc_host( + Signature::new(&[ValueType::I32, ValueType::I32][..], Some(ValueType::I32)), + index, + )) + } +} diff --git a/ableos/src/wasm_jumploader/mod.rs b/ableos/src/wasm_jumploader/mod.rs new file mode 100644 index 0000000..c8924e2 --- /dev/null +++ b/ableos/src/wasm_jumploader/mod.rs @@ -0,0 +1,39 @@ +pub mod host_functions; + +extern crate wasmi; +// extern crate wabt; + +use alloc::vec::Vec; +use genfs::{Fs, OpenOptions}; +use wasmi::{ImportsBuilder, ModuleInstance, NopExternals}; + +use crate::{filesystem::FILE_SYSTEM, wasm_jumploader::host_functions::HostExternals}; + +pub fn interp() { + let fs = &*FILE_SYSTEM.lock(); + + let file = fs + .open(b"/home/able/test.wasm", OpenOptions::new().read(true)) + .unwrap(); + + let mut wasm_binary = Vec::new(); + + let ret = file.read_to_end(&mut wasm_binary).unwrap(); + + // Load wasm binary and prepare it for instantiation. + let module = wasmi::Module::from_buffer(&wasm_binary).expect("failed to load wasm"); + + let imports = ImportsBuilder::new().with_resolver("env", &host_functions::HostExternals {}); + + // Instantiate a module with empty imports and + // assert that there is no `start` function. + let instance = ModuleInstance::new(&module, &imports) + .expect("failed to instantiate wasm module") + .assert_no_start(); + + let ret = instance + .invoke_export("start", &[], &mut HostExternals {}) + .expect("failed to execute export"); + + info!("collected wasm return value: {:?}", ret); +} diff --git a/userland/aos_wasm_stress_test/.cargo/config.toml b/userland/aos_wasm_stress_test/.cargo/config.toml index f4e8c00..f44d78c 100644 --- a/userland/aos_wasm_stress_test/.cargo/config.toml +++ b/userland/aos_wasm_stress_test/.cargo/config.toml @@ -1,2 +1,6 @@ [build] target = "wasm32-unknown-unknown" + +# [unstable] +# build-std = ["core", "compiler_builtins", "alloc"] +# build-std-features = ["compiler-builtins-mem"] diff --git a/userland/aos_wasm_stress_test/src/main.rs b/userland/aos_wasm_stress_test/src/main.rs index 1ba8b8f..6bf54d1 100644 --- a/userland/aos_wasm_stress_test/src/main.rs +++ b/userland/aos_wasm_stress_test/src/main.rs @@ -1,13 +1,22 @@ #![no_std] #![no_main] +#![deny(improper_ctypes)] -pub struct Command {} +#[macro_use] +mod libwasm; + +#[no_mangle] +fn start() -> i32 { + let ret = unsafe { add(1, 2) }; + + info!(b"hello"); + + ret as i32 +} -fn _start(_command: Command) {} -/* use core::panic::PanicInfo; + #[panic_handler] fn panic(_info: &PanicInfo) -> ! { loop {} } -*/ diff --git a/userland/root_rs/ext2.img b/userland/root_rs/ext2.img index bec644f..7b7d4a6 100644 Binary files a/userland/root_rs/ext2.img and b/userland/root_rs/ext2.img differ