aboutsummaryrefslogtreecommitdiff
path: root/system
diff options
context:
space:
mode:
authorBobby <[email protected]>2026-01-27 15:48:11 +0530
committerBobby <[email protected]>2026-01-27 15:48:11 +0530
commitb8f9131901c99a2c2aae090e048ba4ff177c67c0 (patch)
treef5e53d3e3092ea4c1a7f6f197714d10917fb8efd /system
parent2e94f9301100d00edd3ed9637ab3f289834a1d6e (diff)
downloadakiba-b8f9131901c99a2c2aae090e048ba4ff177c67c0.tar.xz
akiba-b8f9131901c99a2c2aae090e048ba4ff177c67c0.zip
feat: Remove echo and rd binaries; add mi stack viewer and viewstack syscall
Diffstat (limited to 'system')
-rw-r--r--system/ash/ash.zig73
-rw-r--r--system/libraries/akiba/io.zig25
-rw-r--r--system/libraries/akiba/kata.zig2
-rw-r--r--system/libraries/akiba/sys.zig14
4 files changed, 100 insertions, 14 deletions
diff --git a/system/ash/ash.zig b/system/ash/ash.zig
index 5d6a600..354ce56 100644
--- a/system/ash/ash.zig
+++ b/system/ash/ash.zig
@@ -10,7 +10,7 @@ var char_buffer: [1]u8 = undefined; // Static buffer for single char echoing
export fn _start() noreturn {
while (true) {
// Print prompt
- akiba.io.print("/ >>> ") catch {};
+ _ = akiba.io.mark(akiba.io.stream, "/ >>> ", 0x00FFFFFF) catch {};
// Read line
input_len = 0;
@@ -18,29 +18,86 @@ export fn _start() noreturn {
const char = akiba.io.getchar() catch continue;
if (char == '\n') {
- akiba.io.print("\n") catch {};
+ _ = 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.print("\x08") catch {};
+ _ = 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.print(&char_buffer) catch {};
+ _ = akiba.io.mark(akiba.io.stream, &char_buffer, 0x00FFFFFF) catch {};
}
}
- // TODO: Parse and execute command
+ // Parse and execute command
if (input_len > 0) {
- akiba.io.print("Command \"") catch {};
- akiba.io.print(input_buffer[0..input_len]) catch {};
- akiba.io.print("\" not implemented yet\n") catch {};
+ execute_command(input_buffer[0..input_len]);
}
}
}
+
+fn execute_command(input: []const u8) void {
+ // Trim whitespace
+ var start: usize = 0;
+ while (start < input.len and input[start] == ' ') : (start += 1) {}
+
+ var end: usize = input.len;
+ while (end > start and input[end - 1] == ' ') : (end -= 1) {}
+
+ if (start >= end) return;
+
+ 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 {};
+}
+
+fn build_path(buf: []u8, prefix: []const u8, name: []const u8, suffix: []const u8) []const u8 {
+ var pos: usize = 0;
+
+ for (prefix) |c| {
+ if (pos >= buf.len) break;
+ buf[pos] = c;
+ pos += 1;
+ }
+
+ for (name) |c| {
+ if (pos >= buf.len) break;
+ buf[pos] = c;
+ pos += 1;
+ }
+
+ for (suffix) |c| {
+ if (pos >= buf.len) break;
+ buf[pos] = c;
+ pos += 1;
+ }
+
+ return buf[0..pos];
+}
+
+fn try_spawn(path: []const u8) bool {
+ const pid = akiba.kata.spawn(path) catch return false;
+ _ = akiba.kata.wait(pid) catch return false;
+ return true;
+}
diff --git a/system/libraries/akiba/io.zig b/system/libraries/akiba/io.zig
index 9de3f2f..7155e27 100644
--- a/system/libraries/akiba/io.zig
+++ b/system/libraries/akiba/io.zig
@@ -44,8 +44,8 @@ pub fn view(fd: FileDescriptor, buffer: []u8) Error!usize {
return result;
}
-pub fn mark(fd: FileDescriptor, data: []const u8) Error!usize {
- const result = sys.syscall3(.mark, fd, @intFromPtr(data.ptr), data.len);
+pub fn mark(fd: FileDescriptor, data: []const u8, color: u32) Error!usize {
+ const result = sys.syscall4(.mark, fd, @intFromPtr(data.ptr), data.len, color);
if (result == @as(u64, @bitCast(@as(i64, -1)))) {
return Error.WriteFailed;
}
@@ -68,10 +68,25 @@ pub fn getchar() !u8 {
}
pub fn print(text: []const u8) Error!void {
- _ = try mark(stream, text);
+ _ = try mark(stream, text, 0x00FFFFFF);
}
pub fn println(text: []const u8) Error!void {
- _ = try mark(stream, text);
- _ = try mark(stream, "\n");
+ _ = try mark(stream, text, 0x00FFFFFF);
+ _ = try mark(stream, "\n", 0x00FFFFFF);
}
+
+pub fn viewstack(path: []const u8, entries: []StackEntry) Error!usize {
+ const result = sys.syscall4(.viewstack, @intFromPtr(path.ptr), path.len, @intFromPtr(entries.ptr), entries.len);
+ if (result == @as(u64, @bitCast(@as(i64, -1)))) {
+ return Error.ReadFailed;
+ }
+ return result;
+}
+
+pub const StackEntry = extern struct {
+ identity: [64]u8,
+ identity_len: u8,
+ size: u32,
+ is_stack: bool,
+};
diff --git a/system/libraries/akiba/kata.zig b/system/libraries/akiba/kata.zig
index 14f2946..7345532 100644
--- a/system/libraries/akiba/kata.zig
+++ b/system/libraries/akiba/kata.zig
@@ -12,7 +12,7 @@ pub fn exit(code: u64) noreturn {
}
pub fn spawn(path: []const u8) !u32 {
- const result = sys.syscall1(.spawn, @intFromPtr(path.ptr));
+ const result = sys.syscall2(.spawn, @intFromPtr(path.ptr), path.len);
if (result == @as(u64, @bitCast(@as(i64, -1)))) {
return error.SpawnFailed;
}
diff --git a/system/libraries/akiba/sys.zig b/system/libraries/akiba/sys.zig
index 10329ff..796a09a 100644
--- a/system/libraries/akiba/sys.zig
+++ b/system/libraries/akiba/sys.zig
@@ -10,6 +10,7 @@ pub const Invocation = enum(u64) {
wait = 0x07,
yield = 0x08,
getkeychar = 0x09,
+ viewstack = 0x0A,
};
pub fn syscall0(inv: Invocation) u64 {
@@ -53,3 +54,16 @@ pub fn syscall3(inv: Invocation, arg1: u64, arg2: u64, arg3: u64) u64 {
: .{ .rcx = true, .r11 = true, .memory = true });
return result;
}
+
+pub fn syscall4(inv: Invocation, arg1: u64, arg2: u64, arg3: u64, arg4: u64) u64 {
+ var result: u64 = undefined;
+ asm volatile ("syscall"
+ : [ret] "={rax}" (result),
+ : [inv] "{rax}" (@intFromEnum(inv)),
+ [arg1] "{rdi}" (arg1),
+ [arg2] "{rsi}" (arg2),
+ [arg3] "{rdx}" (arg3),
+ [arg4] "{r10}" (arg4),
+ : .{ .rcx = true, .r11 = true, .memory = true });
+ return result;
+}