1
0
Fork 0
forked from AbleOS/ableos

patchwork and breaking changes

This commit is contained in:
Able 2022-04-25 04:56:01 -05:00
parent 7492cef2fc
commit a001a7e168
4 changed files with 206 additions and 6 deletions

View file

@ -13,6 +13,8 @@ use rhai::Engine;
use spin::Lazy; use spin::Lazy;
use x86_64::instructions::interrupts::{disable, enable}; use x86_64::instructions::interrupts::{disable, enable};
pub const RHAISHELL_VERSION: &str = "0.1.0";
pub static KEYBUFF: spin::Mutex<Vec<char>> = spin::Mutex::new(Vec::new()); pub static KEYBUFF: spin::Mutex<Vec<char>> = spin::Mutex::new(Vec::new());
pub static CURRENT_DIR: Lazy<spin::Mutex<String>> = Lazy::new(|| spin::Mutex::new("/".to_string())); pub static CURRENT_DIR: Lazy<spin::Mutex<String>> = Lazy::new(|| spin::Mutex::new("/".to_string()));
@ -25,12 +27,19 @@ pub fn shell() {
let engine = engine_construction(); let engine = engine_construction();
let mut scope = rhai::Scope::new(); let mut scope = rhai::Scope::new();
println!("Rhaishell v{}", RHAISHELL_VERSION);
let mut buf = String::new(); let mut buf = String::new();
print!("> "); print!("> ");
loop { loop {
match x86_64::instructions::interrupts::without_interrupts(|| KEYBUFF.lock().pop()) { match x86_64::instructions::interrupts::without_interrupts(|| KEYBUFF.lock().pop()) {
Some('\n') => { Some('\n') => {
if buf == "quit" {
println!("Bye!");
break;
}
match engine.eval_with_scope::<rhai::Dynamic>(&mut scope, &buf) { match engine.eval_with_scope::<rhai::Dynamic>(&mut scope, &buf) {
Ok(o) => println!("{o}"), Ok(o) => println!("{o}"),
@ -201,16 +210,12 @@ fn engine_construction() -> Engine {
debug!("{} at {:?}: {}", src, pos, x); debug!("{} at {:?}: {}", src, pos, x);
}); });
engine.register_fn("ls", ls);
engine.register_fn("cat", echo_file);
engine.register_fn("cd", change_directory);
engine.register_fn("afetch", afetch); engine.register_fn("afetch", afetch);
engine.register_fn("set_hostname", set_hostname); engine.register_fn("set_hostname", set_hostname);
engine.register_fn("shutdown", shutdown); engine.register_fn("shutdown", shutdown);
engine.register_fn("peek", peek_memory); engine.register_fn("peek", peek_memory);
engine.register_fn("poke", poke_memory); engine.register_fn("poke", poke_memory);
engine.register_fn("sloop", sloop); engine.register_fn("sloop", sloop);
engine.register_fn("wasm", interp);
engine.register_fn("log_dump", log_dump); engine.register_fn("log_dump", log_dump);
engine engine

View file

@ -1,7 +1,10 @@
use core::alloc::Layout; use core::alloc::Layout;
use crate::encoding::bin;
use crate::rhai_shell::shell; use crate::rhai_shell::shell;
use crate::wasm_jumploader::run_program;
use acpi::{AcpiTables, PlatformInfo}; use acpi::{AcpiTables, PlatformInfo};
use genfs::Fs;
/// Experimental scratchpad for testing. /// Experimental scratchpad for testing.
pub fn scratchpad() { pub fn scratchpad() {
@ -17,7 +20,7 @@ pub fn scratchpad() {
info!("{:?}", node); info!("{:?}", node);
} }
// acpi(); // acpi();
shell(); real_shell();
} }
pub fn pci_fun() {} pub fn pci_fun() {}
@ -61,3 +64,115 @@ impl acpi::AcpiHandler for AcpiStruct {
todo!("unmap_physical_region"); todo!("unmap_physical_region");
} }
} }
pub fn real_shell() {
let _current_dir = "/".to_string();
let current_user = "able".to_string();
let mut buf = String::new();
print!("> ");
loop {
match x86_64::instructions::interrupts::without_interrupts(|| KEYBUFF.lock().pop()) {
Some('\n') => {
// match engine.eval_with_scope::<rhai::Dynamic>(&mut scope, &buf) {
// Ok(o) => println!("{o}"),
// Err(e) => println!("Eval error: {e}"),
// };
if !buf.is_empty() {
command_parser(current_user.clone(), buf.clone());
}
buf.clear();
print!("> ");
}
Some('\u{0008}') => {
buf.pop();
}
Some('\u{0009}') => {
buf.push(' ');
buf.push(' ');
buf.push(' ');
buf.push(' ');
}
Some(chr) => buf.push(chr),
None => (),
}
}
}
use crate::rhai_shell::KEYBUFF;
pub fn command_parser(user: String, command: String) {
let fs = &*FILE_SYSTEM.lock();
let mut iter = command.split_whitespace();
let bin_name = iter.next().unwrap();
if bin_name == "rhai" {
drop(fs);
shell();
return;
}
let home_exec_path = format!("/home/{}/bins/{}.wasm", user, bin_name);
let shared_exec_path = format!("/shared/bins/{}.wasm", bin_name);
let system_exec_path = format!("/system/bins/{}.wasm", bin_name);
let home_exec_file = fs.open(&home_exec_path.as_bytes(), OpenOptions::new().read(true));
let shared_exec_file = fs.open(&shared_exec_path.as_bytes(), OpenOptions::new().read(true));
let system_exec_file = fs.open(&system_exec_path.as_bytes(), OpenOptions::new().read(true));
let mut in_home = false;
let mut in_shared = false;
let mut in_system = false;
let mut binary_prog: Vec<u8> = vec![];
match home_exec_file {
Ok(file) => {
let ret = file.read_to_end(&mut binary_prog).unwrap();
in_home = true;
}
Err(error) => {
trace!("{:?}", error);
in_home = false;
}
}
match shared_exec_file {
Ok(file) => {
let ret = file.read_to_end(&mut binary_prog).unwrap();
in_shared = true;
}
Err(error) => {
trace!("{:?}", error);
in_shared = false;
}
}
match system_exec_file {
Ok(file) => {
let ret = file.read_to_end(&mut binary_prog).unwrap();
in_system = true;
}
Err(error) => {
trace!("{:?}", error);
in_system = false;
}
}
let args = iter.collect::<Vec<&str>>();
println!("{:?}", args);
if in_home || in_shared || in_system {
run_program(binary_prog);
} else {
println!("No such binary: {}", bin_name);
error!("No such binary: {}", bin_name);
}
}
use crate::filesystem::FILE_SYSTEM;
use genfs::OpenOptions;

View file

@ -98,4 +98,84 @@ pub fn interp() {
} }
} }
pub fn run_program() {} pub fn run_program(program: Vec<u8>) {
// Load wasm binary and prepare it for instantiation.
let module = wasmi::Module::from_buffer(&program).expect("failed to load wasm");
trace!("Loaded wasm binary");
let imports = ImportsBuilder::new().with_resolver("env", &host_functions::HostExternals {});
trace!("Created imports");
// Instantiate a module with empty imports and
// assert that there is no `start` function.
let instance = ModuleInstance::new(&module, &imports); // .expect("failed to instantiate wasm module")
match instance {
Ok(inst) => {
let instance = inst.assert_no_start();
let mut is_driver = false;
let _is_program = false;
let mut has_driver_entry = false;
let mut has_driver_exit = false;
let mut has_start = false;
if let Some(_val) = instance.export_by_name("driver_entry") {
has_driver_entry = true;
}
if let Some(_val) = instance.export_by_name("driver_exit") {
has_driver_exit = true;
}
match instance.export_by_name("start") {
Some(_val) => {
trace!("Program start function found");
has_start = true;
}
None => debug!("No start function found"),
}
match instance.export_by_name("main") {
Some(_val) => {
trace!("Program main function found");
has_start = false;
}
None => debug!("No main function found"),
}
match (has_driver_entry, has_driver_exit) {
(true, true) => {
trace!("Valid driver entry and exit functions found");
is_driver = true;
}
(true, false) => error!("Driver entry function found but no driver exit function"),
(false, true) => error!("Driver exit function found but no driver entry function"),
(false, false) => {
trace!("No driver entry or exit functions found");
}
}
if has_start && has_driver_entry {
error!(
"A program should not have both a start function and a driver entry function. It Will be treated as a program."
);
}
if has_start {
let ret = instance
.invoke_export("start", &[], &mut HostExternals {})
.expect("failed to execute export");
println!("collected wasm return value: {:?}", ret);
} else if is_driver {
let ret = instance
.invoke_export("driver_entry", &[], &mut HostExternals {})
.expect("failed to execute export");
println!("collected wasm return value: {:?}", ret);
} else {
println!("ERROR: No start or driver entry function found, invalid program");
}
}
Err(err) => error!("{}", err),
}
}

Binary file not shown.