aboutsummaryrefslogtreecommitdiff
path: root/system
diff options
context:
space:
mode:
authorBobby <[email protected]>2026-01-22 18:15:12 +0530
committerBobby <[email protected]>2026-01-22 18:15:12 +0530
commit3edd887543474bac679cc8073006bfe4ceacb2ea (patch)
tree3a387acdd6b931f681fc360c7013b9321d4f8758 /system
parentb0375f165f3616dbb8b880b7cf602d281f1d27de (diff)
downloadakiba-3edd887543474bac679cc8073006bfe4ceacb2ea.tar.xz
akiba-3edd887543474bac679cc8073006bfe4ceacb2ea.zip
feat: Implement keyboard input handling and shell functionality
- Added framebuffer initialization and retrieval functions in multiboot2.zig. - Integrated framebuffer support into the boot sequence. - Refactored keyboard driver to use a circular buffer for input and added blocking behavior for kata waiting on keyboard input. - Enhanced kata management to support blocking and waking katas based on keyboard input. - Introduced a new invocation for reading a character from the keyboard (getkeychar). - Implemented a simple shell (ash) that reads user input and echoes it back. - Updated syscall handling to include the new getkeychar invocation. - Improved memory management for loading programs and handling user/kernel stacks. - Added functionality to wake katas waiting for specific events, such as the dissolution of other katas.
Diffstat (limited to 'system')
-rw-r--r--system/ash/ash.zig45
-rw-r--r--system/ash/ash.zon8
-rw-r--r--system/libraries/akiba/io.zig16
-rw-r--r--system/libraries/akiba/kata.zig12
-rw-r--r--system/libraries/akiba/sys.zig13
-rw-r--r--system/pulse/pulse.zig19
6 files changed, 98 insertions, 15 deletions
diff --git a/system/ash/ash.zig b/system/ash/ash.zig
new file mode 100644
index 0000000..577dea3
--- /dev/null
+++ b/system/ash/ash.zig
@@ -0,0 +1,45 @@
+//! Ash - Akiba Shell
+
+const akiba = @import("akiba");
+
+const MAX_INPUT = 256;
+var input_buffer: [MAX_INPUT]u8 = undefined;
+var input_len: usize = 0;
+
+export fn _start() noreturn {
+ while (true) {
+ // Print prompt
+ akiba.io.print("/ >>> ") catch {};
+
+ // Read line
+ input_len = 0;
+ while (true) {
+ const char = akiba.io.getchar() catch continue;
+
+ if (char == '\n') {
+ akiba.io.print("\n") catch {};
+ break;
+ } else if (char == '\x08') {
+ // Backspace
+ if (input_len > 0) {
+ input_len -= 1;
+ // Echo backspace to screen
+ akiba.io.print("\x08") 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
+ const char_str = [_]u8{char};
+ akiba.io.print(&char_str) catch {};
+ }
+ }
+
+ // TODO: 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 {};
+ }
+ }
+}
diff --git a/system/ash/ash.zon b/system/ash/ash.zon
new file mode 100644
index 0000000..0c72775
--- /dev/null
+++ b/system/ash/ash.zon
@@ -0,0 +1,8 @@
+.{
+ .name = "ash",
+ .version = "0.1.0",
+ .paths = .{""},
+ .dependencies = .{
+ .akiba = .{ .path = "../libraries/akiba" },
+ },
+}
diff --git a/system/libraries/akiba/io.zig b/system/libraries/akiba/io.zig
index b8f8eef..35ff739 100644
--- a/system/libraries/akiba/io.zig
+++ b/system/libraries/akiba/io.zig
@@ -1,6 +1,7 @@
//! File I/O operations
const sys = @import("sys.zig");
+const kata = @import("kata.zig");
pub const Error = error{
NotFound,
@@ -51,6 +52,21 @@ pub fn mark(fd: FileDescriptor, data: []const u8) Error!usize {
return result;
}
+pub fn getchar() !u8 {
+ // Loop until character is available, yielding CPU
+ while (true) {
+ const result = sys.syscall0(.getkeychar);
+ if (result != @as(u64, @bitCast(@as(i64, -2)))) {
+ if (result != @as(u64, @bitCast(@as(i64, -1)))) {
+ return @truncate(result);
+ }
+ return error.ReadFailed;
+ }
+ // No input yet (-2 = EAGAIN), yield and try again
+ kata.yield();
+ }
+}
+
pub fn print(text: []const u8) Error!void {
_ = try mark(stream, text);
}
diff --git a/system/libraries/akiba/kata.zig b/system/libraries/akiba/kata.zig
index 2283ce8..14f2946 100644
--- a/system/libraries/akiba/kata.zig
+++ b/system/libraries/akiba/kata.zig
@@ -20,9 +20,13 @@ pub fn spawn(path: []const u8) !u32 {
}
pub fn wait(pid: u32) !u64 {
- const result = sys.syscall1(.wait, pid);
- if (result == @as(u64, @bitCast(@as(i64, -1)))) {
- return error.WaitFailed;
+ // Retry loop: keep checking until the target exits
+ while (true) {
+ const result = sys.syscall1(.wait, pid);
+ if (result != @as(u64, @bitCast(@as(i64, -1)))) {
+ return result;
+ }
+ // Target still running, yield and try again
+ yield();
}
- return result;
}
diff --git a/system/libraries/akiba/sys.zig b/system/libraries/akiba/sys.zig
index ee74777..10329ff 100644
--- a/system/libraries/akiba/sys.zig
+++ b/system/libraries/akiba/sys.zig
@@ -9,6 +9,7 @@ pub const Invocation = enum(u64) {
spawn = 0x06,
wait = 0x07,
yield = 0x08,
+ getkeychar = 0x09,
};
pub fn syscall0(inv: Invocation) u64 {
@@ -16,8 +17,7 @@ pub fn syscall0(inv: Invocation) u64 {
asm volatile ("syscall"
: [ret] "={rax}" (result),
: [inv] "{rax}" (@intFromEnum(inv)),
- : .{ .rcx = true, .r11 = true, .memory = true }
- );
+ : .{ .rcx = true, .r11 = true, .memory = true });
return result;
}
@@ -27,8 +27,7 @@ pub fn syscall1(inv: Invocation, arg1: u64) u64 {
: [ret] "={rax}" (result),
: [inv] "{rax}" (@intFromEnum(inv)),
[arg1] "{rdi}" (arg1),
- : .{ .rcx = true, .r11 = true, .memory = true }
- );
+ : .{ .rcx = true, .r11 = true, .memory = true });
return result;
}
@@ -39,8 +38,7 @@ pub fn syscall2(inv: Invocation, arg1: u64, arg2: u64) u64 {
: [inv] "{rax}" (@intFromEnum(inv)),
[arg1] "{rdi}" (arg1),
[arg2] "{rsi}" (arg2),
- : .{ .rcx = true, .r11 = true, .memory = true }
- );
+ : .{ .rcx = true, .r11 = true, .memory = true });
return result;
}
@@ -52,7 +50,6 @@ pub fn syscall3(inv: Invocation, arg1: u64, arg2: u64, arg3: u64) u64 {
[arg1] "{rdi}" (arg1),
[arg2] "{rsi}" (arg2),
[arg3] "{rdx}" (arg3),
- : .{ .rcx = true, .r11 = true, .memory = true }
- );
+ : .{ .rcx = true, .r11 = true, .memory = true });
return result;
}
diff --git a/system/pulse/pulse.zig b/system/pulse/pulse.zig
index c558eb3..2da96cf 100644
--- a/system/pulse/pulse.zig
+++ b/system/pulse/pulse.zig
@@ -4,9 +4,22 @@
const akiba = @import("akiba");
export fn _start() noreturn {
- akiba.io.println("Pulse: System ready!") catch {};
-
+ // Init loop - respawn shell when it exits
while (true) {
- akiba.kata.yield();
+ const shell_pid = akiba.kata.spawn("/system/ash/ash.akiba") catch {
+ akiba.io.println("Pulse: Failed to spawn shell") catch {};
+ akiba.kata.yield();
+ continue;
+ };
+
+ // Wait for shell to exit
+ _ = akiba.kata.wait(shell_pid) catch {
+ akiba.io.println("Pulse: Shell wait failed") catch {};
+ akiba.kata.yield();
+ continue;
+ };
+
+ // Shell exited, respawn
+ akiba.io.println("\nPulse: Shell exited, respawning...\n") catch {};
}
}