sylveos

Toy Operating System
Log | Files | Refs

commit f0032e962f4cd48af67f1d78ca7f37c7c82f740e
parent 2257dee555b44129f375ce78d8b726414d521d8e
Author: Sylvia Ivory <git@sivory.net>
Date:   Sun, 15 Mar 2026 12:48:35 -0700

Hello World from Linux

Diffstat:
M.gitignore | 1+
Msylveos/loader.zig | 50--------------------------------------------------
Msylveos/memory.zig | 2--
Msylveos/root.zig | 6++----
Asylveos/syscall.zig | 50++++++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 53 insertions(+), 56 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -3,3 +3,4 @@ /src/*.runner.zig target /sylveos/hello +/sylveos/lua diff --git a/sylveos/loader.zig b/sylveos/loader.zig @@ -34,12 +34,6 @@ pub fn init(pt_alloc: std.mem.Allocator, heap_alloc: std.mem.Allocator, root: [] var elf_reader = std.Io.Reader.fixed(elf); const header = try std.elf.Header.read(&elf_reader); - - uart.print("phnum: {d}\n", .{header.phnum}); - uart.print("elf len: {d}\n", .{elf.len}); - uart.print("seek: {d}\n", .{elf_reader.seek}); - uart.print("end: {d}\n", .{elf_reader.end}); - var it: ProgramHeaderBufferIterator = .{ .elf_header = header, .buf = elf, @@ -54,12 +48,9 @@ pub fn init(pt_alloc: std.mem.Allocator, heap_alloc: std.mem.Allocator, root: [] const end = std.mem.alignForward(u32, @intCast(program_header.p_vaddr + program_header.p_memsz), memory.KB4); while (va < end) : (va += memory.KB4) { - uart.print("requesting 4kb: ", .{}); const pa = try memory.request_4kb(heap_alloc); - uart.print("VA(0x{X:0>8}) -> PA(0x{X:0>8})\n", .{ va, pa }); try pages.map_4kb(va, pa, .{}); - uart.print(" mapped: VA(0x{X:0>8}) -> PA(0x{X:0>8})\n", .{ va, memory.translate(va) catch 0 }); // Zero page const dst: [*]u8 = @ptrFromInt(va); @@ -88,7 +79,6 @@ pub fn init(pt_alloc: std.mem.Allocator, heap_alloc: std.mem.Allocator, root: [] header_location = va + offset_in_page; } - uart.print(" writing to 0x{X} from 0x{X} (0x{X})\n", .{ va + offset_in_page, file_offset, copy_size }); @memcpy(dst[offset_in_page .. offset_in_page + copy_size], src); } } @@ -106,9 +96,7 @@ pub fn init(pt_alloc: std.mem.Allocator, heap_alloc: std.mem.Allocator, root: [] { const sp = stack_top - stack_size; - uart.print("requesting 64kb: ", .{}); const pa = try memory.request_64kb(heap_alloc); - uart.print("0x{X:0>8}\n", .{pa}); try pages.map_64kb(sp, pa, .{}); @@ -118,9 +106,7 @@ pub fn init(pt_alloc: std.mem.Allocator, heap_alloc: std.mem.Allocator, root: [] // kuser { - uart.print("requesting 4kb: ", .{}); const pa = try memory.request_4kb(heap_alloc); - uart.print("0x{X:0>8}\n", .{pa}); // TODO; read only try pages.map_4kb(0xFFFF_0000, pa, .{}); @@ -160,97 +146,79 @@ pub fn execute(self: *Program, pid: u24, args: []const []const u8, env: []const // 6. Arguments // 7. Argc - uart.print("initial sp: {X}\n", .{sp}); - sp = align_down(sp, 8); - uart.print("initial alignment: {X}\n", .{sp}); // https://xkcd.com/221/ const at_random_ptr = push_stack_bytes(sp, &[_]u8{4} ** 16); sp = at_random_ptr; - uart.print("at_random ptr: {X}\n", .{sp}); const env_ptrs = try alloc.alloc(u32, env.len); for (env, 0..) |e, idx| { sp = push_cstring(sp, e); env_ptrs[idx] = sp; } - uart.print("env ptrs: {X}\n", .{sp}); const arg_ptrs = try alloc.alloc(u32, args.len); for (args, 0..) |a, idx| { sp = push_cstring(sp, a); arg_ptrs[idx] = sp; } - uart.print("arg ptrs: {X}\n", .{sp}); sp = align_down(sp, 8); // AT_NULL sp = push_u32(sp, 0); sp = push_u32(sp, @intFromEnum(AuxTag.AT_NULL)); - uart.print("at_null sp: {X}\n", .{sp}); // AT_PHDR sp = push_u32(sp, self.header_location); sp = push_u32(sp, @intFromEnum(AuxTag.AT_PHDR)); - uart.print("at_phdr sp: {X}\n", .{sp}); // AT_PHENT sp = push_u32(sp, self.elf_header.phentsize); sp = push_u32(sp, @intFromEnum(AuxTag.AT_PHENT)); - uart.print("at_phent sp: {X}\n", .{sp}); // AT_PHNUM sp = push_u32(sp, self.elf_header.phnum); sp = push_u32(sp, @intFromEnum(AuxTag.AT_PHNUM)); - uart.print("at_phnum sp: {X}\n", .{sp}); // AT_PAGESZ sp = push_u32(sp, memory.KB4); sp = push_u32(sp, @intFromEnum(AuxTag.AT_PAGESZ)); - uart.print("at_pagesz sp: {X}\n", .{sp}); // AT_ENTRY sp = push_u32(sp, self.entrypoint); sp = push_u32(sp, @intFromEnum(AuxTag.AT_ENTRY)); - uart.print("at_entry sp: {X}\n", .{sp}); // AT_UID // TODO; let user specify UID sp = push_u32(sp, 0); sp = push_u32(sp, @intFromEnum(AuxTag.AT_UID)); - uart.print("at_uid sp: {X}\n", .{sp}); // AT_EUID // TODO; let user specify EUID sp = push_u32(sp, 0); sp = push_u32(sp, @intFromEnum(AuxTag.AT_EUID)); - uart.print("at_euid sp: {X}\n", .{sp}); // AT_GID // TODO; let user specify GID sp = push_u32(sp, 0); sp = push_u32(sp, @intFromEnum(AuxTag.AT_GID)); - uart.print("at_gid sp: {X}\n", .{sp}); // AT_EGID // TODO; let user specify EUID sp = push_u32(sp, 0); sp = push_u32(sp, @intFromEnum(AuxTag.AT_EGID)); - uart.print("at_egid sp: {X}\n", .{sp}); // AT_RANDOM sp = push_u32(sp, at_random_ptr); sp = push_u32(sp, @intFromEnum(AuxTag.AT_RANDOM)); - uart.print("at_random sp: {X}\n", .{sp}); // AT_EXECFN if (args.len != 0) { sp = push_u32(sp, arg_ptrs[0]); sp = push_u32(sp, @intFromEnum(AuxTag.AT_EXECFN)); } - uart.print("at_execfn sp: {X}\n", .{sp}); // env_p sp = push_u32(sp, 0); @@ -258,7 +226,6 @@ pub fn execute(self: *Program, pid: u24, args: []const []const u8, env: []const var i = env_ptrs.len; while (i > 0) : (i -= 1) sp = push_u32(sp, env_ptrs[i - 1]); } - uart.print("envp sp: {X}\n", .{sp}); // arg_v sp = push_u32(sp, 0); @@ -266,19 +233,9 @@ pub fn execute(self: *Program, pid: u24, args: []const []const u8, env: []const var i = arg_ptrs.len; while (i > 0) : (i -= 1) sp = push_u32(sp, arg_ptrs[i - 1]); } - uart.print("argv sp: {X}\n", .{sp}); // arg_c sp = push_u32(sp, args.len); - uart.print("argc sp: {X}\n", .{sp}); - - // sp = align_down(sp, 8); - // uart.print("final sp: {X}\n", .{sp}); - - var it = sp; - while (it < self.stack_pointer) : (it += 4) { - uart.print("0x{X:8>0}: {X}\n", .{ it, pi.mem.get_u32(@ptrFromInt(it)) }); - } var psr = pi.PSR.get_c(); psr.mode = .User; @@ -291,13 +248,6 @@ pub fn execute(self: *Program, pid: u24, args: []const []const u8, env: []const .psr = psr, }; - uart.print("switching into!\n", .{}); - uart.print("VA(0x{X}) -> PA(0x{X})\n", .{ self.entrypoint, memory.translate(self.entrypoint) catch 0 }); - - for (0..16) |idx| { - uart.print("{X:8>0}\n", .{pi.mem.get_u32(@ptrFromInt(self.entrypoint + idx * 4))}); - } - pi.switching.restore_state_privileged(&registers); } diff --git a/sylveos/memory.zig b/sylveos/memory.zig @@ -190,7 +190,6 @@ pub fn get_allocator() std.heap.FixedBufferAllocator { const heap = Region.heap(); const fba: std.heap.FixedBufferAllocator = .init(@ptrCast(heap.raw[MB..heap.size])); - uart.print("Main alloc on 0x{X} (size: {Bi})\n", .{ @intFromPtr(fba.buffer.ptr), heap.size - MB }); return fba; } @@ -199,7 +198,6 @@ pub fn get_pt_allocator() std.heap.FixedBufferAllocator { const p_pt = Region.process_page_table(); const fba: std.heap.FixedBufferAllocator = .init(@ptrCast(p_pt.raw[0..p_pt.size])); - uart.print("PT alloc on 0x{X} (size: {Bi})\n", .{ @intFromPtr(fba.buffer.ptr), p_pt.size }); return fba; } diff --git a/sylveos/root.zig b/sylveos/root.zig @@ -3,6 +3,7 @@ const pi = @import("pi"); const memory = @import("./memory.zig"); const loader = @import("./loader.zig"); +const syscall = @import("./syscall.zig"); const hello_binary = @embedFile("./hello"); const uart = pi.devices.mini_uart; @@ -98,7 +99,7 @@ export fn abort() noreturn { } fn main() !void { - uart.print("Hello World from VM!\n", .{}); + interrupts.set_exception_handler(.SoftwareInterrupt, syscall.syscall_handler); var heap_fba = memory.get_allocator(); const heap_alloc = heap_fba.allocator(); @@ -108,9 +109,6 @@ fn main() !void { const pt = memory.get_page_table(); - // Just create a 1mb allocation we'll identity map - uart.print("page_table @ 0x{X}\n", .{@intFromPtr(pt.ptr)}); - var empty = try loader.init(pt_alloc, heap_alloc, pt, hello_binary); uart.print( \\Stack Pointer: {X:0>8} diff --git a/sylveos/syscall.zig b/sylveos/syscall.zig @@ -0,0 +1,50 @@ +const pi = @import("pi"); + +const interrupts = pi.interrupts; +const uart = pi.devices.mini_uart; + +pub fn syscall_handler(registers: interrupts.Registers, _: interrupts.ExceptionVector) void { + const n = registers.gp[7]; + + switch (n) { + // restart_syscall + 0 => {}, + // exit + 1 => { + const error_code = registers.gp[0]; + + uart.print("[syscall] exit({d})\n", .{error_code}); + pi.reboot(); + }, + // fork + 2 => {}, + // read + 3 => {}, + // write + 4 => { + const fd = registers.gp[0]; + const buffer: [*]u8 = @ptrFromInt(registers.gp[1]); + const count = registers.gp[2]; + + uart.print("[syscall] write({d}, 0x{X}, {d})\n", .{ fd, @intFromPtr(buffer), count }); + + // stdout + if (fd == 1) { + uart.print("{s}", .{buffer[0..count]}); + } + }, + // open + 5 => {}, + // close + 6 => {}, + // exit_group + 248 => {}, + // set_tid_address + 256 => {}, + // ARM_set_tls + 983045 => {}, + else => { + uart.print("Unhandled syscall: {d}\n", .{n}); + }, + } +}