aboutsummaryrefslogtreecommitdiff
path: root/system
diff options
context:
space:
mode:
authorBobby <[email protected]>2026-02-13 12:56:59 +0530
committerBobby <[email protected]>2026-02-13 12:56:59 +0530
commitc9078cc59cd5099fdc62e0b38799a2f8b67c3766 (patch)
treec129b9c5688e811e6d09553c7a650322961df3df /system
parent0e62012a9e3fd5e6b27f1ac5e9d9fc45aaaeaf1d (diff)
downloadakiba-c9078cc59cd5099fdc62e0b38799a2f8b67c3766.tar.xz
akiba-c9078cc59cd5099fdc62e0b38799a2f8b67c3766.zip
refactor: Enhance process spawning with argument support and streamline entry points
Diffstat (limited to 'system')
-rw-r--r--system/ash/ash.zig18
-rw-r--r--system/libraries/akiba/akiba.zig5
-rw-r--r--system/libraries/akiba/kata.zig8
-rw-r--r--system/libraries/akiba/start.zig24
-rw-r--r--system/libraries/akiba/sys.zig11
-rw-r--r--system/pulse/pulse.zig7
6 files changed, 61 insertions, 12 deletions
diff --git a/system/ash/ash.zig b/system/ash/ash.zig
index 354ce56..757c910 100644
--- a/system/ash/ash.zig
+++ b/system/ash/ash.zig
@@ -5,9 +5,12 @@ const akiba = @import("akiba");
const MAX_INPUT = 256;
var input_buffer: [MAX_INPUT]u8 = undefined;
var input_len: usize = 0;
-var char_buffer: [1]u8 = undefined; // Static buffer for single char echoing
+var char_buffer: [1]u8 = undefined;
+
+export fn main(pc: u32, pv: [*]const [*:0]const u8) u8 {
+ _ = pc;
+ _ = pv;
-export fn _start() noreturn {
while (true) {
// Print prompt
_ = akiba.io.mark(akiba.io.stream, "/ >>> ", 0x00FFFFFF) catch {};
@@ -21,30 +24,27 @@ export fn _start() noreturn {
_ = akiba.io.mark(akiba.io.stream, "\n", 0x00FFFFFF) catch {};
break;
} else if (char == '\x08') {
- // Backspace
if (input_len > 0) {
input_len -= 1;
- // Echo backspace to screen
_ = akiba.io.mark(akiba.io.stream, "\x08", 0x00FFFFFF) catch {};
}
} else if (char >= 32 and char <= 126 and input_len < MAX_INPUT - 1) {
input_buffer[input_len] = char;
input_len += 1;
- // Echo character to screen
char_buffer[0] = char;
_ = akiba.io.mark(akiba.io.stream, &char_buffer, 0x00FFFFFF) catch {};
}
}
- // Parse and execute command
if (input_len > 0) {
execute_command(input_buffer[0..input_len]);
}
}
+
+ return 0;
}
fn execute_command(input: []const u8) void {
- // Trim whitespace
var start: usize = 0;
while (start < input.len and input[start] == ' ') : (start += 1) {}
@@ -55,18 +55,14 @@ fn execute_command(input: []const u8) void {
const trimmed = input[start..end];
- // Try to execute as binary
var path_buf: [512]u8 = undefined;
- // First try with .akiba extension
const path1 = build_path(&path_buf, "/binaries/", trimmed, ".akiba");
if (try_spawn(path1)) return;
- // Then try without extension (in case user typed it)
const path2 = build_path(&path_buf, "/binaries/", trimmed, "");
if (try_spawn(path2)) return;
- // Binary not found
_ = akiba.io.mark(akiba.io.stream, "ash: binary not found: ", 0x00FFFFFF) catch {};
_ = akiba.io.mark(akiba.io.stream, trimmed, 0x00FFFFFF) catch {};
_ = akiba.io.mark(akiba.io.stream, "\n", 0x00FFFFFF) catch {};
diff --git a/system/libraries/akiba/akiba.zig b/system/libraries/akiba/akiba.zig
index fc7202b..77911e1 100644
--- a/system/libraries/akiba/akiba.zig
+++ b/system/libraries/akiba/akiba.zig
@@ -3,3 +3,8 @@
pub const kata = @import("kata.zig");
pub const io = @import("io.zig");
pub const sys = @import("sys.zig");
+pub const start = @import("start.zig");
+
+comptime {
+ _ = start;
+}
diff --git a/system/libraries/akiba/kata.zig b/system/libraries/akiba/kata.zig
index 1e7cb11..49c056a 100644
--- a/system/libraries/akiba/kata.zig
+++ b/system/libraries/akiba/kata.zig
@@ -19,6 +19,14 @@ pub fn spawn(path: []const u8) !u32 {
return @truncate(result);
}
+pub fn spawn_with_args(path: []const u8, argv: []const [*:0]const u8) !u32 {
+ const result = sys.spawn_with_args(path, argv);
+ if (result == @as(u64, @bitCast(@as(i64, -1)))) {
+ return error.SpawnFailed;
+ }
+ return @truncate(result);
+}
+
pub fn wait(pid: u32) !u64 {
// Retry loop: keep checking until the target exits
while (true) {
diff --git a/system/libraries/akiba/start.zig b/system/libraries/akiba/start.zig
new file mode 100644
index 0000000..d3c374b
--- /dev/null
+++ b/system/libraries/akiba/start.zig
@@ -0,0 +1,24 @@
+//! Akiba Runtime Entry Point
+//! Provides _start that calls user's main(pc, pv) and handles exit
+
+const kata = @import("kata.zig");
+
+// User must provide this
+extern fn main(pc: u32, pv: [*]const [*:0]const u8) u8;
+
+export fn _start() callconv(.c) noreturn {
+ // Stack layout at entry:
+ // [RSP + 0] = pc (parameter count)
+ // [RSP + 8] = pv (pointer to parameter vector)
+
+ const stack_ptr = asm volatile ("mov %%rsp, %[result]"
+ : [result] "=r" (-> u64),
+ );
+
+ const pc: u32 = @intCast(@as(*const u64, @ptrFromInt(stack_ptr)).*);
+ const pv: [*]const [*:0]const u8 = @ptrFromInt(@as(*const u64, @ptrFromInt(stack_ptr + 8)).*);
+
+ const exit_code = main(pc, pv);
+
+ kata.exit(exit_code);
+}
diff --git a/system/libraries/akiba/sys.zig b/system/libraries/akiba/sys.zig
index a79e19d..424801e 100644
--- a/system/libraries/akiba/sys.zig
+++ b/system/libraries/akiba/sys.zig
@@ -52,3 +52,14 @@ pub fn syscall(inv: Invocation, params: anytype) u64 {
: .{ .rcx = true, .r11 = true, .memory = true });
return result;
}
+
+/// Spawn a new process with arguments
+/// argv should be an array of null-terminated string pointers
+pub fn spawn_with_args(path: []const u8, argv: []const [*:0]const u8) u64 {
+ return syscall(.spawn, .{
+ @intFromPtr(path.ptr),
+ path.len,
+ @intFromPtr(argv.ptr),
+ argv.len,
+ });
+}
diff --git a/system/pulse/pulse.zig b/system/pulse/pulse.zig
index 2da96cf..d0f3dd2 100644
--- a/system/pulse/pulse.zig
+++ b/system/pulse/pulse.zig
@@ -3,7 +3,10 @@
const akiba = @import("akiba");
-export fn _start() noreturn {
+export fn main(pc: u32, pv: [*]const [*:0]const u8) u8 {
+ _ = pc;
+ _ = pv;
+
// Init loop - respawn shell when it exits
while (true) {
const shell_pid = akiba.kata.spawn("/system/ash/ash.akiba") catch {
@@ -22,4 +25,6 @@ export fn _start() noreturn {
// Shell exited, respawn
akiba.io.println("\nPulse: Shell exited, respawning...\n") catch {};
}
+
+ return 0;
}