Skip to content

Commit

Permalink
Add port device + use Node.init for zero device
Browse files Browse the repository at this point in the history
  • Loading branch information
Ratakor committed Nov 9, 2023
1 parent fc8a424 commit d597931
Show file tree
Hide file tree
Showing 8 changed files with 151 additions and 105 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Make sure to have `zig master`, `xorriso` and `qemu-system-x86` then run

# File structure
This shouldn't be in readme.
TODO: move init function at the end of file?

1. imports
2. type definitions
Expand Down
18 changes: 9 additions & 9 deletions kernel/acpi.zig
Original file line number Diff line number Diff line change
Expand Up @@ -149,19 +149,19 @@ fn parse(comptime T: type, addr: u64) void {
const sdt: *const SDT = @ptrFromInt(entry + vmm.hhdm_offset);
sdt.doChecksum();

switch (std.mem.readInt(u32, &sdt.signature, .little)) {
std.mem.readInt(u32, "APIC", .little) => handleMADT(sdt),
std.mem.readInt(u32, "FACP", .little) => handleFADT(sdt),
std.mem.readInt(u32, "HPET", .little) => {}, // ignored
std.mem.readInt(u32, "WAET", .little) => {}, // ignored
switch (std.mem.readInt(u32, &sdt.signature, arch.endian)) {
std.mem.readInt(u32, "APIC", arch.endian) => handleMADT(sdt),
std.mem.readInt(u32, "FACP", arch.endian) => handleFADT(sdt),
std.mem.readInt(u32, "HPET", arch.endian) => {}, // ignored
std.mem.readInt(u32, "WAET", arch.endian) => {}, // ignored
else => log.warn("unhandled ACPI table: {s}", .{sdt.signature}),
}
}
}

