diff --git a/ableos/.cargo/config.toml b/ableos/.cargo/config.toml index ef48109b2..06f0486cd 100644 --- a/ableos/.cargo/config.toml +++ b/ableos/.cargo/config.toml @@ -7,8 +7,7 @@ build-std-features = ["compiler-builtins-mem"] [target.'cfg(target_arch = "x86_64")'] -# --quiet suppresses warning messages from the bootimage crate -runner = "bootimage runner --quiet" +runner = "bootimage runner" [target.riscv64gc-unknown-none-elf] rustflags = "-C link-arg=-T../ableos/src/arch/riscv/virt.lds" diff --git a/ableos/Cargo.lock b/ableos/Cargo.lock index 9cf3fa3ee..2cc532014 100644 --- a/ableos/Cargo.lock +++ b/ableos/Cargo.lock @@ -30,6 +30,8 @@ dependencies = [ "bootloader", "cpuio", "externc-libm", + "facepalm", + "hashbrown", "lazy_static", "linked_list_allocator", "lliw", @@ -48,7 +50,6 @@ dependencies = [ "vga", "volatile 0.2.7", "wasmi", - "watson", "x86_64", "y-compositor-protocol", ] @@ -172,6 +173,13 @@ dependencies = [ "libm", ] +[[package]] +name = "facepalm" +version = "0.1.0" +dependencies = [ + "log", +] + [[package]] name = "font8x8" version = "0.3.1" @@ -670,22 +678,6 @@ dependencies = [ "parity-wasm", ] -[[package]] -name = "watson" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cea7ead78c402dbf14e7f11911b0b48955ea13d46e012e2d98775e23c65d4ef" -dependencies = [ - "serde", - "webassembly", -] - -[[package]] -name = "webassembly" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d1a10e1dedffff9cfcbdd33c289c65b87da634259a460a3f23d513649fa7a8c" - [[package]] name = "x86_64" version = "0.14.7" diff --git a/ableos/Cargo.toml b/ableos/Cargo.toml index ee3afedea..595618b3a 100644 --- a/ableos/Cargo.toml +++ b/ableos/Cargo.toml @@ -15,11 +15,16 @@ run-args = [ "stdio", "-smp", "cores=2", - # "-device", - # "virtio-gpu", + + # An example gpu used with ableOS + "-device", + "virtio-gpu", + + # An example disk used with ableOS "-device", "virtio-blk-pci,drive=drive0,id=virtblk0,num-queues=4", + # A simple example of a boot image "-drive", "file=disk.qcow2,if=none,id=drive0", ] @@ -40,7 +45,7 @@ log= "*" pretty-hex = "0.2.1" unicode-width = "0.1.7" picorand = "*" -watson = "0.4" +# watson = "0.4" [dependencies.serde] version = "*" @@ -52,6 +57,11 @@ version = "*" default-features = false features = ["alloc"] +[dependencies.hashbrown] +version = "*" +default-features = false +features = ["inline-more"] + [dependencies.rkyv] version = "0.7.29" default-features = false @@ -68,6 +78,9 @@ git = "https://git.ablecorp.us:443/able/y-compositor-protocol.git" [dependencies.shadeable] path = "../shadeable" +[dependencies.facepalm] +path = "../facepalm" + [dependencies.ab_glyph] version = "*" default-features = false diff --git a/ableos/src/arch/x86_64/init.rs b/ableos/src/arch/x86_64/init.rs index cfda29bdc..bf4b461f1 100644 --- a/ableos/src/arch/x86_64/init.rs +++ b/ableos/src/arch/x86_64/init.rs @@ -1,5 +1,5 @@ // #![allow(clippy::print_literal)] -use crate::logger; +use crate::{logger, SCHEDULER}; use super::{gdt, interrupts}; @@ -11,7 +11,15 @@ pub fn init() { Err(err) => error!("{}", err), } gdt::init(); + + use crate::scheduler::Priority; + let mut scheduler = SCHEDULER.lock(); + use Priority::*; + scheduler.new_process(High); + drop(scheduler); + interrupts::init_idt(); + unsafe { interrupts::PICS.lock().initialize() }; x86_64::instructions::interrupts::enable(); } diff --git a/ableos/src/kmain.rs b/ableos/src/kmain.rs index ae6c98635..5f1b9312f 100644 --- a/ableos/src/kmain.rs +++ b/ableos/src/kmain.rs @@ -4,7 +4,9 @@ use alloc::{format, vec::Vec}; use crate::{ boot_conf::BootConfig, - scheduler::{self, SCHEDULER}, + capabilities::FileAccess, + file::{File, PathRep}, + scheduler::SCHEDULER, }; // use crate::scheduler; @@ -18,7 +20,6 @@ use { systeminfo::{KERNEL_VERSION, RELEASE_TYPE}, }, graphics::{VgaBuffer, SCREEN_BUFFER}, - relib::math::rand::RAND_HANDLE, relib::network::socket::Socket, relib::network::socket::{SimpleSock, SocketReturns}, vga_e::{self, num_to_vga16}, @@ -50,12 +51,15 @@ lazy_static! { pub static ref BOOT_CONF: BootConfig = boot_conf::BootConfig::new(); } +/// The main entry point of the kernel #[no_mangle] pub fn kernel_main() -> ! { init::init(); log::set_max_level(BOOT_CONF.log_level()); // info!("Initialized"); + // facepalm::start_facepalm(); + graphics_pipe_startup(); if false { @@ -81,21 +85,41 @@ pub fn kernel_main() -> ! { let mut scheduler = SCHEDULER.lock(); use Priority::*; - scheduler.new_process(High); - scheduler.new_process(High); - scheduler.new_process(Low); - scheduler.new_process(Low); - scheduler.new_process(Low); - scheduler.new_process(Low); - scheduler.new_process(Medium); - scheduler.new_process(Medium); - scheduler.new_process(High); + let mut xyz = scheduler.new_process(High); + xyz.capabilities.files = FileAccess::Some(vec![PathRep { + location: FileLocations::Home, + file_name: "test".to_string(), + }]); + + scheduler.add_process(xyz); for x in &scheduler.list { trace!("{:?}", x); } drop(scheduler); + use crate::proto_filetable::contain::FILE_TABLE; + use crate::proto_filetable::file::FileLocations; + + let mut file_table = FILE_TABLE.lock(); + let mut new_file = File::new(FileLocations::Bin, "test".to_string(), "txt".to_string()); + new_file.write_bytes(b"Hello, world!"); + + file_table.add_file("test", new_file); + + let file = file_table.get_file("test"); + + match file { + Some(file) => { + let file_bytes = &file.data_pointer; + let file_string = String::from_utf8(file_bytes.to_vec()).unwrap(); + info!("{}", file_string); + } + None => { + info!("File not found"); + } + } + use crate::wasm::WasmProgram; let ret = WasmProgram::new_from_bytes(&[0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00]); trace!("Binary Valid: {:?}", ret.validate_header()); @@ -117,10 +141,6 @@ pub fn kernel_main() -> ! { shader_tests(); } - // graphics.copy_to_buffer(); - - // info!("buffer copied"); - sloop() } @@ -129,8 +149,6 @@ pub fn tick() { let mut data = TICK.load(Relaxed); data += 1; - RAND_HANDLE.lock().seed_entropy_timer(data); - crate::kernel_state::KERNEL_STATE.lock().update_state(); let mut scheduler = SCHEDULER.lock(); @@ -138,10 +156,8 @@ pub fn tick() { TICK.store(data, Relaxed) } - -pub fn key_entropy(key: u8) { - RAND_HANDLE.lock().seed_entropy_keyboard(key); -} +/// called every time a key is pressed to add it to the randomness pool +pub fn key_entropy(key: u8) {} pub fn cpu_socket_startup() { let mut cpu_info_socket = SimpleSock::new(); @@ -210,7 +226,6 @@ pub fn screen_writer_test() { let mut sock_print_id = SimpleSock::new(); sock_print_id.register_protocol("Screen Printer".to_string()); - // // sock_print_id.write(format!("a原 b画 cフ dァ eイ fル 集").into()); // sock_print_id.write(format!("⋮").into()); @@ -219,16 +234,8 @@ pub fn screen_writer_test() { // sock_print_id.write(format!("I look forward to ur ai stuff :^>").into()); // sock_print_id.write(format!("1....2....3....4....5....6....7....8....9").into()); - let mut prev = None; - - // let mut graphics = SCREEN_BUFFER.lock(); - // graphics.clear(); - // graphics.copy_to_buffer(); - for current in (*String::from_utf8_lossy(&sock_print_id.peek().unwrap())).chars() { - vga_e::draw_char(prev, current, 0); - - prev = Some(current); + vga_e::draw_char(0, 0, current, 0); } } diff --git a/ableos/src/lib.rs b/ableos/src/lib.rs index 47e4c6fb7..1805912f0 100644 --- a/ableos/src/lib.rs +++ b/ableos/src/lib.rs @@ -1,4 +1,7 @@ -//! hi +//! main library for the AbleOS kernel. +//! exposing all the kernel functionality to the rest of the kernel. +//! +//! #![no_std] #![feature( @@ -13,6 +16,7 @@ naked_functions )] #![feature(exclusive_range_pattern)] +#![feature(slice_pattern)] #[cfg(target_arch = "aarch64")] #[path = "arch/aarch64/mod.rs"] @@ -32,24 +36,49 @@ pub mod print; #[macro_use] pub extern crate log; +///////////// +// Modules // +///////////// pub mod allocator; pub mod boot_conf; pub mod driver_traits; pub mod experiments; pub mod graphics; +pub mod kernel_state; pub mod keyboard; pub mod kmain; pub mod logger; pub mod panic; +pub mod proto_filetable; pub mod relib; pub mod scheduler; mod unicode_utils; pub mod utils; +pub mod vga_e; pub mod wasm; pub extern crate alloc; pub extern crate externc_libm as libm; -/////////////////////////////// -pub mod kernel_state; -pub mod vga_e; +////////////////// +// Re-exports /// +//////////////// +pub use allocator::*; +pub use boot_conf::*; +pub use driver_traits::*; +pub use experiments::*; +pub use graphics::*; +pub use kernel_state::*; +pub use keyboard::*; +pub use logger::*; +pub use panic::*; +pub use proto_filetable::*; +pub use relib::*; +pub use scheduler::*; +pub use utils::*; +pub use vga_e::*; +pub use wasm::*; + +////////////////// +pub mod virtio; +pub use virtio::*; diff --git a/ableos/src/logger.rs b/ableos/src/logger.rs index 374d54530..64ae5e8be 100644 --- a/ableos/src/logger.rs +++ b/ableos/src/logger.rs @@ -1,6 +1,6 @@ use core::sync::atomic::Ordering; -use crate::kmain::{BOOT_CONF, TICK}; +use crate::kmain::TICK; use crate::serial_println; use lliw::{Fg, Reset}; pub use log::{debug, info, trace, warn}; @@ -42,7 +42,7 @@ impl log::Log for SimpleLogger { ); } } - + /// Clear the log buffer fn flush(&self) {} } diff --git a/ableos/src/panic.rs b/ableos/src/panic.rs index 35d38be8a..9ae4d7c15 100644 --- a/ableos/src/panic.rs +++ b/ableos/src/panic.rs @@ -1,8 +1,22 @@ use {crate::arch::sloop, core::panic::PanicInfo}; +/// A function to handle a panic in the kernel. +/// # Example +/// ``` +/// use ableos::panic::panic; +/// panic!("This is a panic!"); +/// ``` +/// +/// # Safety +/// This function is unsafe because it does not guarantee that the panic is handled. #[panic_handler] fn panic(info: &PanicInfo) -> ! { - // println!("{}", info); error!("{}", info); + // help me use facepalm::start_facepalm; + sloop() } + +pub fn test_panic() { + panic!("test panic!"); +} diff --git a/ableos/src/pci.rs b/ableos/src/pci.rs deleted file mode 100644 index 824850b3c..000000000 --- a/ableos/src/pci.rs +++ /dev/null @@ -1,22 +0,0 @@ -pub fn pciConfigReadWord(bus: u8, slot: u8, func: u8, offset: u8) {} - -/* -uint16_t pciConfigReadWord(uint8_t bus, uint8_t slot, uint8_t func, uint8_t offset) { - uint32_t address; - uint32_t lbus = (uint32_t)bus; - uint32_t lslot = (uint32_t)slot; - uint32_t lfunc = (uint32_t)func; - uint16_t tmp = 0; - - // Create configuration address as per Figure 1 - address = (uint32_t)((lbus << 16) | (lslot << 11) | - (lfunc << 8) | (offset & 0xFC) | ((uint32_t)0x80000000)); - - // Write out the address - outl(0xCF8, address); - // Read in the data - // (offset & 2) * 8) = 0 will choose the first word of the 32-bit register - tmp = (uint16_t)((inl(0xCFC) >> ((offset & 2) * 8)) & 0xFFFF); - return tmp; -} -*/ diff --git a/ableos/src/proto_filetable/contain.rs b/ableos/src/proto_filetable/contain.rs new file mode 100644 index 000000000..d957455bb --- /dev/null +++ b/ableos/src/proto_filetable/contain.rs @@ -0,0 +1,5 @@ +use crate::ProtoFileTable; + +lazy_static::lazy_static!( + pub static ref FILE_TABLE: spin::Mutex = spin::Mutex::new(ProtoFileTable::new()); +); diff --git a/ableos/src/proto_filetable/file.rs b/ableos/src/proto_filetable/file.rs new file mode 100644 index 000000000..16f6fe18a --- /dev/null +++ b/ableos/src/proto_filetable/file.rs @@ -0,0 +1,76 @@ +use core::fmt; + +use alloc::{string::String, vec, vec::Vec}; + +#[derive(Debug, PartialEq, Clone)] +pub struct PathRep { + pub location: FileLocations, + pub file_name: String, +} + +#[derive(Debug)] +pub struct FileMetadata { + pub file_type: String, + pub size: usize, +} + +#[derive(Debug, Clone, PartialEq)] +pub enum FileLocations { + Bin, + Config, + Home, +} +impl fmt::Display for FileLocations { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{:?}", self) + } +} + +#[derive(Debug)] +pub struct File { + pub location: FileLocations, + pub file_name: String, + pub meta_data: FileMetadata, + pub data_pointer: Vec, +} + +impl File { + /// Write the provided bytes to a file + pub fn write_bytes(&mut self, bytes: &[u8]) { + for byte in bytes { + self.data_pointer.push(*byte); + } + + self.meta_data.size = self.data_pointer.len(); + } + + pub fn new(location: FileLocations, file_name: String, file_type: String) -> Self { + let bytes: Vec = vec![]; + let abc123 = bytes; + + Self { + location, + file_name, + meta_data: FileMetadata { file_type, size: 0 }, + data_pointer: abc123, + } + } + + pub fn size(&self) -> usize { + self.meta_data.size.clone() + } + + pub fn read_to_string(&mut self, _string: &mut String) { + todo!(); + } + + pub fn read_and_return(&mut self) -> String { + String::from_utf8(self.data_pointer.clone()).expect("Found invalid UTF-8") + } +} + +impl fmt::Display for File { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}://{}", self.location, self.file_name) + } +} diff --git a/ableos/src/proto_filetable/mod.rs b/ableos/src/proto_filetable/mod.rs new file mode 100644 index 000000000..51103af3c --- /dev/null +++ b/ableos/src/proto_filetable/mod.rs @@ -0,0 +1,61 @@ +//! A file table module for AbleOS +//! +//! This module provides a file table interface for AbleOS. +//! +//! # Examples +//! ``` +//! use relib::filesystem::ProtoFileTable; +//! let mut file_table = ProtoFileTable::new(); +//! file_table.add_file("test.txt", "Hello, world!".as_bytes()); +//! let file = file_table.get_file("test.txt"); +//! assert_eq!(file.unwrap().as_slice(), "Hello, world!".as_bytes()); +//! ``` +//! # Notes +//! The file table is a simple in-memory hashmap. +//! The file table is not thread safe. +//! The file table is not persistent. + +use alloc::{ + string::{String, ToString}, + vec::Vec, +}; + +use hashbrown::HashMap; + +pub mod contain; +pub mod file; +use file::File; +/// A prototype file table for AbleOS +/// +/// This module provides a file table interface for AbleOS. +/// +/// # Examples +/// ``` +/// use crate::filesystem::ProtoFileTable; +/// let mut file_table = ProtoFileTable::new(); +/// file_table.add_file("test.txt", "Hello, world!".as_bytes()); +/// let file = file_table.get_file("test.txt"); +/// assert_eq!(file.unwrap().as_slice(), "Hello, world!".as_bytes()); +/// ``` +pub struct ProtoFileTable { + files: HashMap, +} + +impl ProtoFileTable { + pub fn new() -> ProtoFileTable { + ProtoFileTable { + files: HashMap::new(), + } + } + + pub fn add_file(&mut self, path: &str, contents: File) { + self.files.insert(path.to_string(), contents); + } + + pub fn get_file(&self, path: &str) -> Option<&File> { + self.files.get(path) + } +} + +#[cfg(test)] +mod tests; diff --git a/ableos/src/proto_filetable/tests.rs b/ableos/src/proto_filetable/tests.rs new file mode 100644 index 000000000..2877b2ebc --- /dev/null +++ b/ableos/src/proto_filetable/tests.rs @@ -0,0 +1,16 @@ +use super::file::FileLocations; + +use super::*; + +// #[test] +fn test_add_file() { + let mut file_table = ProtoFileTable::new(); + let file_to_add = File::new(FileLocations::Bin, "test".to_string(), "txt".to_string()); + file_to_add.write_bytes(b"Hello, world!"); + file_table.add_file("test", file_to_add); + let file = file_table.get_file("test.txt"); + assert_eq!( + file.unwrap().data_pointer.as_slice(), + "Hello, world!".as_bytes() + ); +} diff --git a/ableos/src/relib/filesystem/mod.rs b/ableos/src/relib/filesystem/mod.rs deleted file mode 100644 index e69de29bb..000000000 diff --git a/ableos/src/relib/math/mod.rs b/ableos/src/relib/math/mod.rs index bd4b7e1a2..bb39ef7e9 100644 --- a/ableos/src/relib/math/mod.rs +++ b/ableos/src/relib/math/mod.rs @@ -1,2 +1,3 @@ +//! A standard implementation of common math functions + pub mod ciphers; -pub mod rand; diff --git a/ableos/src/relib/math/rand/linearshift.rs b/ableos/src/relib/math/rand/linearshift.rs deleted file mode 100644 index 0bdd4752b..000000000 --- a/ableos/src/relib/math/rand/linearshift.rs +++ /dev/null @@ -1,32 +0,0 @@ -use crate::relib::math::rand::RNG; - -pub struct LinearShiftRegister { - reg: u64, -} -// 64 bit -// non-cryptographically secure -impl RNG for LinearShiftRegister { - fn new() -> Self { - Self { reg: (1 << 63) | 1 } - } - fn rand(&mut self) -> u64 { - let newbit = (self.reg >> 1) ^ (self.reg >> 2) ^ (self.reg >> 7); - - self.reg = (self.reg >> 1) | (newbit << 3); - newbit - } - fn seed(&mut self, seed: u64) { - let entropy = 34; // replace with hardware entropy - - let shifted = (self.reg >> 1) ^ ((self.reg >> 2) + entropy); - let x: u64 = 2983745; - let x123: u64 = 100000000; - let multitude: u64 = x123.wrapping_mul(x) / x; - let mult = shifted.wrapping_mul(multitude); - let seeded_bit = seed / mult; - - for _ in 0..seeded_bit { - self.rand(); - } - } -} diff --git a/ableos/src/relib/math/rand/mod.rs b/ableos/src/relib/math/rand/mod.rs deleted file mode 100644 index 4617a4f60..000000000 --- a/ableos/src/relib/math/rand/mod.rs +++ /dev/null @@ -1,85 +0,0 @@ -#![allow(dead_code)] -pub mod linearshift; -pub mod prand; -pub mod wichmanhillrand; // FIXEME: Reimplement -use lazy_static::lazy_static; -use linearshift::LinearShiftRegister; -use prand::PRand; -pub trait RNG { - fn new() -> Self; - fn rand(&mut self) -> u64; - fn seed(&mut self, seed: u64); -} - -pub type KeyEntropyHandler = u8; - -pub struct Entropy { - // Everytime entropy is used decrement bits count - bytes_count: u8, // 167 is our lower desired bit count - pool_index: u8, - pool: [u64; 255], -} -impl Entropy { - pub fn new() -> Self { - Self { - bytes_count: 0, - pool: [0; 255], - pool_index: 0, - } - } - pub fn poll_hardware() { - todo!(); - } - pub fn read_entropy(&mut self) -> u8 { - self.bytes_count -= 1; - 1 - } -} -impl Default for Entropy { - fn default() -> Self { - Self::new() - } -} -pub struct RandomHandeler { - prand: prand::PRand, - linearshift: linearshift::LinearShiftRegister, - entropy: Entropy, -} -impl RandomHandeler { - pub fn seed_entropy(&mut self) { - // n is even - self.prand - .seed(self.entropy.pool[self.entropy.pool_index as usize]); - //otherwise odd - self.linearshift - .seed(self.entropy.pool[self.entropy.pool_index as usize]); - } - - pub fn seed_entropy_keyboard(&mut self, key: u8) { - self.entropy.pool_index += key; - if self.entropy.pool_index > 254 { - self.entropy.pool_index = 0 - } - self.entropy.pool[self.entropy.pool_index as usize] += key as u64; - - self.entropy.pool_index += 1; - } - pub fn seed_entropy_timer(&mut self, seed: u64) { - let bytes = seed.to_be_bytes(); - - for byte in bytes { - if self.entropy.pool_index > 254 { - self.entropy.pool_index = 0 - } - self.entropy.pool[self.entropy.pool_index as usize] += byte as u64; - self.entropy.pool_index += 1; - } - } -} -lazy_static! { - pub static ref RAND_HANDLE: spin::Mutex = spin::Mutex::new(RandomHandeler { - prand: PRand::new(), - linearshift: LinearShiftRegister::new(), - entropy: Entropy::new(), - }); -} diff --git a/ableos/src/relib/math/rand/prand.rs b/ableos/src/relib/math/rand/prand.rs deleted file mode 100644 index 509df21ab..000000000 --- a/ableos/src/relib/math/rand/prand.rs +++ /dev/null @@ -1,17 +0,0 @@ -use crate::relib::math::rand::RNG; -pub struct PRand { - next: u64, -} -impl RNG for PRand { - fn new() -> Self { - Self { next: 7 } - } - fn rand(&mut self) -> u64 { - let internal_seed_1 = 21354; - self.next = self.next.wrapping_mul(1103515245) + internal_seed_1; - (self.next / 65536) % 32768 - } - fn seed(&mut self, seed: u64) { - self.next = seed; - } -} diff --git a/ableos/src/relib/math/rand/wichmanhillrand.rs b/ableos/src/relib/math/rand/wichmanhillrand.rs deleted file mode 100644 index 9857c6d2a..000000000 --- a/ableos/src/relib/math/rand/wichmanhillrand.rs +++ /dev/null @@ -1,27 +0,0 @@ -use crate::relib::math::rand::RNG; -pub struct WichmannHillRand { - seed0: u16, - seed1: u16, - seed2: u16, -} -impl RNG for WichmannHillRand { - fn new() -> Self { - Self { - seed0: 123, - seed1: 456, - seed2: 789, - } - } - fn rand(&mut self) -> u64 { - self.seed0 = (self.seed0.wrapping_mul(170)) % 30269; - self.seed1 = (self.seed1.wrapping_mul(172)) % 30307; - self.seed2 = (self.seed2.wrapping_mul(173)) % 30323; - - (self.seed0 / 30269 + self.seed1 / 30307 + self.seed2 / 30323).into() - } - fn seed(&mut self, seed: u64) { - self.seed0 = (seed >> 48) as u16; - self.seed1 = ((seed << 16) >> 48) as u16; - self.seed2 = ((seed << 32) >> 48) as u16; - } -} diff --git a/ableos/src/relib/mod.rs b/ableos/src/relib/mod.rs index bd08214ec..4cea1c902 100644 --- a/ableos/src/relib/mod.rs +++ b/ableos/src/relib/mod.rs @@ -1,3 +1,5 @@ +//! A simple reimplimentation of the the rust standard library + pub mod clparse; pub mod encoding; pub mod image; diff --git a/ableos/src/relib/security/mod.rs b/ableos/src/relib/security/mod.rs index 8b1378917..71c79f1ad 100644 --- a/ableos/src/relib/security/mod.rs +++ b/ableos/src/relib/security/mod.rs @@ -1 +1,23 @@ +// Copilot module +// Language: rust +//! Security module. +//! +//! This module provides a security interface for AbleOS. +//! +//! # Examples +//! ``` +//! use crate::security::Security; +//! +//! let mut security = Security::new(); +//! security.add_user("admin", "password"); +//! security.add_user("user", "password"); +//! security.add_user("guest", "password"); +//! +//! assert_eq!(security.authenticate("admin", "password"), true); +//! assert_eq!(security.authenticate("user", "password"), true); +//! assert_eq!(security.authenticate("guest", "password"), true); +//! assert_eq!(security.authenticate("admin", "password2"), false); +//! assert_eq!(security.authenticate("user", "password2"), false); +//! assert_eq!(security.authenticate("guest", "password2"), false); +//! ``` diff --git a/ableos/src/scheduler/capabilities.rs b/ableos/src/scheduler/capabilities.rs index 5baf6a001..7e53501af 100644 --- a/ableos/src/scheduler/capabilities.rs +++ b/ableos/src/scheduler/capabilities.rs @@ -1,51 +1,60 @@ use alloc::vec::Vec; -/// Placeholder to be replaced with a proper FileReference when such a thing exists -pub type FileID = u8; +use crate::file::PathRep; + pub type SoundCardID = u8; pub type DeviceID = u8; pub type ControllerID = u8; -#[derive(Clone, Debug)] +#[derive(Clone, Debug, PartialEq)] pub enum FileAccess { All, - Some(Vec), + Some(Vec), None, } -#[derive(Clone, Debug)] +#[derive(Clone, Debug, PartialEq)] pub enum ControllerAccess { All, Some(Vec), None, } -#[derive(Clone, Debug)] +#[derive(Clone, Debug, PartialEq)] pub enum SoundCardAccess { All, Some(Vec), None, } -#[derive(Clone, Debug)] +#[derive(Clone, Debug, PartialEq)] pub enum MouseAccess { Yes, No, } -#[derive(Clone, Debug)] +#[derive(Clone, Debug, PartialEq)] pub enum KeyboardAccess { Yes, No, } -#[derive(Clone, Debug)] +#[derive(Clone, Debug, PartialEq)] +pub enum NetworkAccess { + Yes, + No, +} + +/// A set of capabilities that a process has +#[derive(Clone, Debug, PartialEq)] pub struct Capabilities { - files: FileAccess, - mouse: MouseAccess, - keyboard: KeyboardAccess, - controllers: ControllerAccess, - sound_cards: SoundCardAccess, + pub files: FileAccess, + pub mouse: MouseAccess, + pub keyboard: KeyboardAccess, + pub controllers: ControllerAccess, + pub sound_cards: SoundCardAccess, + + pub network_access: NetworkAccess, } impl Capabilities { @@ -57,8 +66,7 @@ impl Capabilities { keyboard: KeyboardAccess::No, controllers: ControllerAccess::None, sound_cards: SoundCardAccess::None, + network_access: NetworkAccess::No, } } } - - diff --git a/ableos/src/scheduler/mod.rs b/ableos/src/scheduler/mod.rs index 125aab47a..9ad5b45e3 100644 --- a/ableos/src/scheduler/mod.rs +++ b/ableos/src/scheduler/mod.rs @@ -3,7 +3,10 @@ use alloc::{vec, vec::Vec}; pub mod capabilities; pub mod proc; -use proc::{Process, ProcessPermissions, PID}; +use proc::{Process, PID}; + +#[cfg(test)] +mod tests; use self::capabilities::Capabilities; @@ -14,8 +17,6 @@ lazy_static::lazy_static!( ); -// pub struct VirtualMemoryTable {} - /// Scheduler priority model #[derive(Clone, Copy, Debug)] pub enum Priority { @@ -38,24 +39,56 @@ pub enum FileAccessTypes { None, } +/// This structure handles the process scheduling and execution /// +/// # Example +/// ``` +/// use crate::scheduler::Priority; +/// use crate::scheduler::Scheduler; +/// +/// let mut scheduler = Scheduler::new(); +/// +/// let pid = scheduler.new_process(Priority::High); +/// scheduler.run_process(pid); +/// ``` #[derive(Clone, Debug)] pub struct Scheduler { + /// The highest free process ID pub free_pid: PID, - + /// The execution time of the current process in ticks pub process_exec_time: u64, + /// The list of processes pub list: Vec, } impl Scheduler { + /// Create a new scheduler + /// + /// # Example + /// ``` + /// use ableos::scheduler::Priority; + /// let mut scheduler = Scheduler::new(); + /// ``` pub fn new() -> Self { Self { - list: vec![], - process_exec_time: 0, free_pid: PID(0), + process_exec_time: 0, + list: Vec::new(), } } + /// Change the current process to the next process in the list + /// + /// # Example + /// + /// ``` + /// let mut scheduler = scheduler(); + /// let mut process = scheduler.next_process(); + /// ``` + /// + /// # Panics + /// + /// Panics if there are no processes in the list pub fn next_process(&mut self) { self.process_exec_time = 0; let previous_task = self.list[0].clone(); @@ -63,19 +96,47 @@ impl Scheduler { self.list.push(previous_task); } - /// Create a - pub fn new_process(&mut self, priority: Priority) { - // let new_pid = self.free_pid; - + /// Creates a new process + /// + /// # Arguments + /// + /// * `priority` - The priority of the process + /// + /// # Example + /// + /// ``` + /// let mut scheduler = scheduler(); + /// let mut process = scheduler.new_process(Priority::Medium); + /// ``` + pub fn new_process(&mut self, priority: Priority) -> Process { let process = Process { id: self.free_pid.clone(), capabilities: Capabilities::empty(), priority, }; - self.free_pid.0 += 1; + // self.free_pid.0 += 1; + // self.list.push(process); + process + } + + pub fn add_process(&mut self, process: Process) { self.list.push(process); + + self.free_pid.0 += 1; } /// Terminate the process with the matching PID + /// + /// # Arguments + /// + /// * `pid` - The PID of the process to terminate + /// + /// # Example + /// + /// ``` + /// let mut scheduler = scheduler(); + /// let mut process = scheduler.new_process(Priority::Medium); + /// scheduler.terminate_process(process.id); + /// ``` pub fn term_process(&mut self, pid: PID) { let mut process_index = 0; for x in &self.list { @@ -86,11 +147,19 @@ impl Scheduler { process_index += 1 } } - + /// Bump the current process' execution time + /// + /// # Example + /// + /// ``` + /// let mut scheduler = scheduler(); + /// let mut process = scheduler.new_process(Priority::Medium); + /// scheduler.bump_exec(); + /// ``` pub fn bump_exec(&mut self) { self.process_exec_time += 1; - use Priority::*; + use Priority::*; if self.list.len() > 0 { match (self.process_exec_time, self.list[0].priority) { (20, High) => { diff --git a/ableos/src/scheduler/proc.rs b/ableos/src/scheduler/proc.rs index 23139c521..6b265e9c4 100644 --- a/ableos/src/scheduler/proc.rs +++ b/ableos/src/scheduler/proc.rs @@ -7,12 +7,6 @@ use super::{capabilities::Capabilities, FileAccessTypes, Priority}; pub struct PID(pub usize); -/// Temporary till integration of capabilities -#[derive(Clone, Debug)] -pub struct ProcessPermissions { - pub file_access: FileAccessTypes, -} - /// A process #[derive(Clone, Debug)] pub struct Process { diff --git a/ableos/src/scheduler/tests.rs b/ableos/src/scheduler/tests.rs new file mode 100644 index 000000000..f76799eed --- /dev/null +++ b/ableos/src/scheduler/tests.rs @@ -0,0 +1,49 @@ +use super::*; + +use crate::scheduler::{ + capabilities::{ControllerAccess, FileAccess, KeyboardAccess, MouseAccess, SoundCardAccess}, + proc::PID, + Priority::*, + Scheduler, +}; + +// #[test] +fn test_new_process() { + let mut scheduler = Scheduler::new(); + scheduler.new_process(High); + assert_eq!(scheduler.list.len(), 1); +} + +// #[test] +fn test_next_process() { + let mut scheduler = Scheduler::new(); + scheduler.new_process(High); + scheduler.next_process(); + assert_eq!(scheduler.list.len(), 0); +} + +// #[test] +fn test_term_process() { + let mut scheduler = Scheduler::new(); + scheduler.new_process(High); + scheduler.term_process(PID(1)); + assert_eq!(scheduler.list.len(), 0); +} + +// #[test] +fn test_bump_exec() { + let mut scheduler = Scheduler::new(); + scheduler.new_process(High); + scheduler.bump_exec(); + assert_eq!(scheduler.process_exec_time, 1); +} + +// #[test] +fn test_capabilities() { + let caps = Capabilities::empty(); + assert_eq!(caps.files, FileAccess::None); + assert_eq!(caps.mouse, MouseAccess::No); + assert_eq!(caps.keyboard, KeyboardAccess::No); + assert_eq!(caps.controllers, ControllerAccess::None); + assert_eq!(caps.sound_cards, SoundCardAccess::None); +} diff --git a/ableos/src/utils.rs b/ableos/src/utils.rs index 615fd90ff..91088e7d0 100644 --- a/ableos/src/utils.rs +++ b/ableos/src/utils.rs @@ -6,3 +6,13 @@ pub fn type_of(_: &T) -> &str { core::any::type_name::() } + +#[cfg(test)] +mod tests { + use super::*; + + // #[test] + fn test_type_of() { + assert_eq!(type_of(&1), "i32"); + } +} diff --git a/ableos/src/vga_e.rs b/ableos/src/vga_e.rs index 773193f7f..0f0c1bf49 100644 --- a/ableos/src/vga_e.rs +++ b/ableos/src/vga_e.rs @@ -1,3 +1,7 @@ +use shadeable::pixel_format::Rgba64; + +use crate::SCREEN_BUFFER; + use { ab_glyph::{Font, FontRef, Glyph}, vga::{ @@ -16,15 +20,16 @@ lazy_static::lazy_static! { pub static ref VGAE_BUFF_OFFSET_Y: spin::Mutex = spin::Mutex::new(0); } -pub fn draw_char(previous_character: Option, character: char, _offset: usize) { - let mode = *VGAE.lock(); - let mut offset_x = VGAE_BUFF_OFFSET_X.lock(); - let mut offset_y = VGAE_BUFF_OFFSET_Y.lock(); - - if *offset_x == 39 { - *offset_x = 0; - *offset_y += 1; - } +/// Draw a glyph on the screen at the given position +/// +/// # Arguments +/// * `x` - the x position of the glyph +/// * `y` - the y position of the glyph +/// * `glyph` - the glyph to draw +/// * `color` - the color of the glyph +pub fn draw_char(x: u8, y: u8, character: char, color: Rgba64) { + // let mode = *VGAE.lock(); + let mut mode = SCREEN_BUFFER.lock(); let font = FontRef::try_from_slice(include_bytes!( "../../ableos/assets/fonts/unifont-14.0.01.ttf" @@ -55,29 +60,10 @@ pub fn draw_char(previous_character: Option, character: char, _offset: usi match character { '\n' => {} _ => { - let previous_glyph: Glyph = used_font - .glyph_id(previous_character.unwrap_or(' ')) - .with_scale_and_position( - 20.0 * font_scale, - ab_glyph::point( - *offset_x as f32 * (10.0 * font_scale), - *offset_y as f32 + (18.0 * font_scale), - ), - ); - let mut q_glyph: Glyph = used_font.glyph_id(character).with_scale_and_position( 20.0 * font_scale, - ab_glyph::point( - *offset_x as f32 * (10.0 * font_scale), - *offset_y as f32 + (18.0 * font_scale), - ), + ab_glyph::point(10.0 * font_scale, 18.0 * font_scale), ); - { - // figure it our latter bruh - let spacing = used_font.kern_unscaled(previous_glyph.id, q_glyph.id); - // info!("{spacing} {:?} {:?}", previous_glyph.id, q_glyph.id); - q_glyph.position.x += spacing * font_scale; - } if let Some(q) = used_font.outline_glyph(q_glyph) { q.draw(|x, y, c| { @@ -86,13 +72,11 @@ pub fn draw_char(previous_character: Option, character: char, _offset: usi mode.set_pixel( x as usize + corner.x as usize, y as usize + corner.y as usize, - Color16::Green, + color, ); } }); } - - *offset_x += 1; } } } diff --git a/ableos/src/virtio/mod.rs b/ableos/src/virtio/mod.rs new file mode 100644 index 000000000..2a5ff3fdc --- /dev/null +++ b/ableos/src/virtio/mod.rs @@ -0,0 +1,61 @@ +//! virtio device +//! +//! This module contains the virtio device structural code. +//! +//! # Notes +//! https://docs.oasis-open.org/virtio/virtio/v1.1/csprd01/virtio-v1.1-csprd01.html#x1-20001 + +pub struct VirtioDevice { + status: VirtioDeviceStatus, +} + +#[repr(C)] +pub enum VirtioDeviceStatus { + // Indicates that the guest OS has found the device and recognized it as a valid virtio device. + Acknowleged = 1, + // Indicates that the guest OS knows how to drive the device. Note: There could be a significant (or infinite) delay before setting this bit. For example, under Linux, drivers can be loadable modules. + Driver = 2, + // Indicates that the driver has acknowledged all the features it understands, and feature negotiation is complete. + FeaturesOk = 8, + // Indicates that the device is set up and ready to drive the device. + DriverOk = 4, + // Indicates that the device needs to be reset. + DeviceNeedsReset = 64, + // Indicates that the device has failed. + Failed = 128, +} + +pub struct FeaturesBits(u64); +impl FeaturesBits { + // bit mask the first 23 bits and return a u64 + // 0 to 23 + // Feature bits for the specific device type + pub fn device_type_features(&self) -> u64 { + 0 + } + + // bit mask the 24th bit to the 37th bit and return a u64 + // 24 to 37 + // Feature bits reserved for extensions to the queue and feature negotiation mechanisms + pub fn extension_features(&self) -> u64 { + 0 + } + + // bit mask the 38th bit to the 63th bit and return a u64 + // 38 and above + // Feature bits reserved for future extensions. + pub fn future_features(&self) -> u64 { + 0 + } +} + +// configuration change notification +// available buffer notification +// used buffer notification. + +#[repr(C)] +pub struct VirtioDeviceNotification { + pub type_: u32, + pub index: u32, + pub value: u32, +} diff --git a/ableos/src/wasm/mod.rs b/ableos/src/wasm/mod.rs index 152ee5ee2..436ad2f84 100644 --- a/ableos/src/wasm/mod.rs +++ b/ableos/src/wasm/mod.rs @@ -5,21 +5,78 @@ pub const WASM_BINARY_MAGIC: [u8; 4] = [0x00, 0x61, 0x73, 0x6d]; /// `1 0 0 0` as an array of 4 bytes pub const WASM_VERSION: [u8; 4] = [0x01, 0x00, 0x00, 0x00]; -/// Validate a wasm header (8 bytes) - +/// A wasm section +/// +/// # Examples +/// ``` +/// use wasm_loader::wasm::WasmSection; +/// let section = WasmSection::new(0, vec![0x00, 0x01, 0x02, 0x03]); +/// assert_eq!(section.id, 0); +/// assert_eq!(section.data, vec![0x00, 0x01, 0x02, 0x03]); +/// ``` +/// # Notes +/// The wasm spec defines the following section types: +/// * `0`: custom +/// * `1`: type +/// * `2`: import +/// * `3`: function +/// * `4`: table +/// * `5`: memory +/// * `6`: global +/// * `7`: export +/// * `8`: start +/// * `9`: element +/// * `10`: code +/// * `11`: data pub enum SectionType { None = 0, Type = 1, + Import = 2, + Function = 3, + Table = 4, + Memory = 5, + Global = 6, + Export = 7, + Start = 8, + Element = 9, + Code = 10, + Data = 11, } pub struct Section { + /// The section type stype: SectionType, section_size: u8, } +/// A wasm type +/// # Examples +/// ``` +/// use wasm_loader::wasm::WasmType; +/// let type_ = WasmType::new(vec![0x00, 0x01, 0x02, 0x03]); +/// assert_eq!(type_.subtypes, vec![0x00, 0x01, 0x02, 0x03]); +/// ``` +/// # Notes +/// The wasm spec defines the following type subtypes: +/// * `0`: anyfunc +/// * `1`: func +/// * `2`: block +/// * `3`: i32 +/// * `4`: i64 +/// * `5`: f32 +/// * `6`: f64 +pub enum WasmType { + Anyfunc = 0, + Func = 1, + Block = 2, + I32 = 3, + I64 = 4, + F32 = 5, + F64 = 6, +} + pub struct WasmProgram { raw_bytes: Vec, - // version: } impl WasmProgram { @@ -28,7 +85,16 @@ impl WasmProgram { raw_bytes: bytes.to_vec(), } } - + /// Returns the a tuple of two bools + /// The first bool is true if the wasm binary is valid + /// The second bool is true if the wasm binary version is 1 + /// + /// # Examples + /// ``` + /// use wasm_loader::wasm::WasmProgram; + /// let wasm_program = WasmProgram::new_from_bytes(b"\0\0\0\0\1\0\0\0"); + /// assert_eq!(wasm_program.is_valid(), (true, false)); + /// ``` pub fn validate_header(self) -> (bool, bool) { let mut byte_magic_valid = false; let mut byte_version_valid = false; @@ -42,9 +108,4 @@ impl WasmProgram { } return (byte_magic_valid, byte_version_valid); } - - - - - } diff --git a/facepalm/Cargo.lock b/facepalm/Cargo.lock index b3c338d0d..0cbf9d3e7 100644 --- a/facepalm/Cargo.lock +++ b/facepalm/Cargo.lock @@ -2,6 +2,24 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + [[package]] name = "facepalm" version = "0.1.0" +dependencies = [ + "log", +] + +[[package]] +name = "log" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +dependencies = [ + "cfg-if", +] diff --git a/facepalm/Cargo.toml b/facepalm/Cargo.toml index 581272b20..00a78e61a 100644 --- a/facepalm/Cargo.toml +++ b/facepalm/Cargo.toml @@ -6,3 +6,4 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +log = "0.4.0" \ No newline at end of file diff --git a/facepalm/src/lib.rs b/facepalm/src/lib.rs new file mode 100644 index 000000000..bde9c15ce --- /dev/null +++ b/facepalm/src/lib.rs @@ -0,0 +1,19 @@ +#![no_std] + +// extern crate alloc; + +use log::*; + +pub const VERSION: &str = env!("CARGO_PKG_VERSION"); + +#[cfg(debug_assertions)] +pub const RELEASE_TYPE: &str = "debug"; + +#[cfg(not(debug_assertions))] +pub const RELEASE_TYPE: &str = "release"; + +pub fn start_facepalm() { + info!("facepalm 🤦 launched!"); + info!("facepalm 🤦 version: {}", VERSION); + info!("facepalm 🤦 {} mode", RELEASE_TYPE); +} diff --git a/facepalm/src/main.rs b/facepalm/src/main.rs deleted file mode 100644 index e7a11a969..000000000 --- a/facepalm/src/main.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - println!("Hello, world!"); -}