diff --git a/Cargo.lock b/Cargo.lock index c82d46222..2f07974bd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -213,12 +213,12 @@ dependencies = [ [[package]] name = "hbbytecode" version = "0.1.0" -source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#542c69fd6042a4b48462199c4391761bfe1b7c2e" +source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#37dd13cab295aa9e74d704b3345685b4428d149a" [[package]] name = "hblang" version = "0.1.0" -source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#542c69fd6042a4b48462199c4391761bfe1b7c2e" +source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#37dd13cab295aa9e74d704b3345685b4428d149a" dependencies = [ "hashbrown", "hbbytecode", @@ -229,7 +229,7 @@ dependencies = [ [[package]] name = "hbvm" version = "0.1.0" -source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#542c69fd6042a4b48462199c4391761bfe1b7c2e" +source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#37dd13cab295aa9e74d704b3345685b4428d149a" dependencies = [ "hbbytecode", ] diff --git a/kernel/src/holeybytes/ecah.rs b/kernel/src/holeybytes/ecah.rs index b4ef63411..67576f478 100644 --- a/kernel/src/holeybytes/ecah.rs +++ b/kernel/src/holeybytes/ecah.rs @@ -1,8 +1,17 @@ //! Environment call handling routines -use crate::holeybytes::kernel_services::{ - block_read, dt_msg_handler::dt_msg_handler, logging_service::log_msg_handler, - service_definition_service::sds_msg_handler, +use {alloc::boxed::Box, core::cell::LazyCell, hbvm::mem::Address}; + +use crate::{ + holeybytes::{ + kernel_services::{ + block_read, dt_msg_handler::dt_msg_handler, logging_service::log_msg_handler, + service_definition_service::sds_msg_handler, + }, + ExecThread, + }, + kmain::EXECUTOR, + task::Executor, }; use { @@ -143,6 +152,43 @@ pub fn handler(vm: &mut Vm) { Ok(()) => {} Err(_) => log::error!("Improper dt query"), }, + 6 => unsafe { + let program = block_read(mem_addr, length); + + // decode AbleOS Executable format + let header = &program[0..46]; + let magic_slice = &header[0..3]; + if magic_slice != [0x15, 0x91, 0xD2] { + log::error!("Invalid magic number at the start of executable."); + return; + } + + let executable_format_version = + u32::from_le_bytes(header[3..7].try_into().unwrap()); + let offset = if executable_format_version == 0 { + 47 + } else { + error!("Invalid executable format."); + return; + }; + + let code_length = u64::from_le_bytes(header[7..15].try_into().unwrap()); + let data_length = u64::from_le_bytes(header[15..23].try_into().unwrap()); + let end = (code_length + data_length) as usize; + log::debug!("{code_length} + {data_length} = {end}"); + + let thr = ExecThread::new(&program[offset..end], Address::new(0)); + vm.registers[1] = Value( + LazyCell::::get_mut(&mut EXECUTOR) + .unwrap() + .spawn(Box::pin(async move { + if let Err(e) = thr.await { + log::error!("{e:?}"); + } + })) as u64, + ); + log::debug!("spawned a process"); + }, buffer_id => { let mut buffs = IPC_BUFFERS.lock(); diff --git a/kernel/src/kmain.rs b/kernel/src/kmain.rs index 7ca0780db..ec87c6f81 100644 --- a/kernel/src/kmain.rs +++ b/kernel/src/kmain.rs @@ -8,7 +8,10 @@ use { device_tree::DeviceTree, holeybytes::ExecThread, ipc::buffer::IpcBuffer, + task::Executor, }, + alloc::boxed::Box, + core::cell::LazyCell, hashbrown::HashMap, hbvm::mem::Address, limine::{Framebuffer, FramebufferRequest, NonNullPtr}, @@ -65,8 +68,8 @@ pub fn kmain(_cmdline: &str, boot_modules: BootModules) -> ! { fb1.address.as_ptr().unwrap() as *const u8 ); - let mut executor = crate::task::Executor::new(256); unsafe { + let executor = LazyCell::::force_mut(&mut EXECUTOR); for module in boot_modules.iter() { let cmd = module.cmd.trim_matches('"'); let cmd_len = cmd.len() as u64; @@ -109,11 +112,11 @@ pub fn kmain(_cmdline: &str, boot_modules: BootModules) -> ! { if cmd_len > 0 { thr.set_arguments(cmd.as_ptr() as u64, cmd_len); } - executor.spawn(async move { + executor.spawn(Box::pin(async move { if let Err(e) = thr.await { log::error!("{e:?}"); } - }) + })); } debug!("Random number: {}", hardware_random_u64()); @@ -124,6 +127,10 @@ pub fn kmain(_cmdline: &str, boot_modules: BootModules) -> ! { crate::arch::spin_loop() } +// ! SAFETY: this is not threadsafe at all, like even a little bit. +// ! SERIOUSLY +pub static mut EXECUTOR: LazyCell = LazyCell::new(|| Executor::new()); + pub static DEVICE_TREE: Lazy> = Lazy::new(|| { let dt = DeviceTree::new(); Mutex::new(dt) diff --git a/kernel/src/lib.rs b/kernel/src/lib.rs index 3eff39d8e..f5bf86f85 100644 --- a/kernel/src/lib.rs +++ b/kernel/src/lib.rs @@ -7,6 +7,7 @@ exclusive_wrapper, core_intrinsics, abi_x86_interrupt, + lazy_get, alloc_error_handler, ptr_sub_ptr, custom_test_frameworks, diff --git a/kernel/src/task.rs b/kernel/src/task.rs index 241f64c58..3326871b3 100644 --- a/kernel/src/task.rs +++ b/kernel/src/task.rs @@ -29,24 +29,24 @@ pub fn yield_now() -> impl Future { YieldNow(false) } -pub struct Executor + Send> { - tasks: Slab>, +pub struct Executor { + tasks: Slab, task_queue: Arc, } -impl + Send> Executor { - pub fn new(size: usize) -> Self { +impl Executor { + pub fn new() -> Self { Self { - tasks: Slab::with_capacity(size), + tasks: Slab::new(), task_queue: Arc::new(TaskQueue::new()), } } #[inline] - pub fn spawn(&mut self, future: F) { - self.task_queue - .queue - .push(self.tasks.insert(Task::new(future))); + pub fn spawn(&mut self, future: Pin + Send>>) -> usize { + let id = self.tasks.insert(Task::new(future)); + self.task_queue.queue.push(id); + id } pub fn run(&mut self) { @@ -83,17 +83,17 @@ impl + Send> Executor { } } -struct Task + Send> { - future: Pin>, +struct Task { + future: Pin + Send>>, waker: Option, } -impl + Send> Task { +impl Task { #[inline(always)] - pub fn new(future: F) -> Self { + pub fn new(future: Pin + Send>>) -> Self { Self { - future: Box::pin(future), - waker: None, + future, + waker: None, } } diff --git a/repbuild/src/dev.rs b/repbuild/src/dev.rs index c5d972337..48f90e070 100644 --- a/repbuild/src/dev.rs +++ b/repbuild/src/dev.rs @@ -77,6 +77,8 @@ impl Package { let path = format!("sysdata/programs/{}/{}", self.name, file); // compile here + let mut warnings = String::new(); + hblang::run_compiler( &path, Options { @@ -85,6 +87,7 @@ impl Package { ..Default::default() }, out, + &mut warnings, )?; match std::fs::create_dir("target/programs") { @@ -100,6 +103,7 @@ impl Package { ..Default::default() }, out, + &mut warnings, )?; std::fs::write(format!("target/programs/{}.hbf", self.name), &out)?; out.clear(); @@ -112,6 +116,7 @@ impl Package { ..Default::default() }, out, + &mut warnings, )?; std::fs::write(format!("target/programs/{}.hba", self.name), &out)?; out.clear(); diff --git a/sysdata/libraries/stn/src/lib.hb b/sysdata/libraries/stn/src/lib.hb index 8c6fabc99..961037cb9 100644 --- a/sysdata/libraries/stn/src/lib.hb +++ b/sysdata/libraries/stn/src/lib.hb @@ -7,6 +7,7 @@ math := @use("math.hb") random := @use("random.hb") file := @use("file_io.hb") dt := @use("dt.hb") +process := @use("process.hb") panic := fn(message: ?^u8): never { log.error("Error: Panic Called, Message:\0") diff --git a/sysdata/libraries/stn/src/process.hb b/sysdata/libraries/stn/src/process.hb new file mode 100644 index 000000000..918067b60 --- /dev/null +++ b/sysdata/libraries/stn/src/process.hb @@ -0,0 +1,12 @@ +// ! will be rewritten to take a file object when filesystem is exist +// returns PID +$spawn := fn(proc_exe: ^u8, length: uint): uint { + return @eca(3, 6, proc_exe, length) +} + +/* TODO: +- Spawn an empty process +- Call a function to load bytes into that process from a function +Or +- Manually fill the bytes in +- Execute the process via a run type command */ \ No newline at end of file diff --git a/sysdata/programs/processes/meta.toml b/sysdata/programs/processes/meta.toml new file mode 100644 index 000000000..86a48694f --- /dev/null +++ b/sysdata/programs/processes/meta.toml @@ -0,0 +1,11 @@ +[package] +name = "processes" +authors = ["koniifer"] + +[dependants.libraries] + +[dependants.binaries] +hblang.version = "1.0.0" + +[build] +command = "hblang src/main.hb" diff --git a/sysdata/programs/processes/src/hello_world_and_spin.hb b/sysdata/programs/processes/src/hello_world_and_spin.hb new file mode 100644 index 000000000..2d75c6b2d --- /dev/null +++ b/sysdata/programs/processes/src/hello_world_and_spin.hb @@ -0,0 +1,7 @@ +.{log} := @use("../../../libraries/stn/src/lib.hb") + +main := fn(): void { + log.info("Hello, World!\0") + loop { + } +} \ No newline at end of file diff --git a/sysdata/programs/processes/src/hello_world_and_spin.hbf b/sysdata/programs/processes/src/hello_world_and_spin.hbf new file mode 100644 index 000000000..0a7f0e8d2 Binary files /dev/null and b/sysdata/programs/processes/src/hello_world_and_spin.hbf differ diff --git a/sysdata/programs/processes/src/main.hb b/sysdata/programs/processes/src/main.hb new file mode 100644 index 000000000..06b4ade8f --- /dev/null +++ b/sysdata/programs/processes/src/main.hb @@ -0,0 +1,19 @@ +.{process, log, string, memory} := @use("../../../libraries/stn/src/lib.hb") + +exe := @embed("./hello_world_and_spin.hbf") + +main := fn(): void { + buf := "\0\0\0\0\0\0\0" + loop { + log.info( + string.display_int( + @bitcast(process.spawn(@bitcast(&exe), 356)), + buf, + 10, + ), + ) + // spin so we don't spawn 10 quattuordecillion processes + i := 0 + loop if i == 1000000 break else i += 1 + } +} \ No newline at end of file