1
0
Fork 0
forked from AbleOS/ableos

implement stn.process.fork, also various bug fixes, update dependencies

This commit is contained in:
koniifer 2025-01-30 21:17:00 +00:00
parent 62f9fa1fd4
commit 9142c02da0
14 changed files with 129 additions and 87 deletions
Cargo.lock
kernel/src
sysdata
libraries
programs
horizon/src
serial_driver/src
test/src

68
Cargo.lock generated
View file

@ -61,9 +61,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bitflags"
version = "2.6.0"
version = "2.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36"
[[package]]
name = "byteorder"
@ -73,9 +73,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "cc"
version = "1.2.6"
version = "1.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d6dbb628b8f8555f86d0323c2eb39e3ec81901f4b83e091db8a6a76d316a333"
checksum = "13208fcbb66eaeffe09b99fffbe1af420f00a7b35aa99ad683dfc1aa76145229"
dependencies = [
"shlex",
]
@ -213,12 +213,12 @@ dependencies = [
[[package]]
name = "hbbytecode"
version = "0.1.0"
source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#d1bc70892b442376138e854450b0f423302962ef"
source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#18e8a831ab6b710dbdd9b0d6a0880c67df0cec26"
[[package]]
name = "hblang"
version = "0.1.0"
source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#d1bc70892b442376138e854450b0f423302962ef"
source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#18e8a831ab6b710dbdd9b0d6a0880c67df0cec26"
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#d1bc70892b442376138e854450b0f423302962ef"
source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#18e8a831ab6b710dbdd9b0d6a0880c67df0cec26"
dependencies = [
"hbbytecode",
]
@ -375,9 +375,9 @@ dependencies = [
[[package]]
name = "indexmap"
version = "2.7.0"
version = "2.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f"
checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652"
dependencies = [
"equivalent",
"hashbrown",
@ -449,9 +449,9 @@ dependencies = [
[[package]]
name = "log"
version = "0.4.22"
version = "0.4.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f"
[[package]]
name = "logos"
@ -512,9 +512,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
[[package]]
name = "proc-macro2"
version = "1.0.92"
version = "1.0.93"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0"
checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99"
dependencies = [
"unicode-ident",
]
@ -539,11 +539,11 @@ dependencies = [
[[package]]
name = "raw-cpuid"
version = "11.2.0"
version = "11.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ab240315c661615f2ee9f0f2cd32d5a7343a84d5ebcccb99d46e6637565e7b0"
checksum = "c6928fa44c097620b706542d428957635951bade7143269085389d42c8a4927e"
dependencies = [
"bitflags 2.6.0",
"bitflags 2.8.0",
]
[[package]]
@ -561,7 +561,7 @@ dependencies = [
"fatfs",
"hblang",
"log",
"raw-cpuid 11.2.0",
"raw-cpuid 11.3.0",
"str-reader",
"toml",
"ureq",
@ -593,9 +593,9 @@ dependencies = [
[[package]]
name = "rustls"
version = "0.23.20"
version = "0.23.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5065c3f250cbd332cd894be57c40fa52387247659b14a2d6041d121547903b1b"
checksum = "9fb9263ab4eb695e42321db096e3b8fbd715a59b154d5c88d82db2175b681ba7"
dependencies = [
"log",
"once_cell",
@ -608,9 +608,9 @@ dependencies = [
[[package]]
name = "rustls-pki-types"
version = "1.10.1"
version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2bf47e6ff922db3825eb750c4e2ff784c6ff8fb9e13046ef6a1d1c5401b0b37"
checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c"
[[package]]
name = "rustls-webpki"
@ -643,9 +643,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "semver"
version = "1.0.24"
version = "1.0.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3cb6eb87a131f756572d7fb904f6e7b68633f09cca868c5df1c4b8d1a694bbba"
checksum = "f79dfe2d285b0488816f30e700a7438c5a73d816b5b7d3ac72fbc48b0d185e03"
[[package]]
name = "serde"
@ -726,9 +726,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
[[package]]
name = "syn"
version = "2.0.93"
version = "2.0.96"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c786062daee0d6db1132800e623df74274a0a87322d8e183338e01b3d98d058"
checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80"
dependencies = [
"proc-macro2",
"quote",
@ -785,9 +785,9 @@ dependencies = [
[[package]]
name = "toml_edit"
version = "0.22.22"
version = "0.22.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5"
checksum = "02a8b472d1a3d7c18e2d61a489aee3453fd9031c33e4f55bd533f4a7adca1bee"
dependencies = [
"indexmap",
"serde",
@ -802,16 +802,16 @@ version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e492212ac378a5e00da953718dafb1340d9fbaf4f27d6f3c5cab03d931d1c049"
dependencies = [
"bitflags 2.6.0",
"bitflags 2.8.0",
"rustversion",
"x86",
]
[[package]]
name = "unicode-ident"
version = "1.0.14"
version = "1.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83"
checksum = "a210d160f08b701c8721ba1c726c11662f877ea6b7094007e1ca9a1041945034"
[[package]]
name = "unicode-xid"
@ -967,9 +967,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "winnow"
version = "0.6.21"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6f5bb5257f2407a5425c6e749bfd9692192a73e70a6060516ac04f889087d68"
checksum = "7e49d2d35d3fad69b39b94139037ecfb4f359f08958b9c11e7315ce770462419"
dependencies = [
"memchr",
]
@ -1017,7 +1017,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c101112411baafbb4bf8d33e4c4a80ab5b02d74d2612331c61e8192fc9710491"
dependencies = [
"bit_field",
"bitflags 2.6.0",
"bitflags 2.8.0",
"rustversion",
"volatile",
]
@ -1029,7 +1029,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0f042214de98141e9c8706e8192b73f56494087cc55ebec28ce10f26c5c364ae"
dependencies = [
"bit_field",
"bitflags 2.6.0",
"bitflags 2.8.0",
"rustversion",
"volatile",
]

View file

@ -8,14 +8,13 @@ use crate::{
block_read, dt_msg_handler::dt_msg_handler, logging_service::log_msg_handler,
service_definition_service::sds_msg_handler,
},
ExecThread,
ExecThread, STACK_SIZE,
},
kmain::EXECUTOR,
task::Executor,
};
use {
super::Vm,
crate::{arch, ipc::buffer::IpcBuffer, kmain::IPC_BUFFERS},
hbvm::value::Value,
log::{debug, error, info, trace},
@ -33,21 +32,21 @@ unsafe fn x86_in<T: x86_64::instructions::port::PortRead>(address: u16) -> T {
}
#[inline(always)]
pub fn handler(vm: &mut Vm, pid: &usize) {
let ecall_number = vm.registers[2].cast::<u64>();
pub fn handler(thr: &mut ExecThread, pid: &usize) {
let ecall_number = thr.vm.registers[2].cast::<u64>();
match ecall_number {
0 => {
// TODO: explode computer
// hello world ecall
for x in 0u64..=255 {
vm.registers[x as usize] = x.into();
thr.vm.registers[x as usize] = x.into();
}
}
1 => {
// Make buffer
let bounded = match vm.registers[3] {
let bounded = match thr.vm.registers[3] {
Value(0) => false,
Value(1) => true,
_ => {
@ -55,7 +54,7 @@ pub fn handler(vm: &mut Vm, pid: &usize) {
}
};
let length = vm.registers[4].cast::<u64>();
let length = thr.vm.registers[4].cast::<u64>();
let mut buffs = IPC_BUFFERS.lock();
@ -67,7 +66,7 @@ pub fn handler(vm: &mut Vm, pid: &usize) {
true => IpcBuffer::new(true, length),
},
);
vm.registers[1] = hbvm::value::Value(buff_id);
thr.vm.registers[1] = hbvm::value::Value(buff_id);
}
2 => {
log::error!("Oops, deleting buffers is not implemented.")
@ -75,9 +74,9 @@ pub fn handler(vm: &mut Vm, pid: &usize) {
}
3 => {
// Send a message to a buffer
let buffer_id = vm.registers[3].cast::<u64>();
let mem_addr = vm.registers[4].cast::<u64>();
let length = vm.registers[5].cast::<u64>() as usize;
let buffer_id = thr.vm.registers[3].cast::<u64>();
let mem_addr = thr.vm.registers[4].cast::<u64>();
let length = thr.vm.registers[5].cast::<u64>() as usize;
trace!("IPC address: {:?}", mem_addr);
unsafe { LazyCell::<Executor>::get_mut(&mut EXECUTOR) }
@ -85,17 +84,17 @@ pub fn handler(vm: &mut Vm, pid: &usize) {
.send_buffer(buffer_id as usize);
match buffer_id {
0 => match sds_msg_handler(vm, mem_addr, length) {
0 => match sds_msg_handler(&mut thr.vm, mem_addr, length) {
Ok(()) => {}
Err(err) => log::error!("Improper sds format: {err:?}"),
},
1 => match log_msg_handler(vm, mem_addr, length) {
1 => match log_msg_handler(&mut thr.vm, mem_addr, length) {
Ok(()) => {}
Err(_) => log::error!("Improper log format"),
},
2 => {
use crate::holeybytes::kernel_services::mem_serve::memory_msg_handler;
match memory_msg_handler(vm, mem_addr, length) {
match memory_msg_handler(&mut thr.vm, mem_addr, length) {
Ok(_) => {}
Err(_) => {}
}
@ -116,7 +115,7 @@ pub fn handler(vm: &mut Vm, pid: &usize) {
_ => panic!("Trying to read size other than: 8, 16, 32 from port."),
};
// info!("Read the value {} from address {}", value, addr);
vm.registers[1] = hbvm::value::Value(value);
thr.vm.registers[1] = hbvm::value::Value(value);
},
1 => unsafe {
let size = msg_vec[1];
@ -150,9 +149,9 @@ pub fn handler(vm: &mut Vm, pid: &usize) {
&crate::arch::hardware_random_u64().to_le_bytes()[..chunk.len()],
);
});
vm.registers[1] = hbvm::value::Value(mem_addr);
thr.vm.registers[1] = hbvm::value::Value(mem_addr);
}
5 => match dt_msg_handler(vm, mem_addr, length) {
5 => match dt_msg_handler(&mut thr.vm, mem_addr, length) {
Ok(()) => {}
Err(_) => log::error!("Improper dt query"),
},
@ -181,18 +180,39 @@ pub fn handler(vm: &mut Vm, pid: &usize) {
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(
let thr2 = ExecThread::new(program[offset..end].into(), Address::new(0));
thr.vm.registers[1] = Value(
LazyCell::<Executor>::get_mut(&mut EXECUTOR)
.unwrap()
.spawn(Box::pin(async move {
if let Err(e) = thr.await {
if let Err(e) = thr2.await {
log::error!("{e:?}");
}
})) as u64,
);
log::debug!("spawned a process");
},
7 => unsafe {
let mut thr2 = ExecThread::new(
thr.program,
thr.vm.pc.wrapping_sub(thr.program.as_ptr() as u64),
);
thr.stack_bottom
.copy_to_nonoverlapping(thr2.stack_bottom, STACK_SIZE);
thr2.vm.registers = thr.vm.registers;
thr2.vm.registers[1] = Value(0);
thr.vm.registers[1] = Value(
LazyCell::<Executor>::get_mut(&mut EXECUTOR)
.unwrap()
.spawn(Box::pin(async move {
if let Err(e) = thr2.await {
log::error!("{e:?}");
}
})) as u64,
);
log::debug!("forked a process")
},
buffer_id => {
let mut buffs = IPC_BUFFERS.lock();
@ -210,9 +230,9 @@ pub fn handler(vm: &mut Vm, pid: &usize) {
}
}
4 => {
let buffer_id = vm.registers[3].cast::<u64>();
let map_ptr = vm.registers[4].cast::<u64>();
let max_length = vm.registers[5].cast::<u64>();
let buffer_id = thr.vm.registers[3].cast::<u64>();
let map_ptr = thr.vm.registers[4].cast::<u64>();
let max_length = thr.vm.registers[5].cast::<u64>();
let mut buffs = IPC_BUFFERS.lock();
let buff: &mut IpcBuffer = match buffs.get_mut(&buffer_id) {
Some(buff) => buff,
@ -240,16 +260,16 @@ pub fn handler(vm: &mut Vm, pid: &usize) {
5 => {
#[cfg(target_arch = "x86_64")]
{
let r2 = vm.registers[2].cast::<u64>();
let r2 = thr.vm.registers[2].cast::<u64>();
let x = hbvm::value::Value(unsafe { x86_in::<u8>(r2 as u16) } as u64);
// info!("Read {:?} from Port {:?}", x, r2);
vm.registers[3] = x
thr.vm.registers[3] = x
}
}
6 => {
// Wait till interrupt
use crate::kmain::EXECUTOR;
let interrupt_type = vm.registers[3].cast::<u8>();
let interrupt_type = thr.vm.registers[3].cast::<u8>();
debug!("Interrupt subscribed: {}", interrupt_type);
unsafe {
LazyCell::<Executor>::get_mut(&mut EXECUTOR)
@ -260,7 +280,7 @@ pub fn handler(vm: &mut Vm, pid: &usize) {
7 => {
// Wait till buffer
use crate::kmain::EXECUTOR;
let buffer_id = vm.registers[3].cast::<u64>() as usize;
let buffer_id = thr.vm.registers[3].cast::<u64>() as usize;
debug!("Buffer subscribed: {}", buffer_id);
unsafe {
LazyCell::<Executor>::get_mut(&mut EXECUTOR)
@ -269,7 +289,7 @@ pub fn handler(vm: &mut Vm, pid: &usize) {
}
}
_ => {
log::error!("Syscall unknown {:?}{:?}", ecall_number, vm.registers);
log::error!("Syscall unknown {:?}{:?}", ecall_number, thr.vm.registers);
}
}
}

View file

@ -60,7 +60,8 @@ impl hbvm::mem::Memory for Memory {
}
#[inline(always)]
fn log_instr(&mut self, _at: Address, _regs: &[hbvm::value::Value]) {
#[allow(unused)]
fn log_instr(&mut self, at: Address, regs: &[hbvm::value::Value]) {
// log::debug!("exec: [{:02x}] {}", at.get(), unsafe {
// self.logger.display_instr(at, regs)
// });

View file

@ -24,6 +24,7 @@ type Vm = hbvm::Vm<mem::Memory, TIMER_QUOTIENT>;
pub struct ExecThread {
vm: Vm,
stack_bottom: *mut u8,
program: &'static [u8],
}
unsafe impl Send for ExecThread {}
@ -34,7 +35,7 @@ impl ExecThread {
self.vm.registers[2] = hbvm::value::Value(length);
}
pub unsafe fn new(program: &[u8], entrypoint: Address) -> Self {
pub unsafe fn new(program: &'static [u8], entrypoint: Address) -> Self {
let mut vm = Vm::new(
mem::Memory::default(),
Address::new(program.as_ptr() as u64 + entrypoint.get()),
@ -44,7 +45,11 @@ impl ExecThread {
vm.write_reg(254, (stack_bottom as usize + STACK_SIZE - 1) as u64);
ExecThread { vm, stack_bottom }
ExecThread {
vm,
stack_bottom,
program,
}
}
}
@ -66,7 +71,7 @@ impl<'p> Future for ExecThread {
}
Ok(VmRunOk::End) => return Poll::Ready(Ok(())),
Ok(VmRunOk::Ecall) => ecah::handler(
&mut self.vm,
&mut self,
cx.ext()
.downcast_ref()
.expect("PID did not exist in Context"),

View file

@ -19,15 +19,12 @@ use {
spin::{Lazy, Mutex},
};
pub fn kmain(_cmdline: &str, boot_modules: BootModules) -> ! {
pub fn kmain(_cmdline: &str, boot_modules: BootModules<'static>) -> ! {
debug!("Entered kmain");
#[cfg(feature = "ktest")]
{
use {
crate::ktest,
log::info,
};
use {crate::ktest, log::info};
info!("Running tests");
ktest::test_main();

View file

@ -21,7 +21,7 @@ create_window := fn(channel: uint): ^render.Surface {
// wait to recieve a message
windowing_system_buffer := buffer.search("XHorizon")
mem_buf := memory.request_page(1)
mem_buf := memory.request_page(1, false)
if windowing_system_buffer == 0 {
return @as(^render.Surface, idk)

View file

@ -10,7 +10,7 @@ BlockAlloc := struct {
ptr: ?^u8,
$init := fn(): Self {
alloc_page_ptr := memory.request_page(1)
alloc_page_ptr := memory.request_page(1, false)
state := 0xFFFFFFFFFFFFFFFF
return .(state, alloc_page_ptr)
}

View file

@ -1,3 +1,3 @@
$get := fn($Expr: type, query: []u8): Expr {
return @eca(3, 5, query, query.len)
return @eca(3, 5, query.ptr, query.len)
}

View file

@ -24,7 +24,7 @@ print_buffer := memory.dangling(u8)
print := fn(v: @Any(), opts: fmt.FormatOptions): void {
if print_buffer == memory.dangling(u8) {
print_buffer = memory.request_page(1)
print_buffer = memory.request_page(1, false)
}
len := @inline(fmt.format, v, print_buffer[0..memory.PAGE_SIZE], opts)
@eca(3, 1, LogMsg.(opts.log, print_buffer, len), @sizeof(LogMsg))
@ -33,7 +33,7 @@ print := fn(v: @Any(), opts: fmt.FormatOptions): void {
printf := fn(str: []u8, v: @Any(), opts: fmt.FormatOptions): void {
if print_buffer == memory.dangling(u8) {
print_buffer = memory.request_page(1)
print_buffer = memory.request_page(1, false)
}
len := @inline(fmt.format_with_str, v, str, print_buffer[0..memory.PAGE_SIZE], opts)
@eca(3, 1, LogMsg.(opts.log, print_buffer, len), @sizeof(LogMsg))

View file

@ -1,9 +1,10 @@
// ! 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)
}
$fork := fn(): uint return @eca(3, 7)
/* TODO:
- Spawn an empty process
- Call a function to load bytes into that process from a function

View file

@ -39,7 +39,7 @@ main := fn(): int {
window := render.Surface.new(screen.width / 3, screen.height / 3)
mem_buf := memory.request_page(1)
mem_buf := memory.request_page(1, false)
color := random.any(render.Color)
side := window.width / 8

View file

@ -23,7 +23,7 @@ main := fn(): int {
a := buffer.create("XNumber")
serial_println("Starting Serial Driver.")
mem := memory.request_page(1)[1..memory.PAGE_SIZE]
mem := memory.request_page(1, true)[1..memory.PAGE_SIZE]
loop {
ptr := @as(^u8, @eca(4, a, mem, 0x1000))

View file

@ -1,7 +1,4 @@
stn := @use("./tests/stn/lib.hb")
serial_driver := @use("./tests/serial_driver.hb")
main := fn(): uint {
// return serial_driver.test()
return stn.process.test()
}
main := stn.process.test

View file

@ -1,9 +1,30 @@
.{process, log} := @use("stn")
.{process, log, memory} := @use("stn")
// src: https://git.ablecorp.us/koniifer/lily
exe := @embed("./assets/lily.axe")
/*
* extract to un-inlined function so the compiler doesnt
* assume that `*a` never changes (program doesnt work otherwise)
* (this is a reason why memory sharing is bad)
*/
opaque := fn(ptr: ^bool): bool {
return *ptr
}
test := fn(): uint {
process.spawn(@bitcast(&exe), @sizeof(@TypeOf(exe)))
a: ^bool = @bitcast(memory.request_page(1, true))
x := process.fork()
log.info("both will print this")
// (x == 0) => child process
// (x == N) => N is PID of new child process (in theory)
if x == 0 {
// ! NOTE: NEVER DO THIS!!! USE BUFFERS INSTEAD!!! :)
// acts as a lock. when parent is done, this can go ahead.
loop if opaque(a) break else {
};
log.info("child done.")
} else {
*a = true
log.info("parent done.")
}
return 0
}