patchwork and breaking changes
This commit is contained in:
parent
7492cef2fc
commit
a001a7e168
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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