forked from AbleOS/ableos
patchwork and breaking changes
This commit is contained in:
parent
7492cef2fc
commit
a001a7e168
|
@ -13,6 +13,8 @@ use rhai::Engine;
|
|||
use spin::Lazy;
|
||||
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 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 mut scope = rhai::Scope::new();
|
||||
|
||||
println!("Rhaishell v{}", RHAISHELL_VERSION);
|
||||
|
||||
let mut buf = String::new();
|
||||
print!("> ");
|
||||
|
||||
loop {
|
||||
match x86_64::instructions::interrupts::without_interrupts(|| KEYBUFF.lock().pop()) {
|
||||
Some('\n') => {
|
||||
if buf == "quit" {
|
||||
println!("Bye!");
|
||||
break;
|
||||
}
|
||||
|
||||
match engine.eval_with_scope::<rhai::Dynamic>(&mut scope, &buf) {
|
||||
Ok(o) => println!("{o}"),
|
||||
|
||||
|
@ -201,16 +210,12 @@ fn engine_construction() -> Engine {
|
|||
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("set_hostname", set_hostname);
|
||||
engine.register_fn("shutdown", shutdown);
|
||||
engine.register_fn("peek", peek_memory);
|
||||
engine.register_fn("poke", poke_memory);
|
||||
engine.register_fn("sloop", sloop);
|
||||
engine.register_fn("wasm", interp);
|
||||
engine.register_fn("log_dump", log_dump);
|
||||
|
||||
engine
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
use core::alloc::Layout;
|
||||
|
||||
use crate::encoding::bin;
|
||||
use crate::rhai_shell::shell;
|
||||
use crate::wasm_jumploader::run_program;
|
||||
use acpi::{AcpiTables, PlatformInfo};
|
||||
use genfs::Fs;
|
||||
|
||||
/// Experimental scratchpad for testing.
|
||||
pub fn scratchpad() {
|
||||
|
@ -17,7 +20,7 @@ pub fn scratchpad() {
|
|||
info!("{:?}", node);
|
||||
}
|
||||
// acpi();
|
||||
shell();
|
||||
real_shell();
|
||||
}
|
||||
|
||||
pub fn pci_fun() {}
|
||||
|
@ -61,3 +64,115 @@ impl acpi::AcpiHandler for AcpiStruct {
|
|||
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;
|
||||
|
|
|
@ -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.
Loading…
Reference in a new issue