From 6a5543bb8f1f535ca49737bcd7be0cafca3b2a08 Mon Sep 17 00:00:00 2001 From: hachem Date: Mon, 12 Oct 2026 23:08:48 +0200 Subject: feat: lib sea --- boot/boot.zig | 5 +- boot/elf.zig | 9 -- boot/fonts.zig | 11 -- bridge/hosts.zig | 50 +++--- build.zig | 321 +++++++++++++++++++++++++++----------- etc/lung | 79 ---------- etc/motd | 1 - etc/profile | 8 - fonts/acorn8.psf | Bin 2052 -> 0 bytes fonts/dejavu.ttf | Bin 8488 -> 0 bytes fonts/pearl8.psf | Bin 2052 -> 0 bytes fonts/sun16.psf | Bin 4100 -> 0 bytes fonts/terminess.ttf | Bin 9496 -> 0 bytes fonts/vga16.psf | Bin 4100 -> 0 bytes fonts/vga8.psf | Bin 2052 -> 0 bytes kernel/seed.rv | 10 ++ sysroot/etc/lung | 79 ++++++++++ sysroot/etc/motd | 1 + sysroot/etc/profile | 8 + sysroot/usr/include/fcntl.h | 12 ++ sysroot/usr/include/stddef.h | 9 ++ sysroot/usr/include/stdint.h | 10 ++ sysroot/usr/include/stdio.h | 15 ++ sysroot/usr/include/stdlib.h | 17 ++ sysroot/usr/include/string.h | 17 ++ sysroot/usr/include/sys/syscall.h | 34 ++++ sysroot/usr/include/unistd.h | 18 +++ sysroot/usr/lib/libc/crt0.c | 28 ++++ sysroot/usr/lib/libc/stdio.c | 211 +++++++++++++++++++++++++ sysroot/usr/lib/libc/stdlib.c | 185 ++++++++++++++++++++++ sysroot/usr/lib/libc/string.c | 92 +++++++++++ sysroot/usr/lib/libc/syscalls.c | 38 +++++ sysroot/usr/share/acorn8.psf | Bin 0 -> 2052 bytes sysroot/usr/share/dejavu.ttf | Bin 0 -> 8488 bytes sysroot/usr/share/pearl8.psf | Bin 0 -> 2052 bytes sysroot/usr/share/sun16.psf | Bin 0 -> 4100 bytes sysroot/usr/share/terminess.ttf | Bin 0 -> 9496 bytes sysroot/usr/share/vga16.psf | Bin 0 -> 4100 bytes sysroot/usr/share/vga8.psf | Bin 0 -> 2052 bytes user/calc.c | 24 ++- user/chat.c | 36 ++--- user/hexview.c | 93 ++++------- user/membrk.c | 51 +++--- user/primes.c | 28 ++-- user/save.c | 46 +++--- user/user.h | 309 ------------------------------------ 46 files changed, 1154 insertions(+), 701 deletions(-) delete mode 100644 boot/elf.zig delete mode 100644 boot/fonts.zig delete mode 100644 etc/lung delete mode 100644 etc/motd delete mode 100644 etc/profile delete mode 100644 fonts/acorn8.psf delete mode 100644 fonts/dejavu.ttf delete mode 100644 fonts/pearl8.psf delete mode 100644 fonts/sun16.psf delete mode 100644 fonts/terminess.ttf delete mode 100644 fonts/vga16.psf delete mode 100644 fonts/vga8.psf create mode 100644 sysroot/etc/lung create mode 100644 sysroot/etc/motd create mode 100644 sysroot/etc/profile create mode 100644 sysroot/usr/include/fcntl.h create mode 100644 sysroot/usr/include/stddef.h create mode 100644 sysroot/usr/include/stdint.h create mode 100644 sysroot/usr/include/stdio.h create mode 100644 sysroot/usr/include/stdlib.h create mode 100644 sysroot/usr/include/string.h create mode 100644 sysroot/usr/include/sys/syscall.h create mode 100644 sysroot/usr/include/unistd.h create mode 100644 sysroot/usr/lib/libc/crt0.c create mode 100644 sysroot/usr/lib/libc/stdio.c create mode 100644 sysroot/usr/lib/libc/stdlib.c create mode 100644 sysroot/usr/lib/libc/string.c create mode 100644 sysroot/usr/lib/libc/syscalls.c create mode 100644 sysroot/usr/share/acorn8.psf create mode 100644 sysroot/usr/share/dejavu.ttf create mode 100644 sysroot/usr/share/pearl8.psf create mode 100644 sysroot/usr/share/sun16.psf create mode 100644 sysroot/usr/share/terminess.ttf create mode 100644 sysroot/usr/share/vga16.psf create mode 100644 sysroot/usr/share/vga8.psf delete mode 100644 user/user.h diff --git a/boot/boot.zig b/boot/boot.zig index 6ead044..891def7 100644 --- a/boot/boot.zig +++ b/boot/boot.zig @@ -8,8 +8,9 @@ const pmm = @import("pmm.zig"); const heap = @import("heap.zig"); const vmm = @import("vmm.zig"); const user = @import("user.zig"); -const elf = @import("elf.zig"); -const fontdata = @import("fonts.zig"); +// fonts + compiled programs, generated from the filesystem by build.zig +const elf = @import("kasset"); +const fontdata = @import("kasset"); const keyboard = @import("keyboard.zig"); const timer = @import("timer.zig"); const sched = @import("sched.zig"); diff --git a/boot/elf.zig b/boot/elf.zig deleted file mode 100644 index 32acbfe..0000000 --- a/boot/elf.zig +++ /dev/null @@ -1,9 +0,0 @@ -pub const Program = struct { name: []const u8, bytes: []const u8 }; -pub const programs = [_]Program{ - .{ .name = "hexview", .bytes = @embedFile("user_hexview") }, - .{ .name = "calc", .bytes = @embedFile("user_calc") }, - .{ .name = "primes", .bytes = @embedFile("user_primes") }, - .{ .name = "save", .bytes = @embedFile("user_save") }, - .{ .name = "chat", .bytes = @embedFile("user_chat") }, - .{ .name = "membrk", .bytes = @embedFile("user_membrk") }, -}; diff --git a/boot/fonts.zig b/boot/fonts.zig deleted file mode 100644 index 5db8123..0000000 --- a/boot/fonts.zig +++ /dev/null @@ -1,11 +0,0 @@ -// js loading fonts from host disk -pub const Font = struct { name: []const u8, bytes: []const u8 }; -pub const fonts = [_]Font{ - .{ .name = "vga16.psf", .bytes = @embedFile("font_vga16") }, - .{ .name = "vga8.psf", .bytes = @embedFile("font_vga8") }, - .{ .name = "sun16.psf", .bytes = @embedFile("font_sun16") }, - .{ .name = "acorn8.psf", .bytes = @embedFile("font_acorn8") }, - .{ .name = "pearl8.psf", .bytes = @embedFile("font_pearl8") }, - .{ .name = "dejavu.ttf", .bytes = @embedFile("font_dejavu") }, - .{ .name = "terminess.ttf", .bytes = @embedFile("font_terminess") }, -}; diff --git a/bridge/hosts.zig b/bridge/hosts.zig index caf8b0d..5148ca8 100644 --- a/bridge/hosts.zig +++ b/bridge/hosts.zig @@ -8,31 +8,11 @@ const Data = convert.Data; const argInt = convert.argInt; const emit = serial.emit; -// gils shit -const Script = struct { name: []const u8, src: []const u8 }; -const scripts = [_]Script{ - .{ .name = "ls", .src = @embedFile("k_gils_ls") }, - .{ .name = "tree", .src = @embedFile("k_gils_tree") }, - .{ .name = "cat", .src = @embedFile("k_gils_cat") }, - .{ .name = "rm", .src = @embedFile("k_gils_rm") }, - .{ .name = "mkdir", .src = @embedFile("k_gils_mkdir") }, - .{ .name = "touch", .src = @embedFile("k_gils_touch") }, - .{ .name = "cp", .src = @embedFile("k_gils_cp") }, - .{ .name = "mv", .src = @embedFile("k_gils_mv") }, - .{ .name = "wc", .src = @embedFile("k_gils_wc") }, - .{ .name = "head", .src = @embedFile("k_gils_head") }, - .{ .name = "tail", .src = @embedFile("k_gils_tail") }, -}; - -// /etc/ shit -const EtcFile = struct { name: []const u8, src: []const u8 }; -const etc_files = [_]EtcFile{ - .{ .name = "motd", .src = @embedFile("k_etc_motd") }, - .{ .name = "profile", .src = @embedFile("k_etc_profile") }, - .{ .name = "lung", .src = @embedFile("k_etc_lung") }, -}; +const basset = @import("basset"); +const scripts = basset.gils; +const etc_files = basset.etc; +const include_files = basset.include; -// the actual framebuffer, the data layout feels pretty self explanatory pub const Fb = struct { ptr: [*]u8, width: usize, @@ -451,6 +431,25 @@ fn hostEtcSrc(args: []const revo.Value, vm: *revo.VM) anyerror!HostResult { return HostResult.data(try vm.ownValueString(etc_files[i].src)); } +// pass shit to revo +fn hostIncCount(_: []const revo.Value, _: *revo.VM) anyerror!HostResult { + return HostResult.data(Data.new.num(include_files.len)); +} + +// pass shit to revo +fn hostIncName(args: []const revo.Value, vm: *revo.VM) anyerror!HostResult { + const i = argInt(usize, args, 0) orelse return HostResult.other("inc_name: bad index"); + if (i >= include_files.len) return HostResult.other("inc_name: out of range"); + return HostResult.data(try vm.ownValueString(include_files[i].name)); +} + +// pass shit to revo +fn hostIncSrc(args: []const revo.Value, vm: *revo.VM) anyerror!HostResult { + const i = argInt(usize, args, 0) orelse return HostResult.other("inc_src: bad index"); + if (i >= include_files.len) return HostResult.other("inc_src: out of range"); + return HostResult.data(try vm.ownValueString(include_files[i].src)); +} + // pass shit to revo fn hostEvalScript(args: []const revo.Value, vm: *revo.VM) anyerror!HostResult { const sid = args[0].asString() orelse return HostResult.other("eval_script: not a string"); @@ -517,6 +516,9 @@ pub fn passShitToRevo(vm: *revo.VM) !void { try vm.registerGlobal("etc_count", try vm.installHost("etc_count", define(&[_]T{}, hostEtcCount))); try vm.registerGlobal("etc_name", try vm.installHost("etc_name", define(&[_]T{.number}, hostEtcName))); try vm.registerGlobal("etc_src", try vm.installHost("etc_src", define(&[_]T{.number}, hostEtcSrc))); + try vm.registerGlobal("inc_count", try vm.installHost("inc_count", define(&[_]T{}, hostIncCount))); + try vm.registerGlobal("inc_name", try vm.installHost("inc_name", define(&[_]T{.number}, hostIncName))); + try vm.registerGlobal("inc_src", try vm.installHost("inc_src", define(&[_]T{.number}, hostIncSrc))); try vm.registerGlobal("alloc_contig", try vm.installHost("alloc_contig", define(&[_]T{.number}, hostAllocContig))); try vm.registerGlobal("blit_str", try vm.installHost("blit_str", define(&[_]T{ .number, .string }, hostBlitStr))); try vm.registerGlobal("phys_to_str", try vm.installHost("phys_to_str", define(&[_]T{ .number, .number }, hostPhysToStr))); diff --git a/build.zig b/build.zig index e625977..4978296 100644 --- a/build.zig +++ b/build.zig @@ -1,136 +1,275 @@ const std = @import("std"); -// the gils coreutils -const gils_tools = .{ "gils", "ls", "tree", "cat", "rm", "mkdir", "touch", "cp", "mv", "wc", "head", "tail", "ed" }; +const boot_gils = [_][]const u8{ "gils", "ed" }; + +const user_cc = [_][]const u8{ + "zig", "cc", + "-target", "x86_64-freestanding", + "-ffreestanding", "-nostdlib", + "-static", "-no-pie", + "-fno-stack-protector", "-fno-sanitize=all", + "-Wall", "-Wextra", + "-Werror", "-Wpedantic", + "-I", "sysroot/usr/include", + "-Wl,-T,user/link.ld", "-Wl,--build-id=none", + "-o", +}; pub fn build(b: *std.Build) void { - // Default to ReleaseSafe because Debug pulls Zig's UBSan runtime and other - // sanitization, which needs f128/SSE ops, which i don't provide. const optimize = b.option(std.builtin.OptimizeMode, "optimize", "optimize mode") orelse .safe; + const target = kernelTarget(b); + + const kernel = buildKernel(b, target, optimize); + kernel.root_module.addImport("kasset", buildKernelAssets(b, target, optimize)); + kernel.root_module.addImport("bridge", buildBridge(b, target, optimize)); + + b.installArtifact(kernel); +} - // The kernel must NOT touch SSE/MMX/AVX until it has enabled them itself, so - // I strip those features and let the compiler use a soft-float ABI - // `code_model = .kernel` keeps relocations valid for the higher-half load - // address in boot/linker.ld. - // - // In other words. Going raw baby +fn kernelTarget(b: *std.Build) std.Build.ResolvedTarget { var query: std.Target.Query = .{ .cpu_arch = .x86_64, .os_tag = .freestanding, .abi = .none, }; - const Feature = std.Target.x86.Feature; query.cpu_features_sub.addFeature(@backingInt(Feature.mmx)); query.cpu_features_sub.addFeature(@backingInt(Feature.avx)); query.cpu_features_sub.addFeature(@backingInt(Feature.avx2)); + return b.resolveTargetQuery(query); +} - const target = b.resolveTargetQuery(query); +fn kernelModule( + b: *std.Build, + target: std.Build.ResolvedTarget, + optimize: std.builtin.OptimizeMode, + root: std.Build.LazyPath, +) *std.Build.Module { + return b.createModule(.{ + .root_source_file = root, + .target = target, + .optimize = optimize, + .code_model = .kernel, + .red_zone = false, + .single_threaded = true, + .link_libc = false, + }); +} +fn buildKernel( + b: *std.Build, + target: std.Build.ResolvedTarget, + optimize: std.builtin.OptimizeMode, +) *std.Build.Step.Compile { const kernel = b.addExecutable(.{ .name = "revel", - .root_module = b.createModule(.{ - .root_source_file = b.path("boot/boot.zig"), - .target = target, - .optimize = optimize, - .code_model = .kernel, - .red_zone = false, - .single_threaded = true, - .link_libc = false, - }), + .root_module = kernelModule(b, target, optimize, b.path("boot/boot.zig")), }); kernel.entry = .{ .symbol_name = "_start" }; kernel.pie = false; kernel.setLinkerScript(b.path("boot/linker.ld")); + return kernel; +} + +fn buildBridge( + b: *std.Build, + target: std.Build.ResolvedTarget, + optimize: std.builtin.OptimizeMode, +) *std.Build.Module { + const bridge = kernelModule(b, target, optimize, b.path("bridge/bridge.zig")); - // the big guns - const revo_dep = b.dependency("revo", .{ + const revo = b.dependency("revo", .{ .target = target, .optimize = optimize, .features = "regex", - }); - const revo_mod = revo_dep.module("revo"); - + }).module("revo"); var visited: std.AutoHashMap(*std.Build.Module, void) = .init(b.allocator); defer visited.deinit(); - kernelize(revo_mod, &visited); + kernelize(revo, &visited); + bridge.addImport("revo", revo); - // the thin guns - const bridge_mod = b.createModule(.{ - .root_source_file = b.path("bridge/bridge.zig"), - .target = target, - .optimize = optimize, - .code_model = .kernel, - .red_zone = false, - .single_threaded = true, - .link_libc = false, - }); - bridge_mod.addImport("revo", revo_mod); - inline for (.{ - .{ "k_font", "kernel/font.rv" }, - .{ "k_console", "kernel/console.rv" }, - .{ "k_vmm", "kernel/vmm.rv" }, - .{ "k_fs", "kernel/fs.rv" }, - .{ "k_io", "kernel/io.rv" }, - .{ "k_vfs", "kernel/vfs.rv" }, - .{ "k_seed", "kernel/seed.rv" }, - .{ "k_proc", "kernel/proc.rv" }, - .{ "k_ttf", "kernel/ttf.rv" }, - .{ "k_shell", "kernel/shell.rv" }, - .{ "k_tty", "kernel/tty.rv" }, - .{ "k_input", "kernel/input.rv" }, - .{ "k_main", "kernel/main.rv" }, - }) |e| { - bridge_mod.addAnonymousImport(e[0], .{ .root_source_file = b.path(e[1]) }); + for (scan(b, "kernel", ".rv")) |file| { + const name = stripExt(file); + bridge.addAnonymousImport(b.fmt("k_{s}", .{name}), .{ + .root_source_file = b.path(b.fmt("kernel/{s}", .{file})), + }); + } + for (boot_gils) |name| { + bridge.addAnonymousImport(b.fmt("k_gils_{s}", .{name}), .{ + .root_source_file = b.path(b.fmt("gils/{s}.rv", .{name})), + }); } - // load gils - inline for (gils_tools) |g| { - bridge_mod.addAnonymousImport("k_gils_" ++ g, .{ .root_source_file = b.path("gils/" ++ g ++ ".rv") }); + bridge.addImport("basset", buildBridgeAssets(b, target, optimize)); + return bridge; +} + +fn buildBridgeAssets( + b: *std.Build, + target: std.Build.ResolvedTarget, + optimize: std.builtin.OptimizeMode, +) *std.Build.Module { + var embeds = Embeds{ .b = b }; + var src: []const u8 = + \\// generated by build.zig + \\pub const Blob = struct { name: []const u8, src: []const u8 }; + \\ + \\ + ; + + src = b.fmt("{s}pub const gils = [_]Blob{{\n", .{src}); + for (scan(b, "gils", ".rv")) |file| { + const name = stripExt(file); + if (contains(&boot_gils, name)) continue; + const key = b.fmt("k_gils_{s}", .{name}); + embeds.add(key, b.path(b.fmt("gils/{s}", .{file}))); + src = b.fmt("{s} .{{ .name = \"{s}\", .src = @embedFile(\"{s}\") }},\n", .{ src, name, key }); } - // /etc/ bullshit - inline for (.{ "motd", "profile", "lung" }) |name| { - bridge_mod.addAnonymousImport("k_etc_" ++ name, .{ .root_source_file = b.path("etc/" ++ name) }); + src = b.fmt("{s}}};\n\npub const etc = [_]Blob{{\n", .{src}); + for (scan(b, "sysroot/etc", "")) |file| { + const key = b.fmt("k_etc_{s}", .{sanitize(b, file)}); + embeds.add(key, b.path(b.fmt("sysroot/etc/{s}", .{file}))); + src = b.fmt("{s} .{{ .name = \"{s}\", .src = @embedFile(\"{s}\") }},\n", .{ src, file, key }); } - kernel.root_module.addImport("bridge", bridge_mod); - - inline for (.{ - .{ "font_vga16", "fonts/vga16.psf" }, - .{ "font_vga8", "fonts/vga8.psf" }, - .{ "font_sun16", "fonts/sun16.psf" }, - .{ "font_acorn8", "fonts/acorn8.psf" }, - .{ "font_pearl8", "fonts/pearl8.psf" }, - .{ "font_dejavu", "fonts/dejavu.ttf" }, - .{ "font_terminess", "fonts/terminess.ttf" }, - }) |e| { - kernel.root_module.addAnonymousImport(e[0], .{ .root_source_file = b.path(e[1]) }); + src = b.fmt("{s}}};\n\npub const include = [_]Blob{{\n", .{src}); + for (headers(b)) |path| { + const key = b.fmt("k_inc_{s}", .{sanitize(b, path)}); + embeds.add(key, b.path(b.fmt("sysroot/usr/include/{s}", .{path}))); + src = b.fmt("{s} .{{ .name = \"{s}\", .src = @embedFile(\"{s}\") }},\n", .{ src, path, key }); } - inline for (.{ "hexview", "calc", "primes", "save", "chat", "membrk" }) |prog| { - const cc = b.addSystemCommand(&.{ - "zig", "cc", - "-target", "x86_64-freestanding", - "-ffreestanding", "-nostdlib", - "-static", "-no-pie", - "-fno-stack-protector", "-fno-sanitize=all", - "-Wall", "-Wextra", - "-Werror", "-Wpedantic", - "-Wl,-T,user/link.ld", "-Wl,--build-id=none", - "-o", - }); - const prog_elf = cc.addOutputFileArg(prog ++ ".elf"); - cc.addFileArg(b.path("user/" ++ prog ++ ".c")); - cc.addFileInput(b.path("user/user.h")); - cc.addFileInput(b.path("user/link.ld")); - kernel.root_module.addAnonymousImport("user_" ++ prog, .{ .root_source_file = prog_elf }); + src = b.fmt("{s}}};\n", .{src}); + const mod = kernelModule(b, target, optimize, b.addWriteFiles().add("basset.zig", src)); + embeds.apply(mod); + return mod; +} + +fn buildKernelAssets( + b: *std.Build, + target: std.Build.ResolvedTarget, + optimize: std.builtin.OptimizeMode, +) *std.Build.Module { + var embeds = Embeds{ .b = b }; + var src: []const u8 = + \\// generated by build.zig + \\pub const Blob = struct { name: []const u8, bytes: []const u8 }; + \\ + \\ + ; + + src = b.fmt("{s}pub const fonts = [_]Blob{{\n", .{src}); + for (scan(b, "sysroot/usr/share", "")) |file| { + const key = b.fmt("font_{s}", .{sanitize(b, file)}); + embeds.add(key, b.path(b.fmt("sysroot/usr/share/{s}", .{file}))); + src = b.fmt("{s} .{{ .name = \"{s}\", .bytes = @embedFile(\"{s}\") }},\n", .{ src, file, key }); } + src = b.fmt("{s}}};\n\npub const programs = [_]Blob{{\n", .{src}); + for (scan(b, "user", ".c")) |file| { + const name = stripExt(file); + const key = b.fmt("user_{s}", .{name}); + embeds.add(key, compileProgram(b, name)); + src = b.fmt("{s} .{{ .name = \"{s}\", .bytes = @embedFile(\"{s}\") }},\n", .{ src, name, key }); + } + src = b.fmt("{s}}};\n", .{src}); - b.installArtifact(kernel); + const mod = kernelModule(b, target, optimize, b.addWriteFiles().add("kasset.zig", src)); + embeds.apply(mod); + return mod; +} + +fn compileProgram(b: *std.Build, name: []const u8) std.Build.LazyPath { + const cc = b.addSystemCommand(&user_cc); + const elf = cc.addOutputFileArg(b.fmt("{s}.elf", .{name})); + + cc.addFileArg(b.path(b.fmt("user/{s}.c", .{name}))); + for (scan(b, "sysroot/usr/lib/libc", ".c")) |unit| + cc.addFileArg(b.path(b.fmt("sysroot/usr/lib/libc/{s}", .{unit}))); + + for (headers(b)) |path| + cc.addFileInput(b.path(b.fmt("sysroot/usr/include/{s}", .{path}))); + cc.addFileInput(b.path("user/link.ld")); + + return elf; +} + +fn scan(b: *std.Build, dir_path: []const u8, ext: []const u8) [][]const u8 { + const io = b.graph.io; + var dir = std.Io.Dir.cwd().openDir(io, dir_path, .{ .iterate = true }) catch |err| + std.debug.panic("build: cannot scan {s}: {s}", .{ dir_path, @errorName(err) }); + defer dir.close(io); + + var buf: [128][]const u8 = undefined; + var count: usize = 0; + var it = dir.iterate(); + while (it.next(io) catch @panic("build: dir iterate failed")) |entry| { + if (entry.kind != .file) continue; + if (!std.mem.endsWith(u8, entry.name, ext)) continue; + buf[count] = b.allocator.dupe(u8, entry.name) catch @panic("OOM"); + count += 1; + } + + const names = b.allocator.dupe([]const u8, buf[0..count]) catch @panic("OOM"); + std.mem.sort([]const u8, names, {}, lessThan); + return names; +} + +fn headers(b: *std.Build) [][]const u8 { + var buf: [128][]const u8 = undefined; + var count: usize = 0; + for (scan(b, "sysroot/usr/include", ".h")) |name| { + buf[count] = name; + count += 1; + } + for (scan(b, "sysroot/usr/include/sys", ".h")) |name| { + buf[count] = b.fmt("sys/{s}", .{name}); + count += 1; + } + return b.allocator.dupe([]const u8, buf[0..count]) catch @panic("OOM"); +} + +fn lessThan(_: void, a: []const u8, c: []const u8) bool { + return std.mem.lessThan(u8, a, c); +} + +fn stripExt(name: []const u8) []const u8 { + const dot = std.mem.lastIndexOfScalar(u8, name, '.') orelse return name; + return name[0..dot]; +} + +fn sanitize(b: *std.Build, name: []const u8) []const u8 { + const out = b.allocator.dupe(u8, name) catch @panic("OOM"); + for (out) |*ch| { + if (!std.ascii.isAlphanumeric(ch.*)) ch.* = '_'; + } + return out; +} + +const Embeds = struct { + b: *std.Build, + keys: [128][]const u8 = undefined, + paths: [128]std.Build.LazyPath = undefined, + count: usize = 0, + + fn add(self: *Embeds, key: []const u8, path: std.Build.LazyPath) void { + self.keys[self.count] = key; + self.paths[self.count] = path; + self.count += 1; + } + + fn apply(self: *Embeds, module: *std.Build.Module) void { + for (0..self.count) |i| + module.addAnonymousImport(self.keys[i], .{ .root_source_file = self.paths[i] }); + } +}; + +fn contains(haystack: []const []const u8, needle: []const u8) bool { + for (haystack) |item| + if (std.mem.eql(u8, item, needle)) return true; + return false; } -// force a module and everything it imports to the kernel's codegen settings fn kernelize(mod: *std.Build.Module, visited: *std.AutoHashMap(*std.Build.Module, void)) void { if (visited.contains(mod)) return; visited.put(mod, {}) catch @panic("OOM building module graph"); diff --git a/etc/lung b/etc/lung deleted file mode 100644 index 54c10ab..0000000 --- a/etc/lung +++ /dev/null @@ -1,79 +0,0 @@ -(((())))11111{{{}}}}}}[[[]]]]]]]-------_______)juvvvvvvvvvvvvvvvvvvvvvuuuuuuuuuuuuuvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvccccccvvvvvvccccccccccccccccccccccccccvvvvvvuuuuuuuuuuuuuuuunnnnnnnnnnnxxxxxxxxxxxxxxxrrrrrrrrrrrrrrrrrrrrrrrrjjjjjjjjjffjf)][}} -||(((()))11111{{{{}}}}}[[[]]]]]]????----______-{tuuuuuuvvvvvvvvvvvvvvuuuuuuuuuuuuuuvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvccccccvvvvvvcccccccccccccccccccccccvvvvvvvvvuuuuuuuuuuuuunnnnnnnnnnnxxxxxxxxxxxxxxrrrrrrrrrrrrrrrrrrrjjjjjjjjjjjjjjjjjjff/{-_-][ -|||||(((()))111111{{}}}[[[[[[]]]]]??----________[fnuuuuuuuuuuuuuvvvvvvuuuuuuuuuuuuuvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvcccccccccccccccccccccccccvvvccccccvvvvvvvvvuuuuuuuuuunnnnnnnnnnnnnnxxxxxxrrrrrrrrrrrrrrjjjjjjjjjrjjjjjjjjjjjjjjjjjjjjffft)~+[{{1 -\\\|||((())))1111111{{{}}[[[[[]]]]??----_________]|xuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuvvvvvvvvvvvvvvvvvvvvvcccccccccccccccccccccccccvvvvvvvvvuuuuuuuuuuuuuuuunnnnnnnnnnnnnxxxxxxxxrrrrrrrrrrrrrrrjjjjjjjjjjjjjjjjjjjjjjjjjjjjjffftf\}<+{))) -\\\\\||||(()))1111111{{{}}}}[[[[]]??----________+_?(ruuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuvvvvvvvvvvvvvvvvvvvvcccccccccccccccccccccvvvvvuuunnnnnnuuuuuuuuuuuuunnnnnnnnnnnnnnnxxxxxxrrrrrrrrrrrrrjjjjjjjjjjjjjjjjjfffffffffffjjjffffft/{~I~{||( -/\\\\\\||((())))111111{{{}}}[[[[]]??-----_____+++++_1fnnnuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuvuvvvvvvvvvvvvvcvvvvvvvvvvuuuuvvvvvuuuuunnnnnnnnnnnnnnnnnnnnnnnnnnnnnnxxxxxxxxxxxxrrrrrjjjjjjjjjjjjjjjjjjjjjjjjffffffffffffffffffftt\(]+<~+?[[}} -ttttt//////\\|||((()))))111{}}}}}[[]]]?----__+++_++++~~~-(fxxxxnnnnnnnnnnnnnnnnnnnnnxxxnnnnunnnnnuuuuuuuuuuuuuunxjjjjjfjjft/\|||(()))(\//\\\|\||\\///\|(1}[[[}{1)((((|/tfjjjjjjjjjjjjjjjjjjjjjjjjjjffffffffffffffftttt|(1}[]][1\//////)-<___[1{{{{ -fttttttt///\\\\|||((())))111{{{}}[[[]]?---___+++_++~~~<<>~{frxxxxxxxxxxxxxnnnnnnnnnnxxxxnnnnnnnnnnunnnnnxxxxrjjft/\\\\||(1{}}}}}}}}}}?__]}}}}111{{1)1[-~>iii!!ii~_?}{1(|\\ttfjjjjjjjjjjjfffffffffffffffffffffftfftt|}-+<>!I;,^`:>_?[1{?__+_]))((() -jffffttt//////\\\|||(((())11{{{}}}[[]]?---___+++_+~~~<<>ii<]/rrxrrxxxxxxxxxxxxxxxxxxnnnnnnnnnnnnnnnnnxxrrjjffttt//\(1}?~iI:,,,"""""""^`''^,,I<_--_++>I,`. .'`^``^,l+[(\/tttffffjjjjjffffffffttttftttttfffftttt\[~><<iiii-|jrjrrrrrrrrrxxxxxxxxxxxxxxxxnnnxnnnnnnxrrjjtt/\\|(1{]_!,' .''.'. ..'`:<[(/tttttffffffffttttttttttttttttttttttt(_>!!lI:` .''''"I<_[{)((((( -rrjjjjffttttt////\\\||||(())111{{}}[[]]]?---___++~~~<<<>i!!!!+(tjjjrrrrrrrrrrrrrxxxxxxxxxxxxxxxxxrrrrjft/\||(1}]_i" .`:-)\///ttftfftttttttttttttttt/////////(-l``^^`. '",",:l>ii!!!!!>{tjjjjrrrrrrrrrrrrrxrrrrrrrrrrrjjjfftt/\|))1{[-i;' . .,-(\\//tttttttttttt////////\\\\\\\\\(?: .. "i>i!!i+?}{{1111111 -xxrrrrrjjjffttt////\\\||||(())11{{}}[[]]]??--__++~~<<>>i!!!!lll<[tjfffffffffffffffffjjjjjjjjjfftt/||())1}[?+l` ...'l?(\\//tttt/////////\\\\\\\\|||||\()?i:````^:!+?[]<-]{{{1111111 -xxxxrrrjjjfffttttt//\\|||||(())11{{}[[[]]]?--___+~<<>>i!!!lllIII!](ttttttttttttttttffffffffftt//\|)))1{[-~l" '. '~1\\\////\\\\\\\||||||||(((((((((((()111111111}+ll<~+?]]][[}}}}}} -xxxxrrrrjjjjffttttt//\\\\||||()111{}}}[]]]?--__+++~<>ii!!!llII;;::-)///////tttttttttttttt////\|(()11}?ii!!!lIII;:,,,>}|\\\\\\\\//////////\\|||(()){]_i:"' .l-1)(|||((((|||||||(((((()))))))))))1111{[I,:<[[[}}{}[]---- -nnxxxxxxrrrjjfffftttt///\\\||(()111{{}[[]]]??--_++~>>ii!!!llI;;:,"",i[(|||||\\\\\\\\///\\|((((1}?I"' .l-}11))))))))))))))111111{{{{{{{{{{{}?>llI, ,-[}}}}}}}}}}[[[ -unnnxxxxxrrrrjjjjjfttttt//\\||||()1{{{}}[]]]?--_+~~I"' ;+[{1111111111111111{{{{{{{{{{}}}}?>!!i!!!!~[}}}}}}}}}}}[[[ -unnnnxxxxxrrrrrrjjfttttt//\\\|||()11{{{}[]]]?--_+~~l!>_-?--?][}[[[[}}}}}}[[[ -uununxxxxxxrrrrrjjfftttt///\\\||()11{{{}[]]]?--__+~;,I!<_-?][[[[[[[[[[[[[[[[[[[ -uuuuunxxxxxxxrrrrjjffffttt//\\\|(()1{{{}}[[]??--_+~l". .`",:;IIIIlll!!!!lI;,,,,,,::;IIII:"` `>-][}}}}}}}[[[[[[[[[[[]->:^;>_-____--???]]]]]]]]]]]]]]] -vuuuuunnnxxxxrrrrrjjfffttt//\\\||()11{{}}[[]]??-_+~<<~~~~++++~<>i>>>>><<<>>>>il;" `!-]][[[[[[[]]]?_+++~iII!!;l~]]]?-_______----??]]]]]]]] -vvvvuuunnxxxxxxrrrjjffftttt/\\\\|(()111{}}[[]]?-_+~~>i!!lII;::,,,"""^'.... `!_---?-<~~+++_---?????????--_++~~<<>i!I:. .I~???]]]][]]_>;":l>~+--+!l>-?]?????--_++___---??????? -vvvvuuunnnnnnxxxrrjjffftttt/\\\\||())11{}}[[]]?-_+~~>i!!lI;;:,,,""""^`'... 'I+--_>lIIl!I,`. .. `,;!>><~~~+_-?]]]]]]]]]]]]?--_+++~<<>!l;` ,<+___~i!!lI;;:,,"^^^^^^``'.. .:<+~!!!!!l;"^`' .`' .`,;l><~+++__-][[[[[[[[[[]]]]]???-_+~~<<<+_-???????????_>I;l<-???????--------------- -zcccvvvuunnnxxxxrrrjjjjfftttt///\\|(()1{}}[[[]?-_+~<>i!!lI;:,,,"^^^^^^^^^````^:>~il,' "l<~_-----??????????-_+-------------------------- -zzccvvvuuunnxxxxxxrrjjjfftttt///\\\|()11}}}[[]]?_+~i!llI;::,,"""^^^^^",:;Il>~<+____--??][]]]][[[[}}[[[[[]?--_+~~+++_____________________------------------ -zXzzcvvvvuuunnnnnxrrrjjjftttt///\\\|()11{}}[[[]?-+~<>i!lI;;::,,""^"^^^",::;l~__>>i!I;:"^ .. .`,I!><~+-??][[[[[}}[[[[[[[[}}}}[[[[]]?-__~>i!;^ ."l<++++_________________________----------_-- -zzzzzccvvuuunnnxxxrrrrrjffffttt/\\\|()11{}}[[]]--+++~>i!lI;::,,,,,,,:;l!lli-]?+iI::!~-??-+>lI,"` .^:I!>~+_?][[[}}{{{{{{{{{}}}}{{{{{{{{}[[]]?_+ii!llI;,,::Il!iii!i_??_>I,":>-[[[?+>lI,' '";l>~-??]}}}{{1)))(()))111111))))))11{{{}[]-_~>l" `I<~~~++++++++++++++++++++++______________- -YXXXzccccvuunnnxxxrrrrrjjfffttt///\\()11{}}[[]?_+~~~~~<>ii!!!I:,:;!iiii>+--_+>I;:;i-}1{{]_>>iii!l!!IIl><<<<+_?]?-_>l;;l+{)(1[->I:,"^' .'`",l>~-?[{)(||\\\\\\\\\|||((())111{[?_+>ii!!lllllll!i<_??]]]-+~>I;!i>-)(}_ili<>l,' .''' '^^^`'. ^l~?{(||||||((((){[-~~<<<>!lI;;::"`. ^l<<~~~~~~~~~~~~~~~~~~~++++++____------- -YYXXXXzcccvuuunnxxxrrrrjjffffttt//\\|()1{}[[]]-_+~<>iiiii!I;;Ill!!>+-?]]_~iI;",l><~--<<+_~i;"`'''`";;,' '^,:;;;Il!!lI:^`^"l<-]{1)((()){}]_<;^. `I><<<<<<<<<<<<<~~~~~~~+++++__--------- -YYXXXXzzccvuuuunxxxrrrrjjffffftt//\\|()1{}[]??-_+~~~<<<><>!IIIl!>+_?]?-~>illI,"Ili<-[[]]_!;,:;I;,"";;:' .`"IllIl<+?[{1))11{}[?_>I"^^""^^^""",:;;;:,". ^li><<<<<<<<<<<<~<~~~~~++++___-------- -UUYYXXzzzcvuuuunxxxrrrrjjffffftt//\\|()1{}[]]?-_+++~++~<~>!llllll;:I>_})){?<<~>;,,II:` ",. +{]+i!l!<-[{1))11}]_>;:Il!l:' .`. :!i>>>>>>>>>>>><<<<<~~~~++___-------? -JJUYXXzzzcvuuuunxxxrrrrjjffffftt//\\|()1{}[[]?--____+~~+~~<>i!!l;:;:,"",;lIII:,;>?}}-~~?{1{]___+iI:ll:` '`^""^'.^I+?_[}{11}?<;,;>+?; :i; "I!iiiiiiiiiiiiii>>><<~~~++__------?? -JJUYYXXzzzcvuuunxxxrrrrjjffffftt//\\|()1{}[[]?----???-+~~~~~<>>!I;III:",;I;:;:::Ii~+]1\fff\11{}?+!Iiil" '^:Ili>><+---_+~<<>!!>>il:,,:I;,`.. . "I!i!i!!!!!!!!!!!!!i><<<~++_----???? -JJUUUXXXzzcvuuunxxxrrrrjjffffftt//\\|()1{}[[]?------??---_+<>>>ilIl!!lI;;;;;;:,,"I-{\jxxrj/())1}-<~+_--??-_+~>!I;::I>-]][_><~+_--?--+~>!l;:"` .`' ^;!!!!!!llII;;;;;;;;Illi><+_--???]]] -JJJUUYXXzzcvuuunxxxrrrrjjffffftt//\\|(11{}[[?--__++~~~~~++~>!!lllIIlI;,"^^^"""^``:+1/jnnxjf\()11}-<~_]]]_++_?][[]]?-+_--?????] -CJJJUYXXzzcvuuunxxxrrrrjjffffftt//\\()11}[[]?-_++~<>ii!!!!!lI;:,,"^^``'....'``'''"<1/rnnnxf/|(()1[??+iI,^. .`,Ii<_-?[}}}}]??_~>lllII!+][[[-il" '````.'.`,"'..':!>~>I,",^ 'i+-?????? -CCJJUYXXzzcvuuunxxxrrrrjjffffftt//\\()1{}[[]?-__+~?)rnnnxf/\\\()1{}?+>I:. .'":li<+-?[[[[[]??_~>!!ll!>-[}}[-~!I;Ili~_-][{111111{[?_~>l" ."l, .l?]_I . I<_-?---- -CCJUUYYXXzzvuuunxxxxrrjjjfffftt///\|(11{}[[]?___+~>i!lI;;::,""^``'... ^ll>1jxxxt)(tt/|()){?_>:. '`":Ii<+_???]]][[]?_ -CCCJUYYXXzzvuuunxxxxrrjjjfffftt///\|(11{}[[]?___+~>i!lI;;:,,"^^``'''....... .`^.^~)fff(-?\t///\(){?>:'..'^",I!>~~+_-][}{{{}]+>!l!>_[}{{}?+iI;I>~?[{1{}}}}}[]]?_+> -LCJJUYYXXzzvuuunxxxxrrjjjfffftttt/\|()1{}[[]?_+~~>i!lI;:::,""^`''''.....''. .'' l[(||)--)\///\||)]<:'..'`^";l!ii<+-]}{{1)1[+iI!<_?[{{{{[-<~~ -LCJJUYYXXzzvuuunxxxxrrjjjfffftt//\||)1{}}[]?-++<~_][{{1)1]l,,>?{111{{}[]?-+~i!lII;:::,"^`'''.....''`' ^,;>-]+<~?1/tt//|]>;"^`^^,:li>~~++-][{11){_~+]}{}}{1111{}]+>I:!_{11){{}]?-+~[{{1-: `:-11{{{{{ -QLCJJYYXXzzvuuunxxxxrrrjjjtttt///\|(){{[[]??_+~<>i!lII:::,""^`'''....'```' .``',>?]+>~-1/ft/\1+l:,"^",;l!><<~+_-?[}{{{}???[}}{1(\/|){}]_i!lI;:::,"^^`'''....`""^' `:,`.'::,,"",:l!i<~~~++_?][}}}}[?____-[{(){[-~<<<><-[{)11{}]-_+>!!lI;:,,,"^^`''.....^"^' 'l>I,`'"i?]_ii-{(||()}+l"`^''^,I!!>~~+++_-?][[[[[?_+++-?][[]?+~<<<~-][}}}{}}]-+~>l:^' '^. ,+(\\/\{<:' `l-1|\\\\\ -LLCJUYYXXzzvuuuxxrrrrjjffttt////\()11{}[]?-_+~<>>!!lI;:,""^^``''.....'^.. ,i~I^. `:l!>~~++_--?]]][[[]??][}{{{{}}}}]??]][[[}}}}}]-+~iI,` .`` ^<)|///1<;` .;~}(\|||| -LLJJUYXXzzcuuunxxxrrjjffffttt//\|()1{}[]]?-_~~<>i!lI;;:,""^```''..... 'l>i+-<;^^l}/|?_-?{))(1?>l;^ `Ii>~++++_-??][[[[[}}{1)))(((()1{}}[[[[[}}}}}]-+~iI". .. ^<{(\\\1<;` ^i-1||||| -LLJJUYXXzcvuuunxxxrjjjfffttt//\\|)1{{}[]]?_+~<>i!llI;:,,"^^```'.. ':~~!-[+!I;l+{){{1}{11{[>l;,' ^!>~+++___--?]][[[}}{11))1)))1{{{}}[[[][][]]]-+~!:^ '!}(\\\1~I` 'I+}((((( -CCJUUYXXzcvuunxxxrrjjffttttt/\\\|)1{}[[]?-_+~<>i!llI;,"""^```''. ,i~>l]}_>i!ll_)\\|1}?__~l;,". `I>++__________+_-?][[[[[}}}[]????-????]??]]?+[))))) -CCJUUYXXzcvunxxrrrjjjffttt//\\\|()1{}[]??-+~<>i!lII;:,"^^^``'''. 'I~~>!]}_<~_+~{/t|{[_~;"^''`^,;li<~~~<<>i!I:,,,,;!<+--_~i;". 'I?1())1?i"' ^!?{11{1 -CCJUUYXXzcvunxxrrrjjjffttt//\\\|(1{{}]]??-+~<~<<>i<1\|[_~>l,",,` "!~+___+~>l:^. .";Illl:^. ^:!iii!I"' "-{11{]i"' ';~]{11{ -CCJUYXXzcvuunxrrrjjfffttt//\\\|(){{}[]?--_+<>i!llI;,""^^^^`'''.. `>__-?+i:";>l:""^````''....''```":l><~~~>l,' I-1{]i". ,>?}{{} -JJUYYXzzvuunxxrrrjjfftttt//\\|()1{}[[]?-_+~>i!!lI;:,""^^^``'.... ,i+_~!ll;^ '":;:I!!!!I,^. ;<++++++~~~++++~>I" '<[]>^. "i]{111 -JJUYXzzcvuuxxrrjjfftttt///\\\|()1}}[[?-_++i!lIII:,,"^^````'...':~[?!' .'`^^``^` ^i++___--?--__++~~<<<<~~__-_++~~~~i!lII;:,"^^^````'.."<-_: ..'``` `l<+_--?]]]]?????------?---_+~<<i!lI;;::"^^^````'^!_!. .`^` 'Ii<_--?????]]]]]]?????-___+<>iI,`.. . ,~}|// -UYXzcvvunxxrjfffttt///\\\\|()1{}[[]]-_+~<>i!lI;;::,"^^^```^!-_I ";` .. ";l>+_-_????????]????-___+~i;"`'''. ^<](// -YYXzvvunnxrjjfftttt//\/\|||()1{[[]?--_+<>>i!II;::,,"^^^^,!~+I. "I. .. ^,;I!i<~~~~++++++++++~~<>!I:^''''`. 'l-)// -XXzcvunxxrjjfftt////\\\||())1{}[]]?-_+~<>>!lII;:,,,"^";!il' .' .^",:::;IIIIl!iiiii!!!lIII;:"^`''' .I-(jn -Xzcuunxxrrjfftt////\\|||()1{}[[]]?--_+<<>i!lI;::,,,":!>: `^"",,,,;Ili><~__-_+++~!!lII;:::::I;' '^,,,"",:Il!><+-?]]??_+>l;,^``'. `~(nY -zcunxxrjjfftt///\\\\|||()1{}[[]?--_+~<>i!lllI;::;l;` `","""",;I;;;l!<_--+i;:,"^```'. ;]tv -vuunxrrjjfft//\\\\|||())1{}[[]]?-_+~~iii!lIIIl+-; '``^^`^",:;:,""""^"",,^`''. . ,_( -nxxrjjffttt/\\|||||()11{}[]]]]?-__+~~<>ii~?]-~~+!` .``^^^^",::::::::;:,"'. 'i} -xxrjffttt//\\||||())1{}}[]]]???-_+~~~~+[/fjf\}!. '`^^^`'``^"""""`. l] -xrjjff///\\\||(|(()11{}[]]]]?--_+~~~~]/xxf\[i' .'``'. ,_ -jffftt/\\\|||((())1{{}]]??--__++~<<<]tnuj1<. .''. ^< diff --git a/etc/motd b/etc/motd deleted file mode 100644 index f252b8e..0000000 --- a/etc/motd +++ /dev/null @@ -1 +0,0 @@ -why the hell are you using this os? diff --git a/etc/profile b/etc/profile deleted file mode 100644 index 7cd7a19..0000000 --- a/etc/profile +++ /dev/null @@ -1,8 +0,0 @@ -# acts like .bash_profile or .zsh_profile - -const motd_size = fs:size("/etc/motd") -if motd_size > 0 do - puts("\n") - puts(fs:read_bytes("/etc/motd", 0, motd_size)) - puts("\n") -end diff --git a/fonts/acorn8.psf b/fonts/acorn8.psf deleted file mode 100644 index 57bc46b..0000000 Binary files a/fonts/acorn8.psf and /dev/null differ diff --git a/fonts/dejavu.ttf b/fonts/dejavu.ttf deleted file mode 100644 index 597b2e0..0000000 Binary files a/fonts/dejavu.ttf and /dev/null differ diff --git a/fonts/pearl8.psf b/fonts/pearl8.psf deleted file mode 100644 index acf7939..0000000 Binary files a/fonts/pearl8.psf and /dev/null differ diff --git a/fonts/sun16.psf b/fonts/sun16.psf deleted file mode 100644 index 8042ba3..0000000 Binary files a/fonts/sun16.psf and /dev/null differ diff --git a/fonts/terminess.ttf b/fonts/terminess.ttf deleted file mode 100644 index 0055a2c..0000000 Binary files a/fonts/terminess.ttf and /dev/null differ diff --git a/fonts/vga16.psf b/fonts/vga16.psf deleted file mode 100644 index 652b07b..0000000 Binary files a/fonts/vga16.psf and /dev/null differ diff --git a/fonts/vga8.psf b/fonts/vga8.psf deleted file mode 100644 index 3fcce09..0000000 Binary files a/fonts/vga8.psf and /dev/null differ diff --git a/kernel/seed.rv b/kernel/seed.rv index 95ed632..e4ffa9b 100644 --- a/kernel/seed.rv +++ b/kernel/seed.rv @@ -18,6 +18,15 @@ fn seed_fonts() do end end +# libc bullshitery +fn seed_include() do + fs:mkdir("/usr/include") + fs:mkdir("/usr/include/sys") + for index in 0..inc_count() do + fs:store("/usr/include/#{inc_name(index)}", inc_src(index)) + end +end + fn seed_fs() do fs:mkdir("/usr") fs:mkdir("/etc") @@ -31,4 +40,5 @@ fn seed_fs() do seed_bin() seed_fonts() + seed_include() end diff --git a/sysroot/etc/lung b/sysroot/etc/lung new file mode 100644 index 0000000..54c10ab --- /dev/null +++ b/sysroot/etc/lung @@ -0,0 +1,79 @@ +(((())))11111{{{}}}}}}[[[]]]]]]]-------_______)juvvvvvvvvvvvvvvvvvvvvvuuuuuuuuuuuuuvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvccccccvvvvvvccccccccccccccccccccccccccvvvvvvuuuuuuuuuuuuuuuunnnnnnnnnnnxxxxxxxxxxxxxxxrrrrrrrrrrrrrrrrrrrrrrrrjjjjjjjjjffjf)][}} +||(((()))11111{{{{}}}}}[[[]]]]]]????----______-{tuuuuuuvvvvvvvvvvvvvvuuuuuuuuuuuuuuvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvccccccvvvvvvcccccccccccccccccccccccvvvvvvvvvuuuuuuuuuuuuunnnnnnnnnnnxxxxxxxxxxxxxxrrrrrrrrrrrrrrrrrrrjjjjjjjjjjjjjjjjjjff/{-_-][ +|||||(((()))111111{{}}}[[[[[[]]]]]??----________[fnuuuuuuuuuuuuuvvvvvvuuuuuuuuuuuuuvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvcccccccccccccccccccccccccvvvccccccvvvvvvvvvuuuuuuuuuunnnnnnnnnnnnnnxxxxxxrrrrrrrrrrrrrrjjjjjjjjjrjjjjjjjjjjjjjjjjjjjjffft)~+[{{1 +\\\|||((())))1111111{{{}}[[[[[]]]]??----_________]|xuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuvvvvvvvvvvvvvvvvvvvvvcccccccccccccccccccccccccvvvvvvvvvuuuuuuuuuuuuuuuunnnnnnnnnnnnnxxxxxxxxrrrrrrrrrrrrrrrjjjjjjjjjjjjjjjjjjjjjjjjjjjjjffftf\}<+{))) +\\\\\||||(()))1111111{{{}}}}[[[[]]??----________+_?(ruuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuvvvvvvvvvvvvvvvvvvvvcccccccccccccccccccccvvvvvuuunnnnnnuuuuuuuuuuuuunnnnnnnnnnnnnnnxxxxxxrrrrrrrrrrrrrjjjjjjjjjjjjjjjjjfffffffffffjjjffffft/{~I~{||( +/\\\\\\||((())))111111{{{}}}[[[[]]??-----_____+++++_1fnnnuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuvuvvvvvvvvvvvvvcvvvvvvvvvvuuuuvvvvvuuuuunnnnnnnnnnnnnnnnnnnnnnnnnnnnnnxxxxxxxxxxxxrrrrrjjjjjjjjjjjjjjjjjjjjjjjjffffffffffffffffffftt\(]+<~+?[[}} +ttttt//////\\|||((()))))111{}}}}}[[]]]?----__+++_++++~~~-(fxxxxnnnnnnnnnnnnnnnnnnnnnxxxnnnnunnnnnuuuuuuuuuuuuuunxjjjjjfjjft/\|||(()))(\//\\\|\||\\///\|(1}[[[}{1)((((|/tfjjjjjjjjjjjjjjjjjjjjjjjjjjffffffffffffffftttt|(1}[]][1\//////)-<___[1{{{{ +fttttttt///\\\\|||((())))111{{{}}[[[]]?---___+++_++~~~<<>~{frxxxxxxxxxxxxxnnnnnnnnnnxxxxnnnnnnnnnnunnnnnxxxxrjjft/\\\\||(1{}}}}}}}}}}?__]}}}}111{{1)1[-~>iii!!ii~_?}{1(|\\ttfjjjjjjjjjjjfffffffffffffffffffffftfftt|}-+<>!I;,^`:>_?[1{?__+_]))((() +jffffttt//////\\\|||(((())11{{{}}}[[]]?---___+++_+~~~<<>ii<]/rrxrrxxxxxxxxxxxxxxxxxxnnnnnnnnnnnnnnnnnxxrrjjffttt//\(1}?~iI:,,,"""""""^`''^,,I<_--_++>I,`. .'`^``^,l+[(\/tttffffjjjjjffffffffttttftttttfffftttt\[~><<iiii-|jrjrrrrrrrrrxxxxxxxxxxxxxxxxnnnxnnnnnnxrrjjtt/\\|(1{]_!,' .''.'. ..'`:<[(/tttttffffffffttttttttttttttttttttttt(_>!!lI:` .''''"I<_[{)((((( +rrjjjjffttttt////\\\||||(())111{{}}[[]]]?---___++~~~<<<>i!!!!+(tjjjrrrrrrrrrrrrrxxxxxxxxxxxxxxxxxrrrrjft/\||(1}]_i" .`:-)\///ttftfftttttttttttttttt/////////(-l``^^`. '",",:l>ii!!!!!>{tjjjjrrrrrrrrrrrrrxrrrrrrrrrrrjjjfftt/\|))1{[-i;' . .,-(\\//tttttttttttt////////\\\\\\\\\(?: .. "i>i!!i+?}{{1111111 +xxrrrrrjjjffttt////\\\||||(())11{{}}[[]]]??--__++~~<<>>i!!!!lll<[tjfffffffffffffffffjjjjjjjjjfftt/||())1}[?+l` ...'l?(\\//tttt/////////\\\\\\\\|||||\()?i:````^:!+?[]<-]{{{1111111 +xxxxrrrjjjfffttttt//\\|||||(())11{{}[[[]]]?--___+~<<>>i!!!lllIII!](ttttttttttttttttffffffffftt//\|)))1{[-~l" '. '~1\\\////\\\\\\\||||||||(((((((((((()111111111}+ll<~+?]]][[}}}}}} +xxxxrrrrjjjjffttttt//\\\\||||()111{}}}[]]]?--__+++~<>ii!!!llII;;::-)///////tttttttttttttt////\|(()11}?ii!!!lIII;:,,,>}|\\\\\\\\//////////\\|||(()){]_i:"' .l-1)(|||((((|||||||(((((()))))))))))1111{[I,:<[[[}}{}[]---- +nnxxxxxxrrrjjfffftttt///\\\||(()111{{}[[]]]??--_++~>>ii!!!llI;;:,"",i[(|||||\\\\\\\\///\\|((((1}?I"' .l-}11))))))))))))))111111{{{{{{{{{{{}?>llI, ,-[}}}}}}}}}}[[[ +unnnxxxxxrrrrjjjjjfttttt//\\||||()1{{{}}[]]]?--_+~~I"' ;+[{1111111111111111{{{{{{{{{{}}}}?>!!i!!!!~[}}}}}}}}}}}[[[ +unnnnxxxxxrrrrrrjjfttttt//\\\|||()11{{{}[]]]?--_+~~l!>_-?--?][}[[[[}}}}}}[[[ +uununxxxxxxrrrrrjjfftttt///\\\||()11{{{}[]]]?--__+~;,I!<_-?][[[[[[[[[[[[[[[[[[[ +uuuuunxxxxxxxrrrrjjffffttt//\\\|(()1{{{}}[[]??--_+~l". .`",:;IIIIlll!!!!lI;,,,,,,::;IIII:"` `>-][}}}}}}}[[[[[[[[[[[]->:^;>_-____--???]]]]]]]]]]]]]]] +vuuuuunnnxxxxrrrrrjjfffttt//\\\||()11{{}}[[]]??-_+~<<~~~~++++~<>i>>>>><<<>>>>il;" `!-]][[[[[[[]]]?_+++~iII!!;l~]]]?-_______----??]]]]]]]] +vvvvuuunnxxxxxxrrrjjffftttt/\\\\|(()111{}}[[]]?-_+~~>i!!lII;::,,,"""^'.... `!_---?-<~~+++_---?????????--_++~~<<>i!I:. .I~???]]]][]]_>;":l>~+--+!l>-?]?????--_++___---??????? +vvvvuuunnnnnnxxxrrjjffftttt/\\\\||())11{}}[[]]?-_+~~>i!!lI;;:,,,""""^`'... 'I+--_>lIIl!I,`. .. `,;!>><~~~+_-?]]]]]]]]]]]]?--_+++~<<>!l;` ,<+___~i!!lI;;:,,"^^^^^^``'.. .:<+~!!!!!l;"^`' .`' .`,;l><~+++__-][[[[[[[[[[]]]]]???-_+~~<<<+_-???????????_>I;l<-???????--------------- +zcccvvvuunnnxxxxrrrjjjjfftttt///\\|(()1{}}[[[]?-_+~<>i!!lI;:,,,"^^^^^^^^^````^:>~il,' "l<~_-----??????????-_+-------------------------- +zzccvvvuuunnxxxxxxrrjjjfftttt///\\\|()11}}}[[]]?_+~i!llI;::,,"""^^^^^",:;Il>~<+____--??][]]]][[[[}}[[[[[]?--_+~~+++_____________________------------------ +zXzzcvvvvuuunnnnnxrrrjjjftttt///\\\|()11{}}[[[]?-+~<>i!lI;;::,,""^"^^^",::;l~__>>i!I;:"^ .. .`,I!><~+-??][[[[[}}[[[[[[[[}}}}[[[[]]?-__~>i!;^ ."l<++++_________________________----------_-- +zzzzzccvvuuunnnxxxrrrrrjffffttt/\\\|()11{}}[[]]--+++~>i!lI;::,,,,,,,:;l!lli-]?+iI::!~-??-+>lI,"` .^:I!>~+_?][[[}}{{{{{{{{{}}}}{{{{{{{{}[[]]?_+ii!llI;,,::Il!iii!i_??_>I,":>-[[[?+>lI,' '";l>~-??]}}}{{1)))(()))111111))))))11{{{}[]-_~>l" `I<~~~++++++++++++++++++++++______________- +YXXXzccccvuunnnxxxrrrrrjjfffttt///\\()11{}}[[]?_+~~~~~<>ii!!!I:,:;!iiii>+--_+>I;:;i-}1{{]_>>iii!l!!IIl><<<<+_?]?-_>l;;l+{)(1[->I:,"^' .'`",l>~-?[{)(||\\\\\\\\\|||((())111{[?_+>ii!!lllllll!i<_??]]]-+~>I;!i>-)(}_ili<>l,' .''' '^^^`'. ^l~?{(||||||((((){[-~~<<<>!lI;;::"`. ^l<<~~~~~~~~~~~~~~~~~~~++++++____------- +YYXXXXzcccvuuunnxxxrrrrjjffffttt//\\|()1{}[[]]-_+~<>iiiii!I;;Ill!!>+-?]]_~iI;",l><~--<<+_~i;"`'''`";;,' '^,:;;;Il!!lI:^`^"l<-]{1)((()){}]_<;^. `I><<<<<<<<<<<<<~~~~~~~+++++__--------- +YYXXXXzzccvuuuunxxxrrrrjjffffftt//\\|()1{}[]??-_+~~~<<<><>!IIIl!>+_?]?-~>illI,"Ili<-[[]]_!;,:;I;,"";;:' .`"IllIl<+?[{1))11{}[?_>I"^^""^^^""",:;;;:,". ^li><<<<<<<<<<<<~<~~~~~++++___-------- +UUYYXXzzzcvuuuunxxxrrrrjjffffftt//\\|()1{}[]]?-_+++~++~<~>!llllll;:I>_})){?<<~>;,,II:` ",. +{]+i!l!<-[{1))11}]_>;:Il!l:' .`. :!i>>>>>>>>>>>><<<<<~~~~++___-------? +JJUYXXzzzcvuuuunxxxrrrrjjffffftt//\\|()1{}[[]?--____+~~+~~<>i!!l;:;:,"",;lIII:,;>?}}-~~?{1{]___+iI:ll:` '`^""^'.^I+?_[}{11}?<;,;>+?; :i; "I!iiiiiiiiiiiiii>>><<~~~++__------?? +JJUYYXXzzzcvuuunxxxrrrrjjffffftt//\\|()1{}[[]?----???-+~~~~~<>>!I;III:",;I;:;:::Ii~+]1\fff\11{}?+!Iiil" '^:Ili>><+---_+~<<>!!>>il:,,:I;,`.. . "I!i!i!!!!!!!!!!!!!i><<<~++_----???? +JJUUUXXXzzcvuuunxxxrrrrjjffffftt//\\|()1{}[[]?------??---_+<>>>ilIl!!lI;;;;;;:,,"I-{\jxxrj/())1}-<~+_--??-_+~>!I;::I>-]][_><~+_--?--+~>!l;:"` .`' ^;!!!!!!llII;;;;;;;;Illi><+_--???]]] +JJJUUYXXzzcvuuunxxxrrrrjjffffftt//\\|(11{}[[?--__++~~~~~++~>!!lllIIlI;,"^^^"""^``:+1/jnnxjf\()11}-<~_]]]_++_?][[]]?-+_--?????] +CJJJUYXXzzcvuuunxxxrrrrjjffffftt//\\()11}[[]?-_++~<>ii!!!!!lI;:,,"^^``'....'``'''"<1/rnnnxf/|(()1[??+iI,^. .`,Ii<_-?[}}}}]??_~>lllII!+][[[-il" '````.'.`,"'..':!>~>I,",^ 'i+-?????? +CCJJUYXXzzcvuuunxxxrrrrjjffffftt//\\()1{}[[]?-__+~?)rnnnxf/\\\()1{}?+>I:. .'":li<+-?[[[[[]??_~>!!ll!>-[}}[-~!I;Ili~_-][{111111{[?_~>l" ."l, .l?]_I . I<_-?---- +CCJUUYYXXzzvuuunxxxxrrjjjfffftt///\|(11{}[[]?___+~>i!lI;;::,""^``'... ^ll>1jxxxt)(tt/|()){?_>:. '`":Ii<+_???]]][[]?_ +CCCJUYYXXzzvuuunxxxxrrjjjfffftt///\|(11{}[[]?___+~>i!lI;;:,,"^^``'''....... .`^.^~)fff(-?\t///\(){?>:'..'^",I!>~~+_-][}{{{}]+>!l!>_[}{{}?+iI;I>~?[{1{}}}}}[]]?_+> +LCJJUYYXXzzvuuunxxxxrrjjjfffftttt/\|()1{}[[]?_+~~>i!lI;:::,""^`''''.....''. .'' l[(||)--)\///\||)]<:'..'`^";l!ii<+-]}{{1)1[+iI!<_?[{{{{[-<~~ +LCJJUYYXXzzvuuunxxxxrrjjjfffftt//\||)1{}}[]?-++<~_][{{1)1]l,,>?{111{{}[]?-+~i!lII;:::,"^`'''.....''`' ^,;>-]+<~?1/tt//|]>;"^`^^,:li>~~++-][{11){_~+]}{}}{1111{}]+>I:!_{11){{}]?-+~[{{1-: `:-11{{{{{ +QLCJJYYXXzzvuuunxxxxrrrjjjtttt///\|(){{[[]??_+~<>i!lII:::,""^`'''....'```' .``',>?]+>~-1/ft/\1+l:,"^",;l!><<~+_-?[}{{{}???[}}{1(\/|){}]_i!lI;:::,"^^`'''....`""^' `:,`.'::,,"",:l!i<~~~++_?][}}}}[?____-[{(){[-~<<<><-[{)11{}]-_+>!!lI;:,,,"^^`''.....^"^' 'l>I,`'"i?]_ii-{(||()}+l"`^''^,I!!>~~+++_-?][[[[[?_+++-?][[]?+~<<<~-][}}}{}}]-+~>l:^' '^. ,+(\\/\{<:' `l-1|\\\\\ +LLCJUYYXXzzvuuuxxrrrrjjffttt////\()11{}[]?-_+~<>>!!lI;:,""^^``''.....'^.. ,i~I^. `:l!>~~++_--?]]][[[]??][}{{{{}}}}]??]][[[}}}}}]-+~iI,` .`` ^<)|///1<;` .;~}(\|||| +LLJJUYXXzzcuuunxxxrrjjffffttt//\|()1{}[]]?-_~~<>i!lI;;:,""^```''..... 'l>i+-<;^^l}/|?_-?{))(1?>l;^ `Ii>~++++_-??][[[[[}}{1)))(((()1{}}[[[[[}}}}}]-+~iI". .. ^<{(\\\1<;` ^i-1||||| +LLJJUYXXzcvuuunxxxrjjjfffttt//\\|)1{{}[]]?_+~<>i!llI;:,,"^^```'.. ':~~!-[+!I;l+{){{1}{11{[>l;,' ^!>~+++___--?]][[[}}{11))1)))1{{{}}[[[][][]]]-+~!:^ '!}(\\\1~I` 'I+}((((( +CCJUUYXXzcvuunxxxrrjjffttttt/\\\|)1{}[[]?-_+~<>i!llI;,"""^```''. ,i~>l]}_>i!ll_)\\|1}?__~l;,". `I>++__________+_-?][[[[[}}}[]????-????]??]]?+[))))) +CCJUUYXXzcvunxxrrrjjjffttt//\\\|()1{}[]??-+~<>i!lII;:,"^^^``'''. 'I~~>!]}_<~_+~{/t|{[_~;"^''`^,;li<~~~<<>i!I:,,,,;!<+--_~i;". 'I?1())1?i"' ^!?{11{1 +CCJUUYXXzcvunxxrrrjjjffttt//\\\|(1{{}]]??-+~<~<<>i<1\|[_~>l,",,` "!~+___+~>l:^. .";Illl:^. ^:!iii!I"' "-{11{]i"' ';~]{11{ +CCJUYXXzcvuunxrrrjjfffttt//\\\|(){{}[]?--_+<>i!llI;,""^^^^`'''.. `>__-?+i:";>l:""^````''....''```":l><~~~>l,' I-1{]i". ,>?}{{} +JJUYYXzzvuunxxrrrjjfftttt//\\|()1{}[[]?-_+~>i!!lI;:,""^^^``'.... ,i+_~!ll;^ '":;:I!!!!I,^. ;<++++++~~~++++~>I" '<[]>^. "i]{111 +JJUYXzzcvuuxxrrjjfftttt///\\\|()1}}[[?-_++i!lIII:,,"^^````'...':~[?!' .'`^^``^` ^i++___--?--__++~~<<<<~~__-_++~~~~i!lII;:,"^^^````'.."<-_: ..'``` `l<+_--?]]]]?????------?---_+~<<i!lI;;::"^^^````'^!_!. .`^` 'Ii<_--?????]]]]]]?????-___+<>iI,`.. . ,~}|// +UYXzcvvunxxrjfffttt///\\\\|()1{}[[]]-_+~<>i!lI;;::,"^^^```^!-_I ";` .. ";l>+_-_????????]????-___+~i;"`'''. ^<](// +YYXzvvunnxrjjfftttt//\/\|||()1{[[]?--_+<>>i!II;::,,"^^^^,!~+I. "I. .. ^,;I!i<~~~~++++++++++~~<>!I:^''''`. 'l-)// +XXzcvunxxrjjfftt////\\\||())1{}[]]?-_+~<>>!lII;:,,,"^";!il' .' .^",:::;IIIIl!iiiii!!!lIII;:"^`''' .I-(jn +Xzcuunxxrrjfftt////\\|||()1{}[[]]?--_+<<>i!lI;::,,,":!>: `^"",,,,;Ili><~__-_+++~!!lII;:::::I;' '^,,,"",:Il!><+-?]]??_+>l;,^``'. `~(nY +zcunxxrjjfftt///\\\\|||()1{}[[]?--_+~<>i!lllI;::;l;` `","""",;I;;;l!<_--+i;:,"^```'. ;]tv +vuunxrrjjfft//\\\\|||())1{}[[]]?-_+~~iii!lIIIl+-; '``^^`^",:;:,""""^"",,^`''. . ,_( +nxxrjjffttt/\\|||||()11{}[]]]]?-__+~~<>ii~?]-~~+!` .``^^^^",::::::::;:,"'. 'i} +xxrjffttt//\\||||())1{}}[]]]???-_+~~~~+[/fjf\}!. '`^^^`'``^"""""`. l] +xrjjff///\\\||(|(()11{}[]]]]?--_+~~~~]/xxf\[i' .'``'. ,_ +jffftt/\\\|||((())1{{}]]??--__++~<<<]tnuj1<. .''. ^< diff --git a/sysroot/etc/motd b/sysroot/etc/motd new file mode 100644 index 0000000..f252b8e --- /dev/null +++ b/sysroot/etc/motd @@ -0,0 +1 @@ +why the hell are you using this os? diff --git a/sysroot/etc/profile b/sysroot/etc/profile new file mode 100644 index 0000000..7cd7a19 --- /dev/null +++ b/sysroot/etc/profile @@ -0,0 +1,8 @@ +# acts like .bash_profile or .zsh_profile + +const motd_size = fs:size("/etc/motd") +if motd_size > 0 do + puts("\n") + puts(fs:read_bytes("/etc/motd", 0, motd_size)) + puts("\n") +end diff --git a/sysroot/usr/include/fcntl.h b/sysroot/usr/include/fcntl.h new file mode 100644 index 0000000..4c9dc07 --- /dev/null +++ b/sysroot/usr/include/fcntl.h @@ -0,0 +1,12 @@ +#ifndef _FCNTL_H +#define _FCNTL_H + +#define O_RDONLY 0 +#define O_WRONLY 1 +#define O_CREAT 0x40 +#define O_TRUNC 0x200 +#define O_APPEND 0x400 + +int open(const char* path, int flags); + +#endif diff --git a/sysroot/usr/include/stddef.h b/sysroot/usr/include/stddef.h new file mode 100644 index 0000000..0fe5f56 --- /dev/null +++ b/sysroot/usr/include/stddef.h @@ -0,0 +1,9 @@ +#ifndef _STDDEF_H +#define _STDDEF_H + +typedef unsigned long size_t; +typedef long ptrdiff_t; + +#define NULL ((void*)0) + +#endif diff --git a/sysroot/usr/include/stdint.h b/sysroot/usr/include/stdint.h new file mode 100644 index 0000000..d3da3d2 --- /dev/null +++ b/sysroot/usr/include/stdint.h @@ -0,0 +1,10 @@ +#ifndef _STDINT_H +#define _STDINT_H + +typedef unsigned char uint8_t; typedef signed char int8_t; +typedef unsigned short uint16_t; typedef short int16_t; +typedef unsigned int uint32_t; typedef int int32_t; +typedef unsigned long uint64_t; typedef long int64_t; +typedef unsigned long uintptr_t; typedef long intptr_t; + +#endif diff --git a/sysroot/usr/include/stdio.h b/sysroot/usr/include/stdio.h new file mode 100644 index 0000000..9f6929e --- /dev/null +++ b/sysroot/usr/include/stdio.h @@ -0,0 +1,15 @@ +#ifndef _STDIO_H +#define _STDIO_H + +#define EOF (-1) + +int putchar(int character); +int getchar(void); +int puts(const char* string); +int printf(const char* format, ...); + +// revel only, not part of stdc +// read a line from stdin -> returns length +int readline(char* buffer, int max_length); + +#endif diff --git a/sysroot/usr/include/stdlib.h b/sysroot/usr/include/stdlib.h new file mode 100644 index 0000000..7950258 --- /dev/null +++ b/sysroot/usr/include/stdlib.h @@ -0,0 +1,17 @@ +#ifndef _STDLIB_H +#define _STDLIB_H + +#include + +void* malloc(size_t length); +void free(void* pointer); +void* calloc(size_t count, size_t size); +void* realloc(void* pointer, size_t length); + +void exit(int code) __attribute__((noreturn)); + +int atoi(const char* string); +long atol(const char* string); +int abs(int value); + +#endif diff --git a/sysroot/usr/include/string.h b/sysroot/usr/include/string.h new file mode 100644 index 0000000..2177ad6 --- /dev/null +++ b/sysroot/usr/include/string.h @@ -0,0 +1,17 @@ +#ifndef _STRING_H +#define _STRING_H + +#include + +size_t strlen(const char* string); +int strcmp(const char* a, const char* b); +int strncmp(const char* a, const char* b, size_t length); +char* strcpy(char* destination, const char* source); +char* strncpy(char* destination, const char* source, size_t length); + +void* memcpy(void* destination, const void* source, size_t length); +void* memmove(void* destination, const void* source, size_t length); +void* memset(void* destination, int value, size_t length); +int memcmp(const void* a, const void* b, size_t length); + +#endif diff --git a/sysroot/usr/include/sys/syscall.h b/sysroot/usr/include/sys/syscall.h new file mode 100644 index 0000000..4a23a53 --- /dev/null +++ b/sysroot/usr/include/sys/syscall.h @@ -0,0 +1,34 @@ +#ifndef _SYS_SYSCALL_H +#define _SYS_SYSCALL_H + +#define SYS_exit 0 +#define SYS_write 1 +#define SYS_read 2 +#define SYS_open 7 +#define SYS_close 8 +#define SYS_lseek 9 +#define SYS_brk 10 +#define SYS_sbrk 11 + +static inline long __syscall1(long number, long a1) +{ + long result; + __asm__ volatile("int $0x80" : "=a"(result) : "a"(number), "D"(a1) : "memory"); + return result; +} + +static inline long __syscall2(long number, long a1, long a2) +{ + long result; + __asm__ volatile("int $0x80" : "=a"(result) : "a"(number), "D"(a1), "S"(a2) : "memory"); + return result; +} + +static inline long __syscall3(long number, long a1, long a2, long a3) +{ + long result; + __asm__ volatile("int $0x80" : "=a"(result) : "a"(number), "D"(a1), "S"(a2), "d"(a3) : "memory"); + return result; +} + +#endif diff --git a/sysroot/usr/include/unistd.h b/sysroot/usr/include/unistd.h new file mode 100644 index 0000000..f5a67ab --- /dev/null +++ b/sysroot/usr/include/unistd.h @@ -0,0 +1,18 @@ +#ifndef _UNISTD_H +#define _UNISTD_H + +#include + +#define SEEK_SET 0 +#define SEEK_CUR 1 +#define SEEK_END 2 + +long read(int fd, void* buffer, size_t length); +long write(int fd, const void* buffer, size_t length); +int close(int fd); +long lseek(int fd, long offset, int whence); + +void* sbrk(long increment); +int brk(void* address); + +#endif diff --git a/sysroot/usr/lib/libc/crt0.c b/sysroot/usr/lib/libc/crt0.c new file mode 100644 index 0000000..16c3a94 --- /dev/null +++ b/sysroot/usr/lib/libc/crt0.c @@ -0,0 +1,28 @@ +#include + +extern int main(int argc, char** argv); + +void _start(const char* arg, unsigned long arglen) +{ + static char arg_buffer[256]; + char* argv[3]; + int argc = 1; + argv[0] = ""; + + if (arglen > 0) + { + unsigned long count = arglen; + if (count > sizeof(arg_buffer) - 1) + count = sizeof(arg_buffer) - 1; + for (unsigned long i = 0; i < count; i++) + arg_buffer[i] = arg[i]; + arg_buffer[count] = 0; + argv[1] = arg_buffer; + argc = 2; + } + else + argv[1] = NULL; + + argv[argc] = NULL; + exit(main(argc, argv)); +} diff --git a/sysroot/usr/lib/libc/stdio.c b/sysroot/usr/lib/libc/stdio.c new file mode 100644 index 0000000..d0e7ad7 --- /dev/null +++ b/sysroot/usr/lib/libc/stdio.c @@ -0,0 +1,211 @@ +#include +#include +#include +#include + +int putchar(int character) +{ + char byte = (char)character; + if (write(1, &byte, 1) != 1) + return EOF; + return (unsigned char)byte; +} + +int getchar(void) +{ + char byte; + if (read(0, &byte, 1) <= 0) + return EOF; + return (unsigned char)byte; +} + +int puts(const char* string) +{ + (void)write(1, string, strlen(string)); + (void)write(1, "\n", 1); + return 0; +} + +static int format_unsigned(char* buffer, unsigned long value, int base, int upper) +{ + const char* digits = upper ? "0123456789ABCDEF" : "0123456789abcdef"; + char temp[32]; + int count = 0; + if (value == 0) + temp[count++] = '0'; + while (value > 0) + { + temp[count++] = digits[value % (unsigned)base]; + value /= (unsigned)base; + } + for (int i = 0; i < count; i++) + buffer[i] = temp[count - 1 - i]; + return count; +} + +static int format_signed(char* buffer, long value) +{ + int negative = value < 0; + unsigned long magnitude = negative ? (unsigned long)(-value) : (unsigned long)value; + int count = 0; + if (negative) + buffer[count++] = '-'; + return count + format_unsigned(buffer + count, magnitude, 10, 0); +} + +#define PRINTF_BUFFER 256 + +// yoinked straight off open source +int printf(const char* format, ...) +{ + char out[PRINTF_BUFFER]; + int filled = 0; + int total = 0; + va_list args; + va_start(args, format); + +#define FLUSH() \ + do { \ + if (filled > 0) \ + { \ + (void)write(1, out, filled); \ + filled = 0; \ + } \ + } while (0) +#define EMIT(ch) \ + do { \ + if (filled == PRINTF_BUFFER) \ + FLUSH(); \ + out[filled++] = (char)(ch); \ + total++; \ + } while (0) + + for (const char* cursor = format; *cursor; cursor++) + { + if (*cursor != '%') + { + EMIT(*cursor); + continue; + } + + cursor++; + if (*cursor == '%') + { + EMIT('%'); + continue; + } + + int zero_pad = 0; + if (*cursor == '0') + { + zero_pad = 1; + cursor++; + } + int width = 0; + while (*cursor >= '0' && *cursor <= '9') + { + width = width * 10 + (*cursor - '0'); + cursor++; + } + int is_long = 0; + while (*cursor == 'l') + { + is_long = 1; + cursor++; + } + + char conversion = *cursor; + if (conversion == 's') + { + const char* string = va_arg(args, const char*); + if (!string) + string = "(null)"; + int length = (int)strlen(string); + for (int i = length; i < width; i++) + EMIT(' '); + for (int i = 0; i < length; i++) + EMIT(string[i]); + continue; + } + if (conversion == 'c') + { + int character = va_arg(args, int); + for (int i = 1; i < width; i++) + EMIT(' '); + EMIT(character); + continue; + } + + char number[34]; + int length = 0; + if (conversion == 'd' || conversion == 'i') + { + long value = is_long ? va_arg(args, long) : (long)va_arg(args, int); + length = format_signed(number, value); + } + else if (conversion == 'u') + { + unsigned long value = is_long ? va_arg(args, unsigned long) : (unsigned long)va_arg(args, unsigned int); + length = format_unsigned(number, value, 10, 0); + } + else if (conversion == 'x' || conversion == 'X') + { + unsigned long value = is_long ? va_arg(args, unsigned long) : (unsigned long)va_arg(args, unsigned int); + length = format_unsigned(number, value, 16, conversion == 'X'); + } + else if (conversion == 'p') + { + unsigned long value = (unsigned long)va_arg(args, void*); + EMIT('0'); + EMIT('x'); + length = format_unsigned(number, value, 16, 0); + } + else + { + EMIT('%'); + EMIT(conversion); + continue; + } + + for (int i = length; i < width; i++) + EMIT(zero_pad ? '0' : ' '); + for (int i = 0; i < length; i++) + EMIT(number[i]); + } + + FLUSH(); + va_end(args); + return total; + +#undef EMIT +#undef FLUSH +} + +int readline(char* buffer, int max_length) +{ + int length = 0; + for (;;) + { + char character; + if (read(0, &character, 1) <= 0) + break; + if (character == '\n') + break; + if (character == '\b') + { + if (length > 0) + { + length--; + (void)write(1, "\b \b", 3); + } + continue; + } + if (length < max_length - 1) + { + buffer[length++] = character; + (void)write(1, &character, 1); + } + } + buffer[length] = 0; + return length; +} diff --git a/sysroot/usr/lib/libc/stdlib.c b/sysroot/usr/lib/libc/stdlib.c new file mode 100644 index 0000000..a0a86b9 --- /dev/null +++ b/sysroot/usr/lib/libc/stdlib.c @@ -0,0 +1,185 @@ +#include +#include +#include + +#define HEAP_HEADER 16UL +#define HEAP_ALIGN 16UL +#define HEAP_MIN 32UL +#define HEAP_CHUNK (64UL * 1024UL) + +static unsigned long heap_start = 0; +static unsigned long heap_end = 0; +static unsigned long heap_rover = 0; + +static unsigned long heap_block_size(unsigned long block) +{ + return *(unsigned long*)block & ~15UL; +} + +static int heap_block_used(unsigned long block) +{ + return (int)(*(unsigned long*)block & 1UL); +} + +static void heap_set(unsigned long block, unsigned long size, int used) +{ + *(unsigned long*)block = size | (used ? 1UL : 0UL); +} + +static unsigned long heap_align(unsigned long value) +{ + return (value + HEAP_ALIGN - 1UL) & ~(HEAP_ALIGN - 1UL); +} + +// pull another hunk off sbrk and drop a free block over it +static int heap_grow(unsigned long need) +{ + unsigned long want = heap_align(need); + if (want < HEAP_CHUNK) + want = HEAP_CHUNK; + unsigned long got = (unsigned long)sbrk((long)want); + if ((long)got < 0) + return 0; + if (heap_start == 0) + { + heap_start = got; + heap_end = got; + heap_rover = got; + } + heap_set(heap_end, want, 0); + heap_end += want; + return 1; +} + +// fire O(n) malloc implementation frfr +void* malloc(size_t length) +{ + if (length == 0) + return NULL; + unsigned long need = heap_align(HEAP_HEADER + length); + if (need < HEAP_MIN) + need = HEAP_MIN; + + for (;;) + { + if (heap_rover < heap_start || heap_rover >= heap_end) + heap_rover = heap_start; + unsigned long block = heap_rover; + unsigned long limit = heap_end; + for (int pass = 0; pass < 2; pass++) + { + while (block < limit) + { + if (!heap_block_used(block)) + { + // lazily coalesce the free run starting here + unsigned long size = heap_block_size(block); + while (block + size < heap_end && !heap_block_used(block + size)) + size += heap_block_size(block + size); + heap_set(block, size, 0); + if (size >= need) + { + if (size >= need + HEAP_MIN) + { + heap_set(block, need, 1); + heap_set(block + need, size - need, 0); + heap_rover = block + need; + } + else + { + heap_set(block, size, 1); + heap_rover = block + size; + } + if (heap_rover >= heap_end) + heap_rover = heap_start; + return (void*)(block + HEAP_HEADER); + } + } + block += heap_block_size(block); + } + block = heap_start; + limit = heap_rover; + } + if (!heap_grow(need)) + return NULL; + } +} + +void free(void* pointer) +{ + if (pointer == NULL) + return; + unsigned long block = (unsigned long)pointer - HEAP_HEADER; + heap_set(block, heap_block_size(block), 0); +} + +void* calloc(size_t count, size_t size) +{ + unsigned long total = (unsigned long)count * (unsigned long)size; + unsigned char* bytes = malloc(total); + if (bytes) + for (unsigned long i = 0; i < total; i++) + bytes[i] = 0; + return bytes; +} + +void* realloc(void* pointer, size_t length) +{ + if (pointer == NULL) + return malloc(length); + if (length == 0) + { + free(pointer); + return NULL; + } + unsigned long block = (unsigned long)pointer - HEAP_HEADER; + unsigned long have = heap_block_size(block) - HEAP_HEADER; + if (length <= have) + return pointer; + unsigned char* grown = malloc(length); + if (!grown) + return NULL; + unsigned char* source = pointer; + for (unsigned long i = 0; i < have; i++) + grown[i] = source[i]; + free(pointer); + return grown; +} + +void exit(int code) +{ + __syscall1(SYS_exit, code); + for (;;) + ; +} + +long atol(const char* string) +{ + while (*string == ' ' || *string == '\t') + string++; + int negative = 0; + if (*string == '-') + { + negative = 1; + string++; + } + else if (*string == '+') + string++; + long value = 0; + while (*string >= '0' && *string <= '9') + { + value = value * 10 + (*string - '0'); + string++; + } + return negative ? -value : value; +} + +int atoi(const char* string) +{ + return (int)atol(string); +} + +int abs(int value) +{ + return value < 0 ? -value : value; +} diff --git a/sysroot/usr/lib/libc/string.c b/sysroot/usr/lib/libc/string.c new file mode 100644 index 0000000..7bbc0c2 --- /dev/null +++ b/sysroot/usr/lib/libc/string.c @@ -0,0 +1,92 @@ +#include + +size_t strlen(const char* string) +{ + size_t length = 0; + while (string[length]) + length++; + return length; +} + +int strcmp(const char* a, const char* b) +{ + while (*a && *a == *b) + { + a++; + b++; + } + + return (int)(unsigned char)*a - (int)(unsigned char)*b; +} + +int strncmp(const char* a, const char* b, size_t length) +{ + for (size_t i = 0; i < length; i++) + { + unsigned char ca = (unsigned char)a[i]; + unsigned char cb = (unsigned char)b[i]; + if (ca != cb) + return (int)ca - (int)cb; + if (ca == 0) + return 0; + } + return 0; +} + +char* strcpy(char* destination, const char* source) +{ + char* out = destination; + while ((*out++ = *source++)) + ; + return destination; +} + +char* strncpy(char* destination, const char* source, size_t length) +{ + size_t i = 0; + for (; i < length && source[i]; i++) + destination[i] = source[i]; + for (; i < length; i++) + destination[i] = 0; + return destination; +} + +void* memcpy(void* destination, const void* source, size_t length) +{ + unsigned char* out = destination; + const unsigned char* in = source; + for (size_t i = 0; i < length; i++) + out[i] = in[i]; + return destination; +} + +void* memmove(void* destination, const void* source, size_t length) +{ + unsigned char* out = destination; + const unsigned char* in = source; + if (out < in) + for (size_t i = 0; i < length; i++) + out[i] = in[i]; + else + for (size_t i = length; i > 0; i--) + out[i - 1] = in[i - 1]; + return destination; +} + +void* memset(void* destination, int value, size_t length) +{ + unsigned char* out = destination; + for (size_t i = 0; i < length; i++) + out[i] = (unsigned char)value; + return destination; +} + +int memcmp(const void* a, const void* b, size_t length) +{ + const unsigned char* aa = a; + const unsigned char* bb = b; + for (size_t i = 0; i < length; i++) + if (aa[i] != bb[i]) + return (int)aa[i] - (int)bb[i]; + return 0; +} diff --git a/sysroot/usr/lib/libc/syscalls.c b/sysroot/usr/lib/libc/syscalls.c new file mode 100644 index 0000000..ad959b9 --- /dev/null +++ b/sysroot/usr/lib/libc/syscalls.c @@ -0,0 +1,38 @@ +#include +#include +#include + +long read(int fd, void* buffer, size_t length) +{ + return __syscall3(SYS_read, fd, (long)buffer, (long)length); +} + +long write(int fd, const void* buffer, size_t length) +{ + return __syscall3(SYS_write, fd, (long)buffer, (long)length); +} + +int open(const char* path, int flags) +{ + return (int)__syscall2(SYS_open, (long)path, flags); +} + +int close(int fd) +{ + return (int)__syscall1(SYS_close, fd); +} + +long lseek(int fd, long offset, int whence) +{ + return __syscall3(SYS_lseek, fd, offset, whence); +} + +void* sbrk(long increment) +{ + return (void*)__syscall1(SYS_sbrk, increment); +} + +int brk(void* address) +{ + return (int)__syscall1(SYS_brk, (long)address); +} diff --git a/sysroot/usr/share/acorn8.psf b/sysroot/usr/share/acorn8.psf new file mode 100644 index 0000000..57bc46b Binary files /dev/null and b/sysroot/usr/share/acorn8.psf differ diff --git a/sysroot/usr/share/dejavu.ttf b/sysroot/usr/share/dejavu.ttf new file mode 100644 index 0000000..597b2e0 Binary files /dev/null and b/sysroot/usr/share/dejavu.ttf differ diff --git a/sysroot/usr/share/pearl8.psf b/sysroot/usr/share/pearl8.psf new file mode 100644 index 0000000..acf7939 Binary files /dev/null and b/sysroot/usr/share/pearl8.psf differ diff --git a/sysroot/usr/share/sun16.psf b/sysroot/usr/share/sun16.psf new file mode 100644 index 0000000..8042ba3 Binary files /dev/null and b/sysroot/usr/share/sun16.psf differ diff --git a/sysroot/usr/share/terminess.ttf b/sysroot/usr/share/terminess.ttf new file mode 100644 index 0000000..0055a2c Binary files /dev/null and b/sysroot/usr/share/terminess.ttf differ diff --git a/sysroot/usr/share/vga16.psf b/sysroot/usr/share/vga16.psf new file mode 100644 index 0000000..652b07b Binary files /dev/null and b/sysroot/usr/share/vga16.psf differ diff --git a/sysroot/usr/share/vga8.psf b/sysroot/usr/share/vga8.psf new file mode 100644 index 0000000..3fcce09 Binary files /dev/null and b/sysroot/usr/share/vga8.psf differ diff --git a/user/calc.c b/user/calc.c index cf5b1d2..63fa9c6 100644 --- a/user/calc.c +++ b/user/calc.c @@ -1,20 +1,20 @@ -#include "user.h" +#include static int is_digit(char character) { return character >= '0' && character <= '9'; } -void _start(void) +int main(void) { - put("calc, e.g. 3 + 4 * 2 (left to right), empty line quits\n"); + printf("calc, e.g. 3 + 4 * 2 (left to right), empty line quits\n"); char line[128]; for (;;) { - put("> "); - int length = read_line(line, 128); - put("\n"); + printf("> "); + int length = readline(line, 128); + printf("\n"); if (length == 0) break; @@ -49,7 +49,7 @@ void _start(void) { if (value == 0) { - put("divide by zero\n"); + printf("divide by zero\n"); valid = 0; break; } @@ -66,19 +66,15 @@ void _start(void) } else { - put("bad character\n"); + printf("bad character\n"); valid = 0; break; } } if (valid && saw_number) - { - put("= "); - put_int(accumulator); - put("\n"); - } + printf("= %ld\n", accumulator); } - sys_exit(0); + return 0; } diff --git a/user/chat.c b/user/chat.c index 1657c73..7a1d5c8 100644 --- a/user/chat.c +++ b/user/chat.c @@ -1,32 +1,28 @@ -#include "user.h" +#include +#include +#include -void _start(const char* arg, unsigned long arglen) +int main(int argc, char** argv) { - if (arglen == 0) + if (argc < 2) { - put("usage: run chat \n"); - sys_exit(1); + printf("usage: run chat \n"); + return 1; } - char path[128]; - unsigned long i = 0; - for (; i < arglen && i < sizeof(path) - 1; i++) - path[i] = arg[i]; - path[i] = 0; - - long fd = sys_open(path, 0); + const char* path = argv[1]; + int fd = open(path, O_RDONLY); if (fd < 0) { - put("chat: "); - put(path); - put(": cannot open\n"); - sys_exit(1); + printf("chat: %s: cannot open\n", path); + return 1; } char buffer[256]; long bytes_read; - while ((bytes_read = sys_read(fd, buffer, sizeof(buffer))) > 0) - (void)sys_write(1, buffer, (unsigned long)bytes_read); - (void)sys_close(fd); - sys_exit(0); + while ((bytes_read = read(fd, buffer, sizeof(buffer))) > 0) + write(1, buffer, (unsigned long)bytes_read); + + close(fd); + return 0; } diff --git a/user/hexview.c b/user/hexview.c index 5d21711..44bbe38 100644 --- a/user/hexview.c +++ b/user/hexview.c @@ -1,103 +1,75 @@ -#include "user.h" - -static const char HEX[] = "0123456789abcdef"; - -static void put_hex8(unsigned char byte) -{ - char digits[2] = { HEX[byte >> 4], HEX[byte & 15] }; - (void)sys_write(1, digits, 2); -} - -static void put_hex32(unsigned long value) -{ - char digits[8]; - for (int nibble = 0; nibble < 8; nibble++) - digits[nibble] = HEX[(value >> ((7 - nibble) * 4)) & 15]; - (void)sys_write(1, digits, 8); -} +#include +#include +#include #define PAGE 256 #define COLS 16 -void _start(const char* arg, unsigned long arglen) +int main(int argc, char** argv) { - char name[64]; - - if (arglen > 0 && arglen < 64) - { - for (unsigned long i = 0; i < arglen; i++) - name[i] = arg[i]; - name[arglen] = 0; - } + char prompt_name[64]; + const char* name; + if (argc >= 2) + name = argv[1]; else { - put("hexview, type a filename\nfile: "); - (void)read_line(name, 64); - put("\n"); + printf("hexview, type a filename\nfile: "); + readline(prompt_name, 64); + printf("\n"); + name = prompt_name; } - long size = sys_fs_size(name); - if (size < 0) + int fd = open(name, O_RDONLY); + if (fd < 0) { - put("no such file\n"); - sys_exit(1); + printf("no such file\n"); + return 1; } + long size = lseek(fd, 0, SEEK_END); unsigned long offset = 0; char buffer[PAGE]; for (;;) { - long count = sys_fs_read(name, offset, buffer, PAGE); + lseek(fd, (long)offset, SEEK_SET); + long count = read(fd, buffer, PAGE); - put("--- "); - put(name); - put(" @ 0x"); - put_hex32(offset); - put(" / 0x"); - put_hex32((unsigned long)size); - put(" ---\n"); + printf("--- %s @ 0x%08lx / 0x%08lx ---\n", name, offset, (unsigned long)size); for (long row = 0; row < count; row += COLS) { - put_hex32(offset + (unsigned long)row); - put(": "); + printf("%08lx: ", offset + (unsigned long)row); for (int column = 0; column < COLS; column++) { if (row + column < count) - { - put_hex8((unsigned char)buffer[row + column]); - (void)sys_write(1, " ", 1); - } + printf("%02x ", (unsigned char)buffer[row + column]); else - put(" "); + printf(" "); } - put(" "); + printf(" "); for (int column = 0; column < COLS && row + column < count; column++) { char character = buffer[row + column]; - if (character >= 32 && character < 127) - (void)sys_write(1, &character, 1); - else - (void)sys_write(1, ".", 1); + putchar((character >= 32 && character < 127) ? character : '.'); } - put("\n"); + printf("\n"); } - put("[n]ext [p]rev [q]uit (or up/down arrows) > "); - char key = (char)get_char(); + printf("[n]ext [p]rev [q]uit (or up/down arrows) > "); + int key = getchar(); if (key == 27) // ESC { - (void)get_char(); - char final = (char)get_char(); + getchar(); + int final = getchar(); if (final == 'A') key = 'p'; else if (final == 'B') key = 'n'; } - put("\n"); + printf("\n"); if (key == 'q') break; if (key == 'n' && offset + PAGE < (unsigned long)size) @@ -106,5 +78,6 @@ void _start(const char* arg, unsigned long arglen) offset -= PAGE; } - sys_exit(0); + close(fd); + return 0; } diff --git a/user/membrk.c b/user/membrk.c index f1949cc..7d73adf 100644 --- a/user/membrk.c +++ b/user/membrk.c @@ -1,31 +1,26 @@ -#include "user.h" +#include +#include +#include static void check(const char* name, int ok) { - put(ok ? "ok " : "FAIL "); - put(name); - put("\n"); + printf("%s%s\n", ok ? "ok " : "FAIL ", name); } -void _start(const char* arg, unsigned long arglen) +int main(void) { - (void)arg; - (void)arglen; - - long start = (long)sys_sbrk(0); - put("heap base: "); - put_int(start); - put("\n"); + long start = (long)sbrk(0); + printf("heap base: %ld\n", start); // obese alloc test char* run[80]; for (int i = 0; i < 80; i++) - run[i] = (char*)malloc(4000); - long run_after = (long)sys_sbrk(0); + run[i] = malloc(4000); + long run_after = (long)sbrk(0); for (int i = 0; i < 80; i++) free(run[i]); - char* merged = (char*)malloc(80 * 4000 - 8000); - long merge_after = (long)sys_sbrk(0); + char* merged = malloc(80 * 4000 - 8000); + long merge_after = (long)sbrk(0); check("freed neighbours coalesce", merged != 0 && merge_after <= run_after); free(merged); @@ -33,7 +28,7 @@ void _start(const char* arg, unsigned long arglen) char* blocks[16]; for (int i = 0; i < 16; i++) { - blocks[i] = (char*)malloc(64); + blocks[i] = malloc(64); for (int j = 0; j < 64; j++) blocks[i][j] = (char)(i * 7 + j); } @@ -46,7 +41,7 @@ void _start(const char* arg, unsigned long arglen) // a big block spanning several pages written edge to edge unsigned long big = 20000; - unsigned char* buffer = (unsigned char*)malloc(big); + unsigned char* buffer = malloc(big); for (unsigned long k = 0; k < big; k++) buffer[k] = (unsigned char)(k & 0xff); int big_ok = 1; @@ -55,18 +50,18 @@ void _start(const char* arg, unsigned long arglen) big_ok = 0; check("big multi page alloc", big_ok); - // testing that the the heap must doesnt grow across the loop - long churn_before = (long)sys_sbrk(0); + // testing that the heap doesnt grow across the loop + long churn_before = (long)sbrk(0); for (int i = 0; i < 2000; i++) { void* pointer = malloc(500); free(pointer); } - long churn_after = (long)sys_sbrk(0); + long churn_after = (long)sbrk(0); check("alloc/free churn reclaims (no growth)", churn_before == churn_after); // calloc dirty test - unsigned char* zeroed = (unsigned char*)calloc(200, 1); + unsigned char* zeroed = calloc(200, 1); int zero_ok = 1; for (int i = 0; i < 200; i++) if (zeroed[i] != 0) @@ -74,20 +69,18 @@ void _start(const char* arg, unsigned long arglen) check("calloc is zeroed", zero_ok); // realloc test - char* grown = (char*)malloc(32); + char* grown = malloc(32); for (int i = 0; i < 32; i++) grown[i] = (char)(i + 1); - grown = (char*)realloc(grown, 500); + grown = realloc(grown, 500); int grow_ok = 1; for (int i = 0; i < 32; i++) if (grown[i] != (char)(i + 1)) grow_ok = 0; check("realloc grows and preserves data", grow_ok); - long end = (long)sys_sbrk(0); - put("heap high water: "); - put_int(end - start); - put(" bytes\n"); + long end = (long)sbrk(0); + printf("heap high water: %ld bytes\n", end - start); - sys_exit(0); + return 0; } diff --git a/user/primes.c b/user/primes.c index 49c545a..5501c32 100644 --- a/user/primes.c +++ b/user/primes.c @@ -1,22 +1,19 @@ -#include "user.h" +#include +#include -void _start(void) +int main(void) { - put("primes up to N, enter N (empty line quits)\n"); + printf("primes up to N, enter N (empty line quits)\n"); char line[32]; for (;;) { - put("> "); - int length = read_line(line, 32); - put("\n"); + printf("> "); + int length = readline(line, 32); + printf("\n"); if (length == 0) break; - long limit = 0; - for (int position = 0; position < length; position++) - if (line[position] >= '0' && line[position] <= '9') - limit = limit * 10 + (line[position] - '0'); - + long limit = atol(line); int count = 0; for (long candidate = 2; candidate <= limit; candidate++) { @@ -29,14 +26,11 @@ void _start(void) } if (prime) { - put_int(candidate); - put(" "); + printf("%ld ", candidate); count++; } } - put("\n"); - put_int(count); - put(" primes\n"); + printf("\n%d primes\n", count); } - sys_exit(0); + return 0; } diff --git a/user/save.c b/user/save.c index 2ac065f..056e160 100644 --- a/user/save.c +++ b/user/save.c @@ -1,45 +1,37 @@ -#include "user.h" +#include +#include +#include -void _start(const char* arg, unsigned long arglen) +int main(int argc, char** argv) { - if (arglen == 0 || arglen >= 120) + if (argc < 2) { - put("usage: run save \n"); - sys_exit(1); + printf("usage: run save \n"); + return 1; } - char name[128]; - for (unsigned long i = 0; i < arglen; i++) - name[i] = arg[i]; - name[arglen] = 0; - - long fd = sys_open(name, O_CREAT | O_TRUNC | O_WRONLY); + const char* name = argv[1]; + int fd = open(name, O_CREAT | O_TRUNC | O_WRONLY); if (fd < 0) { - put("save: "); - put(name); - put(": cannot open\n"); - sys_exit(1); + printf("save: %s: cannot open\n", name); + return 1; } - put("saving to "); - put(name); - put(" -- type lines, a single . saves\n"); + printf("saving to %s -- type lines, a single . saves\n", name); for (;;) { char line[256]; - int bytes_read = read_line(line, 256); - put("\n"); + int bytes_read = readline(line, 256); + printf("\n"); if (bytes_read == 1 && line[0] == '.') break; - (void)sys_write(fd, line, (unsigned long)bytes_read); - (void)sys_write(fd, "\n", 1); + write(fd, line, (unsigned long)bytes_read); + write(fd, "\n", 1); } - (void)sys_close(fd); - put("saved "); - put(name); - put("\n"); - sys_exit(0); + close(fd); + printf("saved %s\n", name); + return 0; } diff --git a/user/user.h b/user/user.h deleted file mode 100644 index 58a1bc5..0000000 --- a/user/user.h +++ /dev/null @@ -1,309 +0,0 @@ -#define SEEK_SET 0 -#define SEEK_CUR 1 -#define SEEK_END 2 - -#define O_WRONLY 1 -#define O_CREAT 0x40 -#define O_TRUNC 0x200 -#define O_APPEND 0x400 - -static inline __attribute__((warn_unused_result)) long sys_write(long fd, const char* buffer, unsigned long length) -{ - long result; - __asm__ volatile("int $0x80" : "=a"(result) : "a"(1L), "D"(fd), "S"(buffer), "d"(length) : "memory"); - return result; -} - -static inline __attribute__((warn_unused_result)) long sys_read(long fd, char* buffer, unsigned long length) -{ - long result; - __asm__ volatile("int $0x80" : "=a"(result) : "a"(2L), "D"(fd), "S"(buffer), "d"(length) : "memory"); - return result; -} - -static inline __attribute__((warn_unused_result)) long sys_open(const char* path, long flags) -{ - long result; - __asm__ volatile("int $0x80" : "=a"(result) : "a"(7L), "D"(path), "S"(flags) : "memory"); - return result; -} - -static inline __attribute__((warn_unused_result)) long sys_close(long fd) -{ - long result; - __asm__ volatile("int $0x80" : "=a"(result) : "a"(8L), "D"(fd) : "memory"); - return result; -} - -static inline __attribute__((warn_unused_result)) long sys_lseek(long fd, long offset, long whence) -{ - long result; - __asm__ volatile("int $0x80" : "=a"(result) : "a"(9L), "D"(fd), "S"(offset), "d"(whence) : "memory"); - return result; -} - -static inline void sys_exit(long code) -{ - __asm__ volatile("int $0x80" : : "a"(0L), "D"(code) : "memory"); - for (;;); -} - -static inline __attribute__((warn_unused_result)) long sys_fs_size(const char* name) -{ - long result; - __asm__ volatile("int $0x80" : "=a"(result) : "a"(4L), "D"(name) : "memory"); - return result; -} - -static inline __attribute__((warn_unused_result)) long sys_fs_read(const char* name, unsigned long offset, char* buffer, unsigned long length) -{ - long result; - __asm__ volatile("int $0x80" - : "=a"(result) - : "a"(5L), "D"(name), "S"(offset), "d"(buffer), "c"(length) - : "memory"); - return result; -} - -static inline __attribute__((warn_unused_result)) long sys_fs_write(const char* name, const char* buffer, unsigned long length) -{ - long result; - __asm__ volatile("int $0x80" - : "=a"(result) - : "a"(6L), "D"(name), "S"(buffer), "d"(length) - : "memory"); - return result; -} - -static inline __attribute__((warn_unused_result)) long sys_brk(void* address) -{ - long result; - __asm__ volatile("int $0x80" : "=a"(result) : "a"(10L), "D"(address) : "memory"); - return result; -} - -static inline __attribute__((warn_unused_result)) void* sys_sbrk(long increment) -{ - long result; - __asm__ volatile("int $0x80" : "=a"(result) : "a"(11L), "D"(increment) : "memory"); - return (void*)result; -} - -// shitty heap implementation -// temporary af this will be in its own libc -#define HEAP_HEADER 16UL -#define HEAP_ALIGN 16UL -#define HEAP_MIN 32UL -#define HEAP_CHUNK (64UL * 1024UL) - -static unsigned long heap_start = 0; -static unsigned long heap_end = 0; -static unsigned long heap_rover = 0; - -static inline __attribute__((warn_unused_result)) unsigned long heap_block_size(unsigned long block) -{ - return *(unsigned long*)block & ~15UL; -} - -static inline __attribute__((warn_unused_result)) int heap_block_used(unsigned long block) -{ - return (int)(*(unsigned long*)block & 1UL); -} - -static inline void heap_set(unsigned long block, unsigned long size, int used) -{ - *(unsigned long*)block = size | (used ? 1UL : 0UL); -} - -static inline __attribute__((warn_unused_result)) unsigned long heap_align(unsigned long value) -{ - return (value + HEAP_ALIGN - 1UL) & ~(HEAP_ALIGN - 1UL); -} - -// pull another hunk off sbrk and drop a free block over it -static inline __attribute__((warn_unused_result)) int heap_grow(unsigned long need) -{ - unsigned long want = heap_align(need); - if (want < HEAP_CHUNK) - want = HEAP_CHUNK; - unsigned long got = (unsigned long)sys_sbrk((long)want); - if ((long)got < 0) - return 0; - if (heap_start == 0) - { - heap_start = got; - heap_end = got; - heap_rover = got; - } - heap_set(heap_end, want, 0); - heap_end += want; - return 1; -} - -// yummy O(n) malloc implementation -static inline __attribute__((warn_unused_result)) void* malloc(unsigned long length) -{ - if (length == 0) - return 0; - unsigned long need = heap_align(HEAP_HEADER + length); - if (need < HEAP_MIN) - need = HEAP_MIN; - - for (;;) - { - if (heap_rover < heap_start || heap_rover >= heap_end) - heap_rover = heap_start; - unsigned long block = heap_rover; - unsigned long limit = heap_end; - for (int pass = 0; pass < 2; pass++) - { - while (block < limit) - { - if (!heap_block_used(block)) - { - unsigned long size = heap_block_size(block); - while (block + size < heap_end && !heap_block_used(block + size)) - size += heap_block_size(block + size); - heap_set(block, size, 0); - if (size >= need) - { - if (size >= need + HEAP_MIN) - { - heap_set(block, need, 1); - heap_set(block + need, size - need, 0); - heap_rover = block + need; - } - else - { - heap_set(block, size, 1); - heap_rover = block + size; - } - if (heap_rover >= heap_end) - heap_rover = heap_start; - return (void*)(block + HEAP_HEADER); - } - } - block += heap_block_size(block); - } - block = heap_start; - limit = heap_rover; - } - if (!heap_grow(need)) - return 0; - } -} - -static inline void free(void* pointer) -{ - if (pointer == 0) - return; - unsigned long block = (unsigned long)pointer - HEAP_HEADER; - heap_set(block, heap_block_size(block), 0); -} - -static inline __attribute__((warn_unused_result)) void* calloc(unsigned long count, unsigned long size) -{ - unsigned long total = count * size; - unsigned char* bytes = (unsigned char*)malloc(total); - if (bytes) - for (unsigned long i = 0; i < total; i++) - bytes[i] = 0; - return bytes; -} - -static inline __attribute__((warn_unused_result)) void* realloc(void* pointer, unsigned long length) -{ - if (pointer == 0) - return malloc(length); - if (length == 0) - { - free(pointer); - return 0; - } - unsigned long block = (unsigned long)pointer - HEAP_HEADER; - unsigned long have = heap_block_size(block) - HEAP_HEADER; - if (length <= have) - return pointer; - unsigned char* new_block = (unsigned char*)malloc(length); - if (!new_block) - return 0; - unsigned char* source = (unsigned char*)pointer; - for (unsigned long i = 0; i < have; i++) - new_block[i] = source[i]; - free(pointer); - return new_block; -} - -static inline void put(const char* string) -{ - unsigned long length = 0; - while (string[length]) - length++; - (void)sys_write(1, string, length); -} - -static inline __attribute__((warn_unused_result)) int get_char(void) -{ - char character; - if (sys_read(0, &character, 1) <= 0) - return -1; - return (unsigned char)character; -} - -static inline __attribute__((warn_unused_result)) int read_line(char* buffer, int max_length) -{ - int length = 0; - for (;;) - { - char character; - if (sys_read(0, &character, 1) <= 0) - break; - if (character == '\n') - break; - if (character == '\b') - { - if (length > 0) - { - length--; - (void)sys_write(1, "\b \b", 3); - } - continue; - } - if (length < max_length - 1) - { - buffer[length++] = character; - (void)sys_write(1, &character, 1); - } - } - buffer[length] = 0; - return length; -} - -static inline void put_int(long value) -{ - char buffer[21]; - int length = 0; - int negative = value < 0; - unsigned long magnitude = negative ? (unsigned long)(-value) : (unsigned long)value; - - if (magnitude == 0) - buffer[length++] = '0'; - - while (magnitude > 0) - { - buffer[length++] = (char)('0' + magnitude % 10); - magnitude /= 10; - } - - if (negative) - buffer[length++] = '-'; - - for (int left = 0, right = length - 1; left < right; left++, right--) - { - char swap = buffer[left]; - buffer[left] = buffer[right]; - buffer[right] = swap; - } - - (void)sys_write(1, buffer, length); -} -- cgit v1.3