Skip to content

Commit

Permalink
Unfinished changes, WIP vfs and tmpfs
Browse files Browse the repository at this point in the history
  • Loading branch information
Ratakor committed Nov 7, 2023
1 parent 42ba18e commit 2b6694e
Show file tree
Hide file tree
Showing 8 changed files with 496 additions and 257 deletions.
13 changes: 3 additions & 10 deletions kernel/arch/x86_64/gdt.zig
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const GDT = extern struct {
user_data: Entry align(1),
tss: TSS.Descriptor align(1),

const Entry = packed struct {
const Entry = packed struct(u64) {
limit_low: u16 = 0,
base_low: u16 = 0,
base_mid: u8 = 0,
Expand All @@ -27,9 +27,7 @@ const GDT = extern struct {
};

comptime {
std.debug.assert(@sizeOf(GDT) == 7 * 8);
std.debug.assert(@sizeOf(Entry) == @sizeOf(u64));
std.debug.assert(@bitSizeOf(Entry) == @bitSizeOf(u64));
std.debug.assert(@sizeOf(GDT) == 7 * @sizeOf(u64));
std.debug.assert(@bitSizeOf(Descriptor) == 80);
}
};
Expand All @@ -52,7 +50,7 @@ pub const TSS = extern struct {
reserved3: u16 align(1) = 0,
iopb: u16 align(1),

const Descriptor = packed struct {
const Descriptor = packed struct(u128) {
limit_low: u16 = @sizeOf(TSS),
base_low: u16 = undefined,
base_mid: u8 = undefined,
Expand All @@ -63,11 +61,6 @@ pub const TSS = extern struct {
base_upper: u32 = undefined,
reserved: u32 = 0,
};

comptime {
std.debug.assert(@sizeOf(Descriptor) == @sizeOf(u64) * 2);
std.debug.assert(@bitSizeOf(Descriptor) == @bitSizeOf(u64) * 2);
}
};

pub const kernel_code = 0x08;
Expand Down
2 changes: 1 addition & 1 deletion kernel/arch/x86_64/idt.zig
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ fn defaultHandler(ctx: *Context) callconv(.SysV) void {
if (ctx.cs == gdt.user_code) {
switch (ctx.vector) {
0x0e => {
if (vmm.handlePageFault(cr2, ctx.error_code)) {
if (vmm.handlePageFault(cr2, @bitCast(@as(u32, @intCast(ctx.error_code))))) {
return;
} else |err| {
log.err("failed to handle page fault: {}", .{err});
Expand Down
7 changes: 1 addition & 6 deletions kernel/arch/x86_64/x86_64.zig
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const assert = @import("std").debug.assert;

pub const RFlags = packed struct {
pub const RFlags = packed struct(u64) {
CF: u1 = 0,
reserved: u1 = 1,
PF: u1 = 0,
Expand All @@ -23,11 +23,6 @@ pub const RFlags = packed struct {
VIP: u1 = 0,
ID: u1 = 0,
reserved4: u42 = 0,

comptime {
assert(@sizeOf(RFlags) == @sizeOf(u64));
assert(@bitSizeOf(RFlags) == @bitSizeOf(u64));
}
};

pub const MSR = enum(u32) {
Expand Down
150 changes: 106 additions & 44 deletions kernel/fs/tmpfs.zig
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
const std = @import("std");
const root = @import("root");
const vfs = root.vfs;
const page_size = std.mem.page_size;
const vmm = root.vmm;
const pmm = root.pmm;

const file_vtable: vfs.VNode.VTable = .{
// TODO

const file_vtable: vfs.Node.VTable = .{
.read = File.read,
.write = File.write,
.stat = File.stat,
};

const dir_vtable: vfs.VNode.VTable = .{
const dir_vtable: vfs.Node.VTable = .{
.open = Dir.open,
.readDir = Dir.read,
.insert = Dir.insert,
Expand All @@ -23,50 +26,109 @@ const fs_vtable: vfs.FileSystem.VTable = .{
.allocInode = FileSystem.allocInode,
};

const vtable: vfs.Node.VTable = .{
.read = File.read,
.write = File.write,
.stat = File.stat,
.truncate = File.truncate,
};

const File = struct {
vnode: vfs.VNode,
data: std.ArrayListAlignedUnmanaged(u8, page_size) = .{},
node: vfs.Node,
data: std.ArrayListAlignedUnmanaged(u8, blksize) = .{},

fn read(vnode: *vfs.VNode, buf: []u8, offset: usize, flags: usize) vfs.ReadError!usize {
_ = flags;
const blksize = std.mem.page_size;

const self = @fieldParentPtr(File, "vnode", vnode);
fn read(node: *vfs.Node, buf: []u8, offset: std.os.off_t) vfs.ReadError!usize {
const self = @fieldParentPtr(File, "node", node);
if (offset >= self.data.items.len) {
return 0;
}
const bytes_read = @min(buf.len, self.data.items.len - offset);
@memcpy(buf[0..bytes_read], self.data.items[offset .. offset + bytes_read]);
const u_offset: usize = @intCast(offset);
@memcpy(buf[0..bytes_read], self.data.items[u_offset .. u_offset + bytes_read]);
return bytes_read;
}

fn write(vnode: *vfs.VNode, buf: []const u8, offset: usize, flags: usize) vfs.WriteError!usize {
_ = flags;

const self = @fieldParentPtr(File, "vnode", vnode);
try self.data.insertSlice(root.allocator, offset, buf);
fn write(node: *vfs.Node, buf: []const u8, offset: std.os.off_t) vfs.WriteError!usize {
const self = @fieldParentPtr(File, "node", node);
try self.data.insertSlice(root.allocator, @intCast(offset), buf);
return buf.len;
}

fn stat(vnode: *vfs.VNode, buf: *std.os.Stat) vfs.StatError!void {
const self = @fieldParentPtr(File, "vnode", vnode);
fn stat(node: *vfs.Node, buf: *std.os.Stat) vfs.StatError!void {
const self = @fieldParentPtr(File, "node", node);
buf.* = .{
.dev = undefined,
.ino = node.inode,
.mode = node.mode, // TODO: 0o777 | std.os.S.IFREG,
.nlink = node.nlink,
.uid = node.uid,
.gid = node.gid,
.rdev = undefined,
.size = @intCast(self.data.items.len),
.blksize = blksize,
.blocks = std.math.divCeil(usize, self.data.items.len, blksize), // TODO: use @divCeil
.atim = node.atim,
.mtim = node.mtim,
.ctim = node.ctim,
};
}

buf.* = std.mem.zeroes(std.os.Stat);
buf.ino = vnode.inode;
buf.mode = 0o777 | std.os.S.IFREG; // TODO
buf.size = @intCast(self.data.items.len);
buf.blksize = page_size;
buf.blocks = @intCast(std.mem.alignForward(usize, self.data.items.len, page_size) / page_size);
// TODO
fn mmap(node: *vfs.Node, file_page: usize, flags: u64) !*anyopaque {
const self = @fieldParentPtr(File, "node", node);
return if (flags & std.os.MAP.SHARED != 0)
@intFromPtr(self.data[file_page * blksize ..].ptr) - vmm.hhdm_offset
else blk: {
const data = try root.allocator.alloc(u8, blksize);
@memcpy(data, self.data[file_page * blksize ..][0..blksize]);
break :blk @intFromPtr(data.ptr) - vmm.hhdm_offset;
};
}

fn truncate(node: *vfs.Node, length: usize) vfs.DefaultError!void {
const self = @fieldParentPtr(File, "node", node);
try self.data.resize(root.allocator, length);
}

fn create(parent: *vfs.Node, name: []const u8, mode: std.os.mode_t) vfs.CreateError!void {
_ = mode;
_ = name;
_ = parent;
const node = try root.allocator.create(vfs.Node);
node.* = .{
.vtable = &vtable,
};
return node;
// TODO
}

// TODO: create_resource
// TODO: instantiate?
// TODO: mount
// TODO: create
// TODO: symlink
// TODO: link
};

// pub const MountFn = *const fn (arg: []const u8, mount_point: []const u8) *Node;
fn mount(parent: *vfs.Node, name: []const u8, _: *vfs.Node) *vfs.Node {
_ = name;
_ = parent;
// return parent.createFile(parent,
// TODO

}

const Dir = struct {
vnode: vfs.VNode,
children: std.ArrayListUnmanaged(*vfs.VNode) = .{},
node: vfs.Node,
children: std.ArrayListUnmanaged(*vfs.Node) = .{},

fn open(vnode: *vfs.VNode, name: []const u8, flags: usize) vfs.OpenError!*vfs.VNode {
fn open(node: *vfs.Node, name: []const u8, flags: u64) vfs.OpenError!*vfs.Node {
_ = flags;

const self = @fieldParentPtr(Dir, "vnode", vnode);
const self = @fieldParentPtr(Dir, "node", node);
for (self.children.items) |child| {
if (std.mem.eql(u8, child.name, name)) {
return child;
Expand All @@ -77,8 +139,8 @@ const Dir = struct {
}

// TODO
fn read(vnode: *vfs.VNode, buf: []u8, offset: *usize) vfs.ReadDirError!usize {
const self = @fieldParentPtr(Dir, "vnode", vnode);
fn read(node: *vfs.Node, buf: []u8, offset: *usize) vfs.ReadDirError!usize {
const self = @fieldParentPtr(Dir, "node", node);

var dir_ent: *std.os.system.DirectoryEntry = @ptrCast(@alignCast(buf.ptr));
var buf_offset: usize = 0;
Expand All @@ -90,7 +152,7 @@ const Dir = struct {
if (buf_offset + real_size > buf.len) break;

dir_ent.d_off = 0;
dir_ent.d_ino = vnode.inode;
dir_ent.d_ino = node.inode;
dir_ent.d_reclen = @truncate(real_size);
dir_ent.d_type = return @intFromEnum(child.kind);
@memcpy(dir_ent.d_name[0..child.name.len], child.name); // TODO
Expand All @@ -102,8 +164,8 @@ const Dir = struct {
return buf_offset;
}

fn insert(vnode: *vfs.VNode, new_child: *vfs.VNode) vfs.InsertError!void {
const self = @fieldParentPtr(Dir, "vnode", vnode);
fn insert(node: *vfs.Node, new_child: *vfs.Node) vfs.InsertError!void {
const self = @fieldParentPtr(Dir, "node", node);
for (self.children.items) |child| {
if (std.mem.eql(u8, child.name, new_child.name)) {
return error.PathAlreadyExists;
Expand All @@ -112,9 +174,9 @@ const Dir = struct {
try self.children.append(root.allocator, new_child);
}

fn stat(vnode: *vfs.VNode, buf: *std.os.Stat) vfs.StatError!void {
fn stat(node: *vfs.Node, buf: *std.os.Stat) vfs.StatError!void {
buf.* = std.mem.zeroes(std.os.Stat);
buf.ino = vnode.inode;
buf.ino = node.inode;
buf.mode = 0o777 | std.os.S.IFDIR; // TODO
}
};
Expand All @@ -124,12 +186,12 @@ const FileSystem = struct {
root: Dir,
inode_counter: u64,

fn createFile(fs: *vfs.FileSystem) !*vfs.VNode {
fn createFile(fs: *vfs.FileSystem) !*vfs.Node {
const file = try root.allocator.create(File);

// TODO!: are data field, parent or kind field correctly put in file?
file.* = .{
.vnode = .{
.node = .{
.vtable = &file_vtable,
.filesystem = fs,
.kind = .file,
Expand All @@ -138,14 +200,14 @@ const FileSystem = struct {
},
};

return &file.vnode;
return &file.node;
}

fn createDir(fs: *vfs.FileSystem) !*vfs.VNode {
fn createDir(fs: *vfs.FileSystem) !*vfs.Node {
const dir = try root.allocator.create(Dir);

dir.* = .{
.vnode = .{
.node = .{
.vtable = &dir_vtable,
.filesystem = fs,
.kind = .directory,
Expand All @@ -154,11 +216,11 @@ const FileSystem = struct {
},
};

return &dir.vnode;
return &dir.node;
}

fn createSymlink(fs: *vfs.FileSystem, target: []const u8) !*vfs.VNode {
const symlink = try root.allocator.create(vfs.VNode);
fn createSymlink(fs: *vfs.FileSystem, target: []const u8) !*vfs.Node {
const symlink = try root.allocator.create(vfs.Node);
errdefer root.allocator.destroy(symlink);

symlink.* = .{
Expand All @@ -180,15 +242,15 @@ const FileSystem = struct {
}
};

pub fn init(name: []const u8, parent: ?*vfs.VNode) !*vfs.VNode {
pub fn init(name: []const u8, parent: ?*vfs.Node) !*vfs.Node {
const fs = try root.allocator.create(FileSystem);

fs.* = .{
.filesystem = .{
.vtable = &fs_vtable,
},
.root = .{
.vnode = .{
.node = .{
.vtable = &dir_vtable,
.filesystem = &fs.filesystem,
.kind = .directory,
Expand All @@ -200,5 +262,5 @@ pub fn init(name: []const u8, parent: ?*vfs.VNode) !*vfs.VNode {
.inode_counter = 1,
};

return &fs.root.vnode;
return &fs.root.node;
}
9 changes: 5 additions & 4 deletions kernel/lib/tree.zig
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! DEPRECATED (and unfinished)

const std = @import("std");
const Allocator = std.mem.Allocator;

Expand All @@ -14,14 +16,13 @@ pub fn Tree(comptime T: type) type {
return node;
}

// TODO: add a comptime bool for if to free value?
/// Free a node, its children and their values
pub fn deinit(self: *Node, allocator: Allocator) void {
/// Free a node, its children and optionaly its value
pub fn deinit(self: *Node, allocator: Allocator, comptime free_value: bool) void {
for (self.children.items) |child| {
child.deinit(allocator);
}

if (comptime @typeInfo(T) == .Pointer) {
if (comptime free_value and @typeInfo(T) == .Pointer) {
switch (comptime @typeInfo(T).Size) {
.One => allocator.destroy(self.value),
.Slice => allocator.free(self.value),
Expand Down
Loading

0 comments on commit 2b6694e

Please sign in to comment.