/// https://uefi.org/specs/ACPI/6.5/05_ACPI_Software_Programming_Model.html#multiple-apic-description-table-madt
fn handleMADT(madt: *const SDT) void {
apic.lapic_base = std.mem.readInt(u32, madt.data()[0..4], .little);
apic.lapic_base = std.mem.readInt(u32, madt.data()[0..4], arch.endian);
log.info("lapic base: 0x{x}", .{apic.lapic_base});
var data = madt.data()[8..]; // discard madt header

Expand Down Expand Up @@ -268,15 +268,15 @@ inline fn parseInt(s5_addr: []const u8, value: *u64) usize {
return 2;
},
0xb => {
value.* = std.mem.readInt(u16, s5_addr[1..3], .little);
value.* = std.mem.readInt(u16, s5_addr[1..3], arch.endian);
return 3;
},
0xc => {
value.* = std.mem.readInt(u32, s5_addr[1..5], .little);
value.* = std.mem.readInt(u32, s5_addr[1..5], arch.endian);
return 5;
},
0xe => {
value.* = std.mem.readInt(u64, s5_addr[1..9], .little);
value.* = std.mem.readInt(u64, s5_addr[1..9], arch.endian);
return 9;
},
else => unreachable,
Expand Down
1 change: 1 addition & 0 deletions kernel/arch.zig
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
pub const arch = @import("builtin").target.cpu.arch;
pub const endian = arch.endian();

pub usingnamespace switch (arch) {
.x86_64 => @import("arch/x86_64.zig"),
Expand Down
16 changes: 8 additions & 8 deletions kernel/debug.zig
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ fn initDebugInfo() !void {
const kernel_file = root.kernel_file_request.response.?.kernel_file;

debug_info = .{
.endian = .little,
.endian = arch.endian,
.sections = .{
.{ .data = try getSectionSlice(kernel_file.address, ".debug_info"), .owned = true },
.{ .data = try getSectionSlice(kernel_file.address, ".debug_abbrev"), .owned = true },
Expand All @@ -266,8 +266,8 @@ fn initDebugInfo() !void {
}

fn getSectionSlice(elf: [*]const u8, section_name: []const u8) ![]const u8 {
const sh_strndx = std.mem.readInt(u16, elf[62 .. 62 + 2], .little);
const sh_num = std.mem.readInt(u16, elf[60 .. 60 + 2], .little);
const sh_strndx = std.mem.readInt(u16, elf[62 .. 62 + 2], arch.endian);
const sh_num = std.mem.readInt(u16, elf[60 .. 60 + 2], arch.endian);

if (sh_strndx > sh_num) {
return error.ShstrndxOutOfRange;
Expand All @@ -288,22 +288,22 @@ fn getSectionSlice(elf: [*]const u8, section_name: []const u8) ![]const u8 {
}

fn getShdr(elf: [*]const u8, idx: u16) []const u8 {
const sh_offset = std.mem.readInt(u64, elf[40 .. 40 + 8], .little);
const sh_entsize = std.mem.readInt(u16, elf[58 .. 58 + 2], .little);
const sh_offset = std.mem.readInt(u64, elf[40 .. 40 + 8], arch.endian);
const sh_entsize = std.mem.readInt(u16, elf[58 .. 58 + 2], arch.endian);
const off = sh_offset + sh_entsize * idx;

return elf[off .. off + sh_entsize];
}

fn getSectionData(elf: [*]const u8, shdr: []const u8) []const u8 {
const offset = std.mem.readInt(u64, shdr[24..][0..8], .little);
const size = std.mem.readInt(u64, shdr[32..][0..8], .little);
const offset = std.mem.readInt(u64, shdr[24..][0..8], arch.endian);
const size = std.mem.readInt(u64, shdr[32..][0..8], arch.endian);

return elf[offset .. offset + size];
}

fn getSectionName(names: []const u8, shdr: []const u8) ?[]const u8 {
const offset = std.mem.readInt(u32, shdr[0..][0..4], .little);
const offset = std.mem.readInt(u32, shdr[0..][0..4], arch.endian);
const len = std.mem.indexOfScalar(u8, names[offset..], 0) orelse return null;

return names[offset .. offset + len];
Expand Down
46 changes: 46 additions & 0 deletions kernel/fs/port.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
const std = @import("std");
const root = @import("root");
const vfs = root.vfs;
const arch = root.arch;

const vtable = vfs.Node.VTable{
.read = read,
.write = write,
};

pub fn init() void {
const node = vfs.Node.init(&vtable, "port", undefined, 0o640 | std.os.S.IFBLK) catch unreachable;
vfs.mount("/dev/port", node) catch unreachable;
}

fn read(node: *vfs.Node, buf: []u8, offset: std.os.off_t) vfs.ReadError!usize {
_ = node;

const port: u16 = @intCast(offset);
switch (buf.len) {
@sizeOf(u8) => buf[0] = arch.in(u8, port),
@sizeOf(u16) => @as(*u16, @ptrCast(@alignCast(buf.ptr))).* = arch.in(u16, port),
@sizeOf(u32) => @as(*u32, @ptrCast(@alignCast(buf.ptr))).* = arch.in(u32, port),
else => for (buf, 0..) |*byte, i| {
byte.* = arch.in(u8, @intCast(port + i));
},
}

return buf.len;
}

fn write(node: *vfs.Node, buf: []const u8, offset: std.os.off_t) vfs.WriteError!usize {
_ = node;

const port: u16 = @intCast(offset);
switch (buf.len) {
@sizeOf(u8) => arch.out(u8, port, buf[0]),
@sizeOf(u16) => arch.out(u16, port, std.mem.readInt(u16, buf[0..@sizeOf(u16)], arch.endian)),
@sizeOf(u32) => arch.out(u32, port, std.mem.readInt(u32, buf[0..@sizeOf(u32)], arch.endian)),
else => for (buf, 0..) |byte, i| {
arch.out(u8, @intCast(port + i), byte);
},
}

return buf.len;
}
42 changes: 28 additions & 14 deletions kernel/fs/tmpfs.zig
Original file line number Diff line number Diff line change
Expand Up @@ -248,11 +248,12 @@ fn create(parent: *vfs.Node, name: []const u8, mode: std.os.mode_t) vfs.CreateEr
parent.lock.lock();
defer parent.lock.unlock();

const self: *Inode = @ptrCast(@alignCast(parent.context));
const gop = try self.children.getOrPut(root.allocator, name);
if (gop.found_existing) {
return error.PathAlreadyExists;
}
// TODO
// const self: *Inode = @ptrCast(@alignCast(parent.context));
// const gop = try self.children.getOrPut(root.allocator, name);
// if (gop.found_existing) {
// return error.PathAlreadyExists;
// }

const node = try vfs.Node.init(&Inode.vtable, name, parent, mode);
const inode = try Inode.init(node.kind, null);
Expand All @@ -262,7 +263,7 @@ fn create(parent: *vfs.Node, name: []const u8, mode: std.os.mode_t) vfs.CreateEr
node.stat.gid = sched.currentProcess().group;
node.stat.blksize = Inode.blksize;
node.context = @ptrCast(inode);
gop.value_ptr.* = node;
// gop.value_ptr.* = node;
}

fn symlink(parent: *vfs.Node, name: []const u8, target: []const u8) vfs.CreateError!void {
Expand All @@ -271,11 +272,12 @@ fn symlink(parent: *vfs.Node, name: []const u8, target: []const u8) vfs.CreateEr
parent.lock.lock();
defer parent.lock.unlock();

const self: *Inode = @ptrCast(@alignCast(parent.context));
const gop = try self.children.getOrPut(root.allocator, name);
if (gop.found_existing) {
return error.PathAlreadyExists;
}
// TODO
// const self: *Inode = @ptrCast(@alignCast(parent.context));
// const gop = try self.children.getOrPut(root.allocator, name);
// if (gop.found_existing) {
// return error.PathAlreadyExists;
// }

const node = try vfs.Node.init(&Inode.vtable, name, parent, 0o777 | std.os.S.IFLNK);
const inode = try Inode.init(node.kind, target);
Expand All @@ -285,7 +287,7 @@ fn symlink(parent: *vfs.Node, name: []const u8, target: []const u8) vfs.CreateEr
node.stat.gid = sched.currentProcess().group;
node.stat.blksize = Inode.blksize;
node.context = @ptrCast(inode);
gop.value_ptr.* = node;
// gop.value_ptr.* = node;
}

fn link(parent: *vfs.Node, name: []const u8, node: *vfs.Node) vfs.CreateError!void {
Expand Down Expand Up @@ -329,8 +331,20 @@ fn mount(parent: *vfs.Node, name: []const u8, _: *vfs.Node) vfs.CreateError!*vfs

// TODO the problem is that this won't work if parent is not of the same filesystem
// and it returns nothing
_ = try create(parent, name, 0o777 | std.os.S.IFDIR);
return undefined;
// _ = try create(parent, name, 0o777 | std.os.S.IFDIR);

// TODO: use create
const node = try vfs.Node.init(&Inode.vtable, name, parent, 0o777 | std.os.S.IFDIR);
const inode = try Inode.init(node.kind, null);
node.stat.dev = vfs.allocDevID();
node.stat.ino = 0;
// node.stat.ino = @atomicRmw(os.ino_t, self.inode_counter, .Add, 1, .Release);
node.stat.uid = 0;
node.stat.gid = 0;
node.stat.blksize = Inode.blksize;
node.context = @ptrCast(inode);

return node;
}

pub fn init() void {
Expand Down
43 changes: 7 additions & 36 deletions kernel/fs/zero.zig
Original file line number Diff line number Diff line change
Expand Up @@ -22,23 +22,9 @@ const Null = struct {
return buf.len;
}

fn init() !*vfs.Node {
const node = try root.allocator.create(vfs.Node);

node.* = .{
.vtable = &vtable,
.name = try root.allocator.dupe(u8, "null"),
.stat = .{
.ino = 0,
.mode = 0o666,
.uid = 0,
.gid = 0,
},
.kind = .character_device,
.inode = 0,
};

return node;
fn init() *vfs.Node {
// 0o666 = std.fs.File.default_mode
return vfs.Node.init(&vtable, "null", undefined, 0o666 | std.os.S.IFCHR) catch unreachable;
}
};

Expand All @@ -63,27 +49,12 @@ const Zero = struct {
return buf.len;
}

fn init() !*vfs.Node {
const node = try root.allocator.create(vfs.Node);

node.* = .{
.vtable = &vtable,
.name = try root.allocator.dupe(u8, "zero"),
.stat = .{
.ino = 0,
.mode = 0o666,
.uid = 0,
.gid = 0,
},
.kind = .character_device,
.inode = 0,
};

return node;
fn init() *vfs.Node {
return vfs.Node.init(&vtable, "zero", undefined, 0o666 | std.os.S.IFCHR) catch unreachable;
}
};

pub fn init() void {
_ = vfs.mount("/dev/null", Null.init() catch unreachable) catch unreachable;
_ = vfs.mount("/dev/zero", Zero.init() catch unreachable) catch unreachable;
_ = vfs.mount("/dev/null", Null.init()) catch unreachable;
_ = vfs.mount("/dev/zero", Zero.init()) catch unreachable;
}
Loading

0 comments on commit d597931

Please sign in to comment.