diff options
author | Himbeer <himbeer@disroot.org> | 2024-07-10 18:45:04 +0200 |
---|---|---|
committer | Himbeer <himbeer@disroot.org> | 2024-07-10 18:45:04 +0200 |
commit | ea070c02fb0894f264e815d37527ae0e9b67759c (patch) | |
tree | c54eb250825dc717cc1c6cf21519ad6d71448ab1 | |
parent | 16282fe4dce325acb293b23d02d5fa4bab9481ff (diff) |
kernel: Provide userinit contents at /userinit in the VFS (untested)
-rw-r--r-- | src/kernel.zig | 4 | ||||
-rw-r--r-- | src/lib/resources.zig | 107 | ||||
-rw-r--r-- | src/lib/syscall.zig | 1 | ||||
-rw-r--r-- | src/lib/vfs.zig | 3 |
4 files changed, 114 insertions, 1 deletions
diff --git a/src/kernel.zig b/src/kernel.zig index b66bef1..820ee3e 100644 --- a/src/kernel.zig +++ b/src/kernel.zig @@ -13,6 +13,7 @@ const paging = @import("lib/paging.zig"); const pci = @import("lib/pci.zig"); const plic = @import("lib/plic.zig"); const process = @import("lib/process.zig"); +const resources = @import("lib/resources.zig"); const userinit = @import("lib/userinit.zig"); const vfs = @import("lib/vfs.zig"); @@ -200,6 +201,9 @@ fn pagedRun() !noreturn { try vfs.init(allocator); try w.print("Initialize VFS\r\n", .{}); + try resources.provideBuiltin(); + try w.print("Provide builtin resources\r\n", .{}); + try w.print("Start init process\r\n", .{}); var userinit_stream = std.io.fixedBufferStream(userinit.tarball); try process.runInit(allocator, userinit_stream.reader()); diff --git a/src/lib/resources.zig b/src/lib/resources.zig new file mode 100644 index 0000000..0dc6d9f --- /dev/null +++ b/src/lib/resources.zig @@ -0,0 +1,107 @@ +// SPDX-FileCopyrightText: 2024 Himbeer <himbeer@disroot.org> +// +// SPDX-License-Identifier: AGPL-3.0-or-later + +const std = @import("std"); + +const sysexchange = @import("sysexchange.zig"); +const userinit = @import("userinit.zig"); +const vfs = @import("vfs.zig"); + +const Result = sysexchange.Result; +const io = std.io; +const tar = std.tar; + +const File = tar.Iterator(io.FixedBufferStream([]const u8).Reader).File; + +pub const Error = error{ + NoTarFileInitializer, +}; + +pub fn provideBuiltin() !void { + try provideUserinit(); +} + +fn provideUserinit() !void { + try addDir("/userinit"); + + var userinit_stream = io.fixedBufferStream(userinit.tarball); + const reader = userinit_stream.reader(); + + var file_name_buffer: [4086]u8 = undefined; + var link_name_buffer: [4086]u8 = undefined; + var path_buffer: [4096]u8 = undefined; + + var it = tar.iterator(reader, .{ + .file_name_buffer = file_name_buffer[0..], + .link_name_buffer = link_name_buffer[0..], + }); + + while (try it.next()) |file| { + const path = try std.fmt.bufPrint(path_buffer[0..], "/userinit/{s}", .{file.name}); + switch (file.kind) { + .file => try addFile(path, file), + .directory => try addDir(path), + .sym_link => {}, + } + } +} + +fn addFile(path: []const u8, file: File) !void { + const allocator = vfs.treeRoot().allocator; + + const initializer = try allocator.create(File); + initializer.* = file; + + try vfs.provideResource(path, .{ + .tag = .file, + .data = .{ + .file = .{ + .openFn = open, + .readFn = read, + .writeFn = null, + .closeFn = close, + .initializer = initializer, + }, + }, + }, 0); +} + +fn addDir(path: []const u8) !void { + const allocator = vfs.treeRoot().allocator; + const tree = try allocator.create(vfs.Tree); + tree.* = vfs.Tree.init(allocator); + + try vfs.provideResource(path, .{ + .tag = .dir, + .data = .{ .dir = tree }, + }, 0); +} + +fn open(initializer: ?*anyopaque, _: u16) callconv(.C) Result(*anyopaque) { + const file_template: *File = @alignCast(@ptrCast(initializer orelse { + return Result(*anyopaque).fromAnyTypeOrError(Error.NoTarFileInitializer); + })); + + const allocator = vfs.treeRoot().allocator; + const context = allocator.create(File) catch |err| { + return Result(*anyopaque).fromAnyTypeOrError(err); + }; + context.* = file_template.*; + + return Result(*anyopaque).fromAnyTypeOrError(context); +} + +fn read(context: *anyopaque, ptr: [*]u8, len: usize) callconv(.C) Result(usize) { + const ctx: *File = @alignCast(@ptrCast(context)); + + const buffer = ptr[0..len]; + return Result(usize).fromAnyTypeOrError(ctx.read(buffer)); +} + +fn close(context: *anyopaque) callconv(.C) void { + const ctx: *File = @alignCast(@ptrCast(context)); + + const allocator = vfs.treeRoot().allocator; + allocator.destroy(ctx); +} diff --git a/src/lib/syscall.zig b/src/lib/syscall.zig index 51f6ff5..661c98d 100644 --- a/src/lib/syscall.zig +++ b/src/lib/syscall.zig @@ -118,6 +118,7 @@ fn provideFile(proc: *const process.Info, trap_frame: *trap.Frame) void { .readFn = readFn, .writeFn = writeFn, .closeFn = closeFn, + .initializer = null, } }, }, proc.id)); } diff --git a/src/lib/vfs.zig b/src/lib/vfs.zig index 3c3099a..a687c43 100644 --- a/src/lib/vfs.zig +++ b/src/lib/vfs.zig @@ -42,8 +42,9 @@ pub const File = extern struct { readFn: ?ReadFn, writeFn: ?WriteFn, closeFn: ?CloseFn, + initializer: ?*anyopaque, - pub const OpenFn = *allowzero const fn (pid: u16) callconv(.C) sysexchange.Result(*anyopaque); + pub const OpenFn = *allowzero const fn (initializer: ?*anyopaque, pid: u16) callconv(.C) sysexchange.Result(*anyopaque); pub const ReadFn = *const fn (context: *anyopaque, ptr: [*]u8, len: usize) callconv(.C) sysexchange.Result(usize); pub const WriteFn = *const fn (context: *anyopaque, ptr: [*]const u8, len: usize) callconv(.C) sysexchange.Result(usize); pub const CloseFn = *const fn (context: *anyopaque) callconv(.C) void; |