forked from koniifer/ableos
Fixed pixel_format.rs
This commit is contained in:
commit
fd9c18c744
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
|
@ -1,5 +1,8 @@
|
||||||
{
|
{
|
||||||
"files.associations": {
|
"files.associations": {
|
||||||
"stddef.h": "c"
|
"stddef.h": "c"
|
||||||
|
},
|
||||||
|
"settings": {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -21,6 +21,6 @@ repbuild can be used to run and build docs for able os
|
||||||
## Testing on real hardware
|
## Testing on real hardware
|
||||||
I recommend using an old x86_64 computer
|
I recommend using an old x86_64 computer
|
||||||
* `cargo run --release` to generate a binary image that is bootable
|
* `cargo run --release` to generate a binary image that is bootable
|
||||||
* flash it to a USB device via `dd` or belenaEtcher
|
* flash it to a USB device via `dd` or balenaEtcher
|
||||||
* Remove said USB device and plug into test machine
|
* Remove said USB device and plug into test machine
|
||||||
* assure test machine boots from USB devices
|
* assure test machine boots from USB devices
|
||||||
|
|
|
@ -7,7 +7,10 @@ build-std-features = ["compiler-builtins-mem"]
|
||||||
|
|
||||||
|
|
||||||
[target.'cfg(target_arch = "x86_64")']
|
[target.'cfg(target_arch = "x86_64")']
|
||||||
|
<<<<<<< HEAD
|
||||||
# --quiet suppresses warning messages from the bootimage crate
|
# --quiet suppresses warning messages from the bootimage crate
|
||||||
|
=======
|
||||||
|
>>>>>>> 9bba5ae0fa0b592727d97ff033f639e3e07b2a74
|
||||||
runner = "bootimage runner"
|
runner = "bootimage runner"
|
||||||
|
|
||||||
[target.riscv64gc-unknown-none-elf]
|
[target.riscv64gc-unknown-none-elf]
|
||||||
|
|
26
ableos/Cargo.lock
generated
26
ableos/Cargo.lock
generated
|
@ -30,6 +30,8 @@ dependencies = [
|
||||||
"bootloader",
|
"bootloader",
|
||||||
"cpuio",
|
"cpuio",
|
||||||
"externc-libm",
|
"externc-libm",
|
||||||
|
"facepalm",
|
||||||
|
"hashbrown",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"linked_list_allocator",
|
"linked_list_allocator",
|
||||||
"lliw",
|
"lliw",
|
||||||
|
@ -48,7 +50,6 @@ dependencies = [
|
||||||
"vga",
|
"vga",
|
||||||
"volatile 0.2.7",
|
"volatile 0.2.7",
|
||||||
"wasmi",
|
"wasmi",
|
||||||
"watson",
|
|
||||||
"x86_64",
|
"x86_64",
|
||||||
"y-compositor-protocol",
|
"y-compositor-protocol",
|
||||||
]
|
]
|
||||||
|
@ -172,6 +173,13 @@ dependencies = [
|
||||||
"libm",
|
"libm",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "facepalm"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"log",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "font8x8"
|
name = "font8x8"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
|
@ -670,22 +678,6 @@ dependencies = [
|
||||||
"parity-wasm",
|
"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]]
|
[[package]]
|
||||||
name = "x86_64"
|
name = "x86_64"
|
||||||
version = "0.14.7"
|
version = "0.14.7"
|
||||||
|
|
|
@ -15,11 +15,16 @@ run-args = [
|
||||||
"stdio",
|
"stdio",
|
||||||
"-smp",
|
"-smp",
|
||||||
"cores=2",
|
"cores=2",
|
||||||
# "-device",
|
|
||||||
# "virtio-gpu",
|
|
||||||
|
|
||||||
|
|
||||||
|
# An example gpu used with ableOS
|
||||||
|
"-device",
|
||||||
|
"virtio-gpu",
|
||||||
|
|
||||||
|
# An example disk used with ableOS
|
||||||
"-device",
|
"-device",
|
||||||
"virtio-blk-pci,drive=drive0,id=virtblk0,num-queues=4",
|
"virtio-blk-pci,drive=drive0,id=virtblk0,num-queues=4",
|
||||||
|
# A simple example of a boot image
|
||||||
"-drive",
|
"-drive",
|
||||||
"file=disk.qcow2,if=none,id=drive0",
|
"file=disk.qcow2,if=none,id=drive0",
|
||||||
]
|
]
|
||||||
|
@ -40,7 +45,7 @@ log = "*"
|
||||||
pretty-hex = "0.2.1"
|
pretty-hex = "0.2.1"
|
||||||
unicode-width = "0.1.7"
|
unicode-width = "0.1.7"
|
||||||
picorand = "*"
|
picorand = "*"
|
||||||
watson = "0.4"
|
# watson = "0.4"
|
||||||
|
|
||||||
[dependencies.serde]
|
[dependencies.serde]
|
||||||
version = "*"
|
version = "*"
|
||||||
|
@ -52,6 +57,11 @@ version = "*"
|
||||||
default-features = false
|
default-features = false
|
||||||
features = ["alloc"]
|
features = ["alloc"]
|
||||||
|
|
||||||
|
[dependencies.hashbrown]
|
||||||
|
version = "*"
|
||||||
|
default-features = false
|
||||||
|
features = ["inline-more"]
|
||||||
|
|
||||||
[dependencies.rkyv]
|
[dependencies.rkyv]
|
||||||
version = "0.7.29"
|
version = "0.7.29"
|
||||||
default-features = false
|
default-features = false
|
||||||
|
@ -68,6 +78,9 @@ git = "https://git.ablecorp.us:443/able/y-compositor-protocol.git"
|
||||||
[dependencies.shadeable]
|
[dependencies.shadeable]
|
||||||
path = "../shadeable"
|
path = "../shadeable"
|
||||||
|
|
||||||
|
[dependencies.facepalm]
|
||||||
|
path = "../facepalm"
|
||||||
|
|
||||||
[dependencies.ab_glyph]
|
[dependencies.ab_glyph]
|
||||||
version = "*"
|
version = "*"
|
||||||
default-features = false
|
default-features = false
|
||||||
|
@ -83,7 +96,7 @@ features = ["spin_no_std"]
|
||||||
version = "1.0"
|
version = "1.0"
|
||||||
|
|
||||||
[dependencies.externc-libm]
|
[dependencies.externc-libm]
|
||||||
git = "https://git.ablecorp.us/able/externc-libm.git"
|
git = "https://git.ablecorp.us:443/able/externc-libm.git"
|
||||||
|
|
||||||
[target.'cfg(target_arch = "x86_64")'.dependencies]
|
[target.'cfg(target_arch = "x86_64")'.dependencies]
|
||||||
bootloader = { version = "0.9.8", features = ["map_physical_memory"] }
|
bootloader = { version = "0.9.8", features = ["map_physical_memory"] }
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// #![allow(clippy::print_literal)]
|
// #![allow(clippy::print_literal)]
|
||||||
use crate::logger;
|
use crate::{logger, SCHEDULER};
|
||||||
|
|
||||||
use super::{gdt, interrupts};
|
use super::{gdt, interrupts};
|
||||||
|
|
||||||
|
@ -11,7 +11,15 @@ pub fn init() {
|
||||||
Err(err) => error!("{}", err),
|
Err(err) => error!("{}", err),
|
||||||
}
|
}
|
||||||
gdt::init();
|
gdt::init();
|
||||||
|
|
||||||
|
use crate::scheduler::Priority;
|
||||||
|
let mut scheduler = SCHEDULER.lock();
|
||||||
|
use Priority::*;
|
||||||
|
scheduler.new_process(High);
|
||||||
|
drop(scheduler);
|
||||||
|
|
||||||
interrupts::init_idt();
|
interrupts::init_idt();
|
||||||
|
|
||||||
unsafe { interrupts::PICS.lock().initialize() };
|
unsafe { interrupts::PICS.lock().initialize() };
|
||||||
x86_64::instructions::interrupts::enable();
|
x86_64::instructions::interrupts::enable();
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,9 @@ use alloc::{format, vec::Vec};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
boot_conf::BootConfig,
|
boot_conf::BootConfig,
|
||||||
scheduler::{self, SCHEDULER},
|
capabilities::FileAccess,
|
||||||
|
file::{File, PathRep},
|
||||||
|
scheduler::SCHEDULER,
|
||||||
};
|
};
|
||||||
|
|
||||||
// use crate::scheduler;
|
// use crate::scheduler;
|
||||||
|
@ -18,7 +20,6 @@ use {
|
||||||
systeminfo::{KERNEL_VERSION, RELEASE_TYPE},
|
systeminfo::{KERNEL_VERSION, RELEASE_TYPE},
|
||||||
},
|
},
|
||||||
graphics::{VgaBuffer, SCREEN_BUFFER},
|
graphics::{VgaBuffer, SCREEN_BUFFER},
|
||||||
relib::math::rand::RAND_HANDLE,
|
|
||||||
relib::network::socket::Socket,
|
relib::network::socket::Socket,
|
||||||
relib::network::socket::{SimpleSock, SocketReturns},
|
relib::network::socket::{SimpleSock, SocketReturns},
|
||||||
vga_e::{self, num_to_vga16},
|
vga_e::{self, num_to_vga16},
|
||||||
|
@ -50,12 +51,15 @@ lazy_static! {
|
||||||
pub static ref BOOT_CONF: BootConfig = boot_conf::BootConfig::new();
|
pub static ref BOOT_CONF: BootConfig = boot_conf::BootConfig::new();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The main entry point of the kernel
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub fn kernel_main() -> ! {
|
pub fn kernel_main() -> ! {
|
||||||
init::init();
|
init::init();
|
||||||
log::set_max_level(BOOT_CONF.log_level());
|
log::set_max_level(BOOT_CONF.log_level());
|
||||||
// info!("Initialized");
|
// info!("Initialized");
|
||||||
|
|
||||||
|
// facepalm::start_facepalm();
|
||||||
|
|
||||||
graphics_pipe_startup();
|
graphics_pipe_startup();
|
||||||
|
|
||||||
if false {
|
if false {
|
||||||
|
@ -81,21 +85,41 @@ pub fn kernel_main() -> ! {
|
||||||
let mut scheduler = SCHEDULER.lock();
|
let mut scheduler = SCHEDULER.lock();
|
||||||
|
|
||||||
use Priority::*;
|
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 {
|
for x in &scheduler.list {
|
||||||
trace!("{:?}", x);
|
trace!("{:?}", x);
|
||||||
}
|
}
|
||||||
drop(scheduler);
|
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;
|
use crate::wasm::WasmProgram;
|
||||||
let ret = WasmProgram::new_from_bytes(&[0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00]);
|
let ret = WasmProgram::new_from_bytes(&[0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00]);
|
||||||
trace!("Binary Valid: {:?}", ret.validate_header());
|
trace!("Binary Valid: {:?}", ret.validate_header());
|
||||||
|
@ -117,10 +141,6 @@ pub fn kernel_main() -> ! {
|
||||||
shader_tests();
|
shader_tests();
|
||||||
}
|
}
|
||||||
|
|
||||||
// graphics.copy_to_buffer();
|
|
||||||
|
|
||||||
// info!("buffer copied");
|
|
||||||
|
|
||||||
sloop()
|
sloop()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,8 +149,6 @@ pub fn tick() {
|
||||||
let mut data = TICK.load(Relaxed);
|
let mut data = TICK.load(Relaxed);
|
||||||
data += 1;
|
data += 1;
|
||||||
|
|
||||||
RAND_HANDLE.lock().seed_entropy_timer(data);
|
|
||||||
|
|
||||||
crate::kernel_state::KERNEL_STATE.lock().update_state();
|
crate::kernel_state::KERNEL_STATE.lock().update_state();
|
||||||
|
|
||||||
let mut scheduler = SCHEDULER.lock();
|
let mut scheduler = SCHEDULER.lock();
|
||||||
|
@ -138,10 +156,8 @@ pub fn tick() {
|
||||||
|
|
||||||
TICK.store(data, Relaxed)
|
TICK.store(data, Relaxed)
|
||||||
}
|
}
|
||||||
|
/// called every time a key is pressed to add it to the randomness pool
|
||||||
pub fn key_entropy(key: u8) {
|
pub fn key_entropy(key: u8) {}
|
||||||
RAND_HANDLE.lock().seed_entropy_keyboard(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn cpu_socket_startup() {
|
pub fn cpu_socket_startup() {
|
||||||
let mut cpu_info_socket = SimpleSock::new();
|
let mut cpu_info_socket = SimpleSock::new();
|
||||||
|
@ -210,7 +226,6 @@ pub fn screen_writer_test() {
|
||||||
let mut sock_print_id = SimpleSock::new();
|
let mut sock_print_id = SimpleSock::new();
|
||||||
|
|
||||||
sock_print_id.register_protocol("Screen Printer".to_string());
|
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!("a原 b画 cフ dァ eイ fル 集").into());
|
||||||
// sock_print_id.write(format!("⋮").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!("I look forward to ur ai stuff :^>").into());
|
||||||
// sock_print_id.write(format!("1....2....3....4....5....6....7....8....9").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() {
|
for current in (*String::from_utf8_lossy(&sock_print_id.peek().unwrap())).chars() {
|
||||||
vga_e::draw_char(prev, current, 0);
|
vga_e::draw_char(0, 0, current, 0);
|
||||||
|
|
||||||
prev = Some(current);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
//! hi
|
//! main library for the AbleOS kernel.
|
||||||
#![deny(missing_docs)]
|
//! exposing all the kernel functionality to the rest of the kernel.
|
||||||
|
//!
|
||||||
|
//!
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![feature(
|
#![feature(
|
||||||
abi_x86_interrupt,
|
abi_x86_interrupt,
|
||||||
|
@ -13,6 +16,7 @@
|
||||||
naked_functions
|
naked_functions
|
||||||
)]
|
)]
|
||||||
#![feature(exclusive_range_pattern)]
|
#![feature(exclusive_range_pattern)]
|
||||||
|
#![feature(slice_pattern)]
|
||||||
|
|
||||||
/// Contains architecture specific code for aarch64.
|
/// Contains architecture specific code for aarch64.
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
|
@ -35,24 +39,49 @@ pub mod print;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
pub extern crate log;
|
pub extern crate log;
|
||||||
|
|
||||||
|
/////////////
|
||||||
|
// Modules //
|
||||||
|
/////////////
|
||||||
pub mod allocator;
|
pub mod allocator;
|
||||||
pub mod boot_conf;
|
pub mod boot_conf;
|
||||||
pub mod driver_traits;
|
pub mod driver_traits;
|
||||||
pub mod experiments;
|
pub mod experiments;
|
||||||
pub mod graphics;
|
pub mod graphics;
|
||||||
|
pub mod kernel_state;
|
||||||
pub mod keyboard;
|
pub mod keyboard;
|
||||||
pub mod kmain;
|
pub mod kmain;
|
||||||
pub mod logger;
|
pub mod logger;
|
||||||
pub mod panic;
|
pub mod panic;
|
||||||
|
pub mod proto_filetable;
|
||||||
pub mod relib;
|
pub mod relib;
|
||||||
pub mod scheduler;
|
pub mod scheduler;
|
||||||
mod unicode_utils;
|
mod unicode_utils;
|
||||||
pub mod utils;
|
pub mod utils;
|
||||||
|
pub mod vga_e;
|
||||||
pub mod wasm;
|
pub mod wasm;
|
||||||
|
|
||||||
pub extern crate alloc;
|
pub extern crate alloc;
|
||||||
pub extern crate externc_libm as libm;
|
pub extern crate externc_libm as libm;
|
||||||
|
|
||||||
///////////////////////////////
|
//////////////////
|
||||||
pub mod kernel_state;
|
// Re-exports ///
|
||||||
pub mod vga_e;
|
////////////////
|
||||||
|
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::*;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use core::sync::atomic::Ordering;
|
use core::sync::atomic::Ordering;
|
||||||
|
|
||||||
use crate::kmain::{BOOT_CONF, TICK};
|
use crate::kmain::TICK;
|
||||||
use crate::serial_println;
|
use crate::serial_println;
|
||||||
use lliw::{Fg, Reset};
|
use lliw::{Fg, Reset};
|
||||||
pub use log::{debug, info, trace, warn};
|
pub use log::{debug, info, trace, warn};
|
||||||
|
@ -42,7 +42,7 @@ impl log::Log for SimpleLogger {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/// Clear the log buffer
|
||||||
fn flush(&self) {}
|
fn flush(&self) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,22 @@
|
||||||
use {crate::arch::sloop, core::panic::PanicInfo};
|
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]
|
#[panic_handler]
|
||||||
fn panic(info: &PanicInfo) -> ! {
|
fn panic(info: &PanicInfo) -> ! {
|
||||||
// println!("{}", info);
|
|
||||||
error!("{}", info);
|
error!("{}", info);
|
||||||
|
// help me use facepalm::start_facepalm;
|
||||||
|
|
||||||
sloop()
|
sloop()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn test_panic() {
|
||||||
|
panic!("test panic!");
|
||||||
|
}
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
*/
|
|
5
ableos/src/proto_filetable/contain.rs
Normal file
5
ableos/src/proto_filetable/contain.rs
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
use crate::ProtoFileTable;
|
||||||
|
|
||||||
|
lazy_static::lazy_static!(
|
||||||
|
pub static ref FILE_TABLE: spin::Mutex<ProtoFileTable> = spin::Mutex::new(ProtoFileTable::new());
|
||||||
|
);
|
76
ableos/src/proto_filetable/file.rs
Normal file
76
ableos/src/proto_filetable/file.rs
Normal file
|
@ -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<u8>,
|
||||||
|
}
|
||||||
|
|
||||||
|
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<u8> = 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)
|
||||||
|
}
|
||||||
|
}
|
61
ableos/src/proto_filetable/mod.rs
Normal file
61
ableos/src/proto_filetable/mod.rs
Normal file
|
@ -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<String, File>,
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
16
ableos/src/proto_filetable/tests.rs
Normal file
16
ableos/src/proto_filetable/tests.rs
Normal file
|
@ -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()
|
||||||
|
);
|
||||||
|
}
|
|
@ -1,2 +1,3 @@
|
||||||
|
//! A standard implementation of common math functions
|
||||||
|
|
||||||
pub mod ciphers;
|
pub mod ciphers;
|
||||||
pub mod rand;
|
|
||||||
|
|
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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<RandomHandeler> = spin::Mutex::new(RandomHandeler {
|
|
||||||
prand: PRand::new(),
|
|
||||||
linearshift: LinearShiftRegister::new(),
|
|
||||||
entropy: Entropy::new(),
|
|
||||||
});
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
//! A simple reimplimentation of the the rust standard library
|
||||||
|
|
||||||
pub mod clparse;
|
pub mod clparse;
|
||||||
pub mod encoding;
|
pub mod encoding;
|
||||||
pub mod image;
|
pub mod image;
|
||||||
|
|
|
@ -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);
|
||||||
|
//! ```
|
||||||
|
|
|
@ -1,51 +1,60 @@
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
|
|
||||||
/// Placeholder to be replaced with a proper FileReference when such a thing exists
|
use crate::file::PathRep;
|
||||||
pub type FileID = u8;
|
|
||||||
pub type SoundCardID = u8;
|
pub type SoundCardID = u8;
|
||||||
pub type DeviceID = u8;
|
pub type DeviceID = u8;
|
||||||
pub type ControllerID = u8;
|
pub type ControllerID = u8;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub enum FileAccess {
|
pub enum FileAccess {
|
||||||
All,
|
All,
|
||||||
Some(Vec<FileID>),
|
Some(Vec<PathRep>),
|
||||||
None,
|
None,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub enum ControllerAccess {
|
pub enum ControllerAccess {
|
||||||
All,
|
All,
|
||||||
Some(Vec<ControllerID>),
|
Some(Vec<ControllerID>),
|
||||||
None,
|
None,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub enum SoundCardAccess {
|
pub enum SoundCardAccess {
|
||||||
All,
|
All,
|
||||||
Some(Vec<SoundCardID>),
|
Some(Vec<SoundCardID>),
|
||||||
None,
|
None,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub enum MouseAccess {
|
pub enum MouseAccess {
|
||||||
Yes,
|
Yes,
|
||||||
No,
|
No,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub enum KeyboardAccess {
|
pub enum KeyboardAccess {
|
||||||
Yes,
|
Yes,
|
||||||
No,
|
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 {
|
pub struct Capabilities {
|
||||||
files: FileAccess,
|
pub files: FileAccess,
|
||||||
mouse: MouseAccess,
|
pub mouse: MouseAccess,
|
||||||
keyboard: KeyboardAccess,
|
pub keyboard: KeyboardAccess,
|
||||||
controllers: ControllerAccess,
|
pub controllers: ControllerAccess,
|
||||||
sound_cards: SoundCardAccess,
|
pub sound_cards: SoundCardAccess,
|
||||||
|
|
||||||
|
pub network_access: NetworkAccess,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Capabilities {
|
impl Capabilities {
|
||||||
|
@ -57,8 +66,7 @@ impl Capabilities {
|
||||||
keyboard: KeyboardAccess::No,
|
keyboard: KeyboardAccess::No,
|
||||||
controllers: ControllerAccess::None,
|
controllers: ControllerAccess::None,
|
||||||
sound_cards: SoundCardAccess::None,
|
sound_cards: SoundCardAccess::None,
|
||||||
|
network_access: NetworkAccess::No,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,10 @@ use alloc::{vec, vec::Vec};
|
||||||
|
|
||||||
pub mod capabilities;
|
pub mod capabilities;
|
||||||
pub mod proc;
|
pub mod proc;
|
||||||
use proc::{Process, ProcessPermissions, PID};
|
use proc::{Process, PID};
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests;
|
||||||
|
|
||||||
use self::capabilities::Capabilities;
|
use self::capabilities::Capabilities;
|
||||||
|
|
||||||
|
@ -14,8 +17,6 @@ lazy_static::lazy_static!(
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// pub struct VirtualMemoryTable {}
|
|
||||||
|
|
||||||
/// Scheduler priority model
|
/// Scheduler priority model
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub enum Priority {
|
pub enum Priority {
|
||||||
|
@ -38,24 +39,56 @@ pub enum FileAccessTypes {
|
||||||
None,
|
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)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Scheduler {
|
pub struct Scheduler {
|
||||||
|
/// The highest free process ID
|
||||||
pub free_pid: PID,
|
pub free_pid: PID,
|
||||||
|
/// The execution time of the current process in ticks
|
||||||
pub process_exec_time: u64,
|
pub process_exec_time: u64,
|
||||||
|
/// The list of processes
|
||||||
pub list: Vec<Process>,
|
pub list: Vec<Process>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Scheduler {
|
impl Scheduler {
|
||||||
|
/// Create a new scheduler
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
/// ```
|
||||||
|
/// use ableos::scheduler::Priority;
|
||||||
|
/// let mut scheduler = Scheduler::new();
|
||||||
|
/// ```
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
list: vec![],
|
|
||||||
process_exec_time: 0,
|
|
||||||
free_pid: PID(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) {
|
pub fn next_process(&mut self) {
|
||||||
self.process_exec_time = 0;
|
self.process_exec_time = 0;
|
||||||
let previous_task = self.list[0].clone();
|
let previous_task = self.list[0].clone();
|
||||||
|
@ -63,19 +96,47 @@ impl Scheduler {
|
||||||
self.list.push(previous_task);
|
self.list.push(previous_task);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a
|
/// Creates a new process
|
||||||
pub fn new_process(&mut self, priority: Priority) {
|
///
|
||||||
// let new_pid = self.free_pid;
|
/// # 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 {
|
let process = Process {
|
||||||
id: self.free_pid.clone(),
|
id: self.free_pid.clone(),
|
||||||
capabilities: Capabilities::empty(),
|
capabilities: Capabilities::empty(),
|
||||||
priority,
|
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.list.push(process);
|
||||||
|
|
||||||
|
self.free_pid.0 += 1;
|
||||||
}
|
}
|
||||||
/// Terminate the process with the matching PID
|
/// 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) {
|
pub fn term_process(&mut self, pid: PID) {
|
||||||
let mut process_index = 0;
|
let mut process_index = 0;
|
||||||
for x in &self.list {
|
for x in &self.list {
|
||||||
|
@ -86,11 +147,19 @@ impl Scheduler {
|
||||||
process_index += 1
|
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) {
|
pub fn bump_exec(&mut self) {
|
||||||
self.process_exec_time += 1;
|
self.process_exec_time += 1;
|
||||||
use Priority::*;
|
|
||||||
|
|
||||||
|
use Priority::*;
|
||||||
if self.list.len() > 0 {
|
if self.list.len() > 0 {
|
||||||
match (self.process_exec_time, self.list[0].priority) {
|
match (self.process_exec_time, self.list[0].priority) {
|
||||||
(20, High) => {
|
(20, High) => {
|
||||||
|
|
|
@ -7,12 +7,6 @@ use super::{capabilities::Capabilities, FileAccessTypes, Priority};
|
||||||
|
|
||||||
pub struct PID(pub usize);
|
pub struct PID(pub usize);
|
||||||
|
|
||||||
/// Temporary till integration of capabilities
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub struct ProcessPermissions {
|
|
||||||
pub file_access: FileAccessTypes,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A process
|
/// A process
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Process {
|
pub struct Process {
|
||||||
|
|
49
ableos/src/scheduler/tests.rs
Normal file
49
ableos/src/scheduler/tests.rs
Normal file
|
@ -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);
|
||||||
|
}
|
|
@ -6,3 +6,13 @@
|
||||||
pub fn type_of<T>(_: &T) -> &str {
|
pub fn type_of<T>(_: &T) -> &str {
|
||||||
core::any::type_name::<T>()
|
core::any::type_name::<T>()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
// #[test]
|
||||||
|
fn test_type_of() {
|
||||||
|
assert_eq!(type_of(&1), "i32");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
use shadeable::pixel_format::Rgba64;
|
||||||
|
|
||||||
|
use crate::SCREEN_BUFFER;
|
||||||
|
|
||||||
use {
|
use {
|
||||||
ab_glyph::{Font, FontRef, Glyph},
|
ab_glyph::{Font, FontRef, Glyph},
|
||||||
vga::{
|
vga::{
|
||||||
|
@ -15,16 +19,17 @@ lazy_static::lazy_static! {
|
||||||
pub static ref VGAE_BUFF_OFFSET_X: spin::Mutex<u8> = spin::Mutex::new(0);
|
pub static ref VGAE_BUFF_OFFSET_X: spin::Mutex<u8> = spin::Mutex::new(0);
|
||||||
pub static ref VGAE_BUFF_OFFSET_Y: spin::Mutex<u8> = spin::Mutex::new(0);
|
pub static ref VGAE_BUFF_OFFSET_Y: spin::Mutex<u8> = spin::Mutex::new(0);
|
||||||
}
|
}
|
||||||
///
|
|
||||||
pub fn draw_char(previous_character: Option<char>, 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 {
|
/// Draw a glyph on the screen at the given position
|
||||||
*offset_x = 0;
|
///
|
||||||
*offset_y += 1;
|
/// # 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!(
|
let font = FontRef::try_from_slice(include_bytes!(
|
||||||
"../../ableos/assets/fonts/unifont-14.0.01.ttf"
|
"../../ableos/assets/fonts/unifont-14.0.01.ttf"
|
||||||
|
@ -55,29 +60,10 @@ pub fn draw_char(previous_character: Option<char>, character: char, _offset: usi
|
||||||
match character {
|
match character {
|
||||||
'\n' => {}
|
'\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(
|
let mut q_glyph: Glyph = used_font.glyph_id(character).with_scale_and_position(
|
||||||
20.0 * font_scale,
|
20.0 * font_scale,
|
||||||
ab_glyph::point(
|
ab_glyph::point(10.0 * font_scale, 18.0 * font_scale),
|
||||||
*offset_x as f32 * (10.0 * font_scale),
|
|
||||||
*offset_y as f32 + (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) {
|
if let Some(q) = used_font.outline_glyph(q_glyph) {
|
||||||
q.draw(|x, y, c| {
|
q.draw(|x, y, c| {
|
||||||
|
@ -86,13 +72,11 @@ pub fn draw_char(previous_character: Option<char>, character: char, _offset: usi
|
||||||
mode.set_pixel(
|
mode.set_pixel(
|
||||||
x as usize + corner.x as usize,
|
x as usize + corner.x as usize,
|
||||||
y as usize + corner.y as usize,
|
y as usize + corner.y as usize,
|
||||||
Color16::Green,
|
color,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
*offset_x += 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
61
ableos/src/virtio/mod.rs
Normal file
61
ableos/src/virtio/mod.rs
Normal file
|
@ -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,
|
||||||
|
}
|
|
@ -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
|
/// `1 0 0 0` as an array of 4 bytes
|
||||||
pub const WASM_VERSION: [u8; 4] = [0x01, 0x00, 0x00, 0x00];
|
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 {
|
pub enum SectionType {
|
||||||
None = 0,
|
None = 0,
|
||||||
Type = 1,
|
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 {
|
pub struct Section {
|
||||||
|
/// The section type
|
||||||
stype: SectionType,
|
stype: SectionType,
|
||||||
section_size: u8,
|
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 {
|
pub struct WasmProgram {
|
||||||
raw_bytes: Vec<u8>,
|
raw_bytes: Vec<u8>,
|
||||||
// version:
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WasmProgram {
|
impl WasmProgram {
|
||||||
|
@ -28,7 +85,16 @@ impl WasmProgram {
|
||||||
raw_bytes: bytes.to_vec(),
|
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) {
|
pub fn validate_header(self) -> (bool, bool) {
|
||||||
let mut byte_magic_valid = false;
|
let mut byte_magic_valid = false;
|
||||||
let mut byte_version_valid = false;
|
let mut byte_version_valid = false;
|
||||||
|
@ -42,9 +108,4 @@ impl WasmProgram {
|
||||||
}
|
}
|
||||||
return (byte_magic_valid, byte_version_valid);
|
return (byte_magic_valid, byte_version_valid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
18
facepalm/Cargo.lock
generated
18
facepalm/Cargo.lock
generated
|
@ -2,6 +2,24 @@
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 3
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg-if"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "facepalm"
|
name = "facepalm"
|
||||||
version = "0.1.0"
|
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",
|
||||||
|
]
|
||||||
|
|
|
@ -6,3 +6,4 @@ edition = "2021"
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
log = "0.4.0"
|
19
facepalm/src/lib.rs
Normal file
19
facepalm/src/lib.rs
Normal file
|
@ -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);
|
||||||
|
}
|
|
@ -1,3 +0,0 @@
|
||||||
fn main() {
|
|
||||||
println!("Hello, world!");
|
|
||||||
}
|
|
|
@ -55,8 +55,7 @@ fn main() -> anyhow::Result<()> {
|
||||||
).run()?;
|
).run()?;
|
||||||
}
|
}
|
||||||
MachineType::RISCV => {
|
MachineType::RISCV => {
|
||||||
xshell::cmd!("cargo build --release --target=riscv64gc-unknown-none-elf")
|
xshell::cmd!("cargo build --release --target=riscv64gc-unknown-none-elf").run()?;
|
||||||
.run()?;
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
xshell::cmd!(
|
xshell::cmd!(
|
||||||
"qemu-system-riscv64
|
"qemu-system-riscv64
|
||||||
|
@ -79,8 +78,7 @@ fn main() -> anyhow::Result<()> {
|
||||||
xshell::cmd!("cargo doc --open").run()?;
|
xshell::cmd!("cargo doc --open").run()?;
|
||||||
}
|
}
|
||||||
MachineType::ARM => {
|
MachineType::ARM => {
|
||||||
xshell::cmd!("cargo doc --open --target=json_targets/aarch64-ableos.json")
|
xshell::cmd!("cargo doc --open --target=json_targets/aarch64-ableos.json").run()?;
|
||||||
.run()?;
|
|
||||||
}
|
}
|
||||||
MachineType::RISCV => {
|
MachineType::RISCV => {
|
||||||
xshell::cmd!("cargo doc --open --target=riscv64gc-unknown-none-elf").run()?;
|
xshell::cmd!("cargo doc --open --target=riscv64gc-unknown-none-elf").run()?;
|
||||||
|
|
|
@ -1,130 +1,138 @@
|
||||||
#![feature(exclusive_range_pattern)]
|
#![feature(exclusive_range_pattern)]
|
||||||
use log::*;
|
|
||||||
use rhai::INT;
|
|
||||||
use vga::colors::Color16;
|
use vga::colors::Color16;
|
||||||
pub type Rgba64 = u64;
|
pub type Rgba64 = u64;
|
||||||
|
|
||||||
pub fn get_r(rgba: Rgba64) -> u8 {
|
pub fn get_r(rgba: Rgba64) -> u8 {
|
||||||
let x: u64 = rgba;
|
(rgba & 0xff_00_00_00 >> 0o30) as u8
|
||||||
|
|
||||||
let y = x >> 24;
|
|
||||||
|
|
||||||
return (y & 0xff).try_into().unwrap();
|
|
||||||
}
|
}
|
||||||
pub fn get_g(rgba: Rgba64) -> u8 {
|
pub fn get_g(rgba: Rgba64) -> u8 {
|
||||||
let x: u64 = rgba;
|
(rgba & 0xff_00_00 >> 0o20) as u8
|
||||||
|
|
||||||
let y = x >> 16;
|
|
||||||
|
|
||||||
return (y & 0xff).try_into().unwrap();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_b(rgba: Rgba64) -> u8 {
|
pub fn get_b(rgba: Rgba64) -> u8 {
|
||||||
let x: u64 = rgba;
|
(rgba & 0xff_00 >> 0o10) as u8
|
||||||
|
|
||||||
let y = x >> (24 - 16);
|
|
||||||
|
|
||||||
return (y & 0xff).try_into().unwrap();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_a(rgba: Rgba64) -> u8 {
|
pub fn get_a(rgba: Rgba64) -> u8 {
|
||||||
let x = rgba;
|
(rgba & 0xff) as u8
|
||||||
|
|
||||||
let y = x >> (24 - 16 - 8);
|
|
||||||
|
|
||||||
return (y & 0xff).try_into().unwrap();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_r(rgba: Rgba64, r: u8) -> Rgba64 {
|
pub fn set_r(rgba: Rgba64, r: u8) -> Rgba64 {
|
||||||
let z = (r as Rgba64) << 24;
|
rgba & 0xffffffff_00_ff_ff_ff | (r as Rgba64) << 0o30
|
||||||
let y = rgba & 0xffffff;
|
|
||||||
return z | y;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_g(rgba: Rgba64, g: u8) -> Rgba64 {
|
pub fn set_g(rgba: Rgba64, g: u8) -> Rgba64 {
|
||||||
let z = (g as Rgba64) << 16;
|
rgba & 0xffffffff_ff_00_ff_ff | (g as Rgba64) << 0o20
|
||||||
let y = rgba & 0xffffff;
|
|
||||||
return z | y;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_b(rgba: Rgba64, b: u8) -> Rgba64 {
|
pub fn set_b(rgba: Rgba64, b: u8) -> Rgba64 {
|
||||||
let z = (b as Rgba64) << 26 - 16;
|
rgba & 0xffffffff_ff_ff_00_ff | (b as Rgba64) << 0o10
|
||||||
let y = rgba & 0xffffff;
|
|
||||||
return z | y;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_a(rgba: Rgba64, a: u8) -> Rgba64 {
|
pub fn set_a(rgba: Rgba64, a: u8) -> Rgba64 {
|
||||||
let z = (a as Rgba64) << 8;
|
rgba & 0xffffffff_ff_ff_ff_00 | (a as Rgba64)
|
||||||
let y = rgba & 0xffffff;
|
|
||||||
return z | y;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rgba_div(a: Rgba64, b: Rgba64) -> Rgba64 {
|
pub fn rgba_div(a: Rgba64, b: Rgba64) -> Rgba64 {
|
||||||
let mut fin: Rgba64 = 0;
|
set_r(0, get_r(a) / get_r(b))
|
||||||
|
| set_g(0, get_g(a) / get_g(b))
|
||||||
// println!("{}", fin);
|
| set_g(0, get_b(a) / get_b(b))
|
||||||
fin |= set_r(fin, get_r(a) / get_r(b));
|
| set_g(0, get_a(a) / get_a(b))
|
||||||
// println!("{}", fin);
|
|
||||||
|
|
||||||
fin |= set_g(fin, get_g(a) / get_g(b));
|
|
||||||
/*
|
|
||||||
|
|
||||||
get_b(a) / get_b(b);
|
|
||||||
|
|
||||||
get_a(a) / get_a(b);
|
|
||||||
*/
|
|
||||||
|
|
||||||
return fin;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_rgba64(r: u8, g: u8, b: u8, a: u8) -> Rgba64 {
|
pub fn new_rgba64(r: u8, g: u8, b: u8, a: u8) -> Rgba64 {
|
||||||
let mut x = 0;
|
set_r(0, r) | set_g(0, g) | set_b(0, b) | set_a(0, a)
|
||||||
|
}
|
||||||
|
|
||||||
x |= set_r(x, r);
|
enum ChannelValue {
|
||||||
x |= set_g(x, g);
|
Dark,
|
||||||
x |= set_b(x, b);
|
Low,
|
||||||
x |= set_a(x, a);
|
Mid,
|
||||||
|
High,
|
||||||
|
}
|
||||||
|
|
||||||
x
|
impl From<u8> for ChannelValue {
|
||||||
|
fn from(b: u8) -> Self {
|
||||||
|
use ChannelValue::*;
|
||||||
|
match b {
|
||||||
|
0x00..=0x3f => Dark,
|
||||||
|
0x40..=0x7f => Low,
|
||||||
|
0x80..=0xbf => Mid,
|
||||||
|
0xc0..=0xff => High,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn into_vga_16(rgba_64: Rgba64) -> Color16 {
|
pub fn into_vga_16(rgba_64: Rgba64) -> Color16 {
|
||||||
let mut fourbit: u8 = 0;
|
use ChannelValue::*;
|
||||||
fourbit |= match get_r(rgba_64) {
|
|
||||||
85..=170 => 0b0100,
|
|
||||||
171..=255 => 0b1100,
|
|
||||||
_ => 0,
|
|
||||||
};
|
|
||||||
fourbit |= match get_g(rgba_64) {
|
|
||||||
85..=170 => 0b0010,
|
|
||||||
171..=255 => 0b1010,
|
|
||||||
_ => 0,
|
|
||||||
};
|
|
||||||
fourbit |= match get_b(rgba_64) {
|
|
||||||
85..=170 => 0b0001,
|
|
||||||
171..=255 => 0b1001,
|
|
||||||
_ => 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
// trace!("{}", fourbit);
|
|
||||||
|
|
||||||
use Color16::*;
|
use Color16::*;
|
||||||
match fourbit {
|
match (
|
||||||
0 => Black,
|
get_r(rgba_64).into(),
|
||||||
1 => Blue,
|
get_g(rgba_64).into(),
|
||||||
2 => Green,
|
get_b(rgba_64).into(),
|
||||||
3 => Cyan,
|
) {
|
||||||
4 => Red,
|
(Dark, Dark, Dark) => Black,
|
||||||
5 => Magenta,
|
(Dark, Dark, Low) => Black,
|
||||||
6 => Brown,
|
(Dark, Dark, Mid) => Blue,
|
||||||
7 => LightGrey,
|
(Dark, Dark, High) => Blue,
|
||||||
8 => DarkGrey,
|
(Dark, Low, Dark) => Black,
|
||||||
9 => LightBlue,
|
(Dark, Low, Low) => Black,
|
||||||
10 => LightGreen,
|
(Dark, Low, Mid) => Blue,
|
||||||
11 => LightCyan,
|
(Dark, Low, High) => Blue,
|
||||||
12 => LightRed,
|
(Dark, Mid, Dark) => Green,
|
||||||
13 => Pink,
|
(Dark, Mid, Low) => Green,
|
||||||
14 => Yellow,
|
(Dark, Mid, Mid) => Cyan,
|
||||||
15 => White,
|
(Dark, Mid, High) => Cyan,
|
||||||
_ => Green,
|
(Dark, High, Dark) => Green,
|
||||||
|
(Dark, High, Low) => Green,
|
||||||
|
(Dark, High, Mid) => Green,
|
||||||
|
(Dark, High, High) => Cyan,
|
||||||
|
(Low, Dark, Dark) => Black,
|
||||||
|
(Low, Dark, Low) => Black,
|
||||||
|
(Low, Dark, Mid) => Blue,
|
||||||
|
(Low, Dark, High) => Blue,
|
||||||
|
(Low, Low, Dark) => Black,
|
||||||
|
(Low, Low, Low) => DarkGrey,
|
||||||
|
(Low, Low, Mid) => LightGrey,
|
||||||
|
(Low, Low, High) => Blue,
|
||||||
|
(Low, Mid, Dark) => DarkGrey,
|
||||||
|
(Low, Mid, Low) => LightGrey,
|
||||||
|
(Low, Mid, Mid) => Cyan,
|
||||||
|
(Low, Mid, High) => Cyan,
|
||||||
|
(Low, High, Dark) => Green,
|
||||||
|
(Low, High, Low) => Green,
|
||||||
|
(Low, High, Mid) => Cyan,
|
||||||
|
(Low, High, High) => Cyan,
|
||||||
|
(Mid, Dark, Dark) => Red,
|
||||||
|
(Mid, Dark, Low) => Red,
|
||||||
|
(Mid, Dark, Mid) => Magenta,
|
||||||
|
(Mid, Dark, High) => Magenta,
|
||||||
|
(Mid, Low, Dark) => Brown,
|
||||||
|
(Mid, Low, Low) => Red,
|
||||||
|
(Mid, Low, Mid) => DarkGrey,
|
||||||
|
(Mid, Low, High) => LightBlue,
|
||||||
|
(Mid, Mid, Dark) => Brown,
|
||||||
|
(Mid, Mid, Low) => Brown,
|
||||||
|
(Mid, Mid, Mid) => LightGrey,
|
||||||
|
(Mid, Mid, High) => LightBlue,
|
||||||
|
(Mid, High, Dark) => Green,
|
||||||
|
(Mid, High, Low) => Green,
|
||||||
|
(Mid, High, Mid) => LightGreen,
|
||||||
|
(Mid, High, High) => LightCyan,
|
||||||
|
(High, Dark, Dark) => Red,
|
||||||
|
(High, Dark, _) => Magenta,
|
||||||
|
(High, Low, Dark) => Red,
|
||||||
|
(High, Low, Low) => LightRed,
|
||||||
|
(High, Low, Mid) => Pink,
|
||||||
|
(High, Low, High) => Magenta,
|
||||||
|
(High, Mid, Dark) => Yellow,
|
||||||
|
(High, Mid, Low) => Yellow,
|
||||||
|
(High, Mid, Mid) => LightRed,
|
||||||
|
(High, Mid, High) => Pink,
|
||||||
|
(High, High, Dark) => Yellow,
|
||||||
|
(High, High, Low) => White,
|
||||||
|
(High, High, Mid) => White,
|
||||||
|
(High, High, High) => White,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,84 +143,21 @@ pub fn from_vga_16(color: Color16) -> Rgba64 {
|
||||||
DarkGrey => new_rgba64(105, 105, 105, 0),
|
DarkGrey => new_rgba64(105, 105, 105, 0),
|
||||||
LightGrey => new_rgba64(211, 211, 211, 0),
|
LightGrey => new_rgba64(211, 211, 211, 0),
|
||||||
//
|
//
|
||||||
Blue => new_rgba64(0, 0, 255, 0),
|
Blue => new_rgba64(0, 0, 0xff, 0),
|
||||||
Green => new_rgba64(0, 255, 0, 0),
|
Green => new_rgba64(0, 0xff, 0, 0),
|
||||||
Red => new_rgba64(255, 0, 0, 0),
|
Red => new_rgba64(0xff, 0, 0, 0),
|
||||||
//
|
//
|
||||||
Yellow => new_rgba64(255, 255, 0, 0),
|
Yellow => new_rgba64(0xff, 0xff, 0, 0),
|
||||||
Cyan => new_rgba64(0, 255, 255, 0),
|
Cyan => new_rgba64(0, 0xff, 0xff, 0),
|
||||||
Magenta => new_rgba64(255, 0, 255, 0),
|
Magenta => new_rgba64(0xff, 0, 0xff, 0),
|
||||||
|
|
||||||
Brown => new_rgba64(165, 42, 42, 0),
|
Brown => new_rgba64(165, 42, 42, 0),
|
||||||
Pink => new_rgba64(255, 105, 180, 0),
|
Pink => new_rgba64(0xff, 105, 180, 0),
|
||||||
White => new_rgba64(255, 255, 255, 0),
|
White => new_rgba64(0xff, 0xff, 0xff, 0),
|
||||||
|
|
||||||
LightBlue => new_rgba64(173, 216, 230, 0),
|
LightBlue => new_rgba64(173, 216, 230, 0),
|
||||||
LightGreen => new_rgba64(144, 238, 144, 0),
|
LightGreen => new_rgba64(144, 238, 144, 0),
|
||||||
LightCyan => new_rgba64(88, 100, 100, 0),
|
LightCyan => new_rgba64(88, 100, 100, 0),
|
||||||
LightRed => new_rgba64(255, 204, 203, 0),
|
LightRed => new_rgba64(0xff, 204, 203, 0),
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
use libm::sqrt;
|
|
||||||
|
|
||||||
fn euclideand(c1: (u8, u8, u8), c2: (u8, u8, u8)) -> u8 {
|
|
||||||
let (r1, g1, b1) = c1;
|
|
||||||
let (r2, g2, b2) = c2;
|
|
||||||
let (rd, gd, bd) = (r2 - r1, g2 - g1, b2 - b1);
|
|
||||||
sqrt((rd * rd + gd * gd + bd * bd) as f64) as u8
|
|
||||||
}
|
|
||||||
pub fn get_color16(c: Rgba64) -> Color16 {
|
|
||||||
let r = get_r(c);
|
|
||||||
let g = get_g(c);
|
|
||||||
let b = get_b(c);
|
|
||||||
|
|
||||||
let c = (r, g, b);
|
|
||||||
let palette: [(u8, u8, u8); 16] = [
|
|
||||||
(0, 0, 0),
|
|
||||||
(105, 105, 105),
|
|
||||||
(211, 211, 211),
|
|
||||||
(0, 0, 255),
|
|
||||||
(0, 255, 0),
|
|
||||||
(255, 0, 0),
|
|
||||||
(255, 255, 0),
|
|
||||||
(0, 255, 255),
|
|
||||||
(255, 0, 255),
|
|
||||||
(165, 42, 42),
|
|
||||||
(255, 105, 180),
|
|
||||||
(255, 255, 255),
|
|
||||||
(173, 216, 230),
|
|
||||||
(144, 238, 144),
|
|
||||||
(88, 100, 100),
|
|
||||||
(255, 204, 203),
|
|
||||||
];
|
|
||||||
let mut minc = euclideand(c, palette[0]);
|
|
||||||
let mut retval = 0;
|
|
||||||
for i in 1..16 {
|
|
||||||
let eucd = euclideand(c, palette[i]);
|
|
||||||
if eucd < minc {
|
|
||||||
retval = i;
|
|
||||||
minc = eucd
|
|
||||||
}
|
|
||||||
}
|
|
||||||
use Color16::*;
|
|
||||||
match retval {
|
|
||||||
0 => Black,
|
|
||||||
1 => Blue,
|
|
||||||
2 => Green,
|
|
||||||
3 => Cyan,
|
|
||||||
4 => Red,
|
|
||||||
5 => Magenta,
|
|
||||||
6 => Brown,
|
|
||||||
7 => LightGrey,
|
|
||||||
8 => DarkGrey,
|
|
||||||
9 => LightBlue,
|
|
||||||
10 => LightGreen,
|
|
||||||
11 => LightCyan,
|
|
||||||
12 => LightRed,
|
|
||||||
13 => Pink,
|
|
||||||
14 => Yellow,
|
|
||||||
15 => White,
|
|
||||||
_ => Green,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue