Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 11 additions & 27 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,19 @@ const builtin = @import("builtin");
const Builder = std.build.Builder;
const LibExeObjStep = std.build.LibExeObjStep;
const Step = std.build.Step;
const Target = std.build.Target;
const Target = std.Target;
const CrossTarget = std.zig.CrossTarget;
const fs = std.fs;
const Mode = builtin.Mode;

pub fn build(b: *Builder) !void {
const target = Target{
.Cross = Target.Cross{
.arch = .i386,
.os = .freestanding,
.abi = .gnu,
.cpu_features = Target.CpuFeatures.initFromCpu(.i386, &builtin.Target.x86.cpu._i686),
},
const target = CrossTarget{
.cpu_arch = .i386,
.os_tag = .freestanding,
.cpu_model = .{ .explicit = &Target.x86.cpu._i686 },
};

const test_target = Target{
.Cross = Target.Cross{
.arch = .i386,
.os = .linux,
.abi = .gnu,
.cpu_features = Target.CpuFeatures.initFromCpu(.i386, &builtin.Target.x86.cpu._i686),
},
};

const target_str = switch (target.getArch()) {
const target_str = switch (target.getCpuArch()) {
.i386 => "x86",
else => unreachable,
};
Expand All @@ -50,7 +39,7 @@ pub fn build(b: *Builder) !void {
exec.addBuildOption(bool, "rt_test", rt_test);
exec.setBuildMode(build_mode);
exec.setLinkerScriptPath("link.ld");
exec.setTheTarget(target);
exec.setTarget(target);

const output_iso = try fs.path.join(b.allocator, &[_][]const u8{ b.exe_dir, "pluto.iso" });
const iso_dir_path = try fs.path.join(b.allocator, &[_][]const u8{ b.exe_dir, "iso" });
Expand All @@ -77,22 +66,17 @@ pub fn build(b: *Builder) !void {
unit_tests.addBuildOption([]const u8, "mock_path", mock_path);
unit_tests.addBuildOption([]const u8, "arch_mock_path", arch_mock_path);

const qemu_bin = switch (test_target.getArch()) {
.i386 => "qemu-i386",
else => unreachable,
};
if (builtin.os.tag != .windows) unit_tests.enable_qemu = true;

// We need this as the build as the make() doesn't handle it properly
unit_tests.setExecCmd(&[_]?[]const u8{ qemu_bin, null });
unit_tests.setTheTarget(test_target);
unit_tests.setTarget(.{ .cpu_arch = .i386 });

test_step.dependOn(&unit_tests.step);
}

const run_step = b.step("run", "Run with qemu");
const run_debug_step = b.step("debug-run", "Run with qemu and wait for a gdb connection");

const qemu_bin = switch (target.getArch()) {
const qemu_bin = switch (target.getCpuArch()) {
.i386 => "qemu-system-i386",
else => unreachable,
};
Expand Down
3 changes: 1 addition & 2 deletions src/kernel/arch/x86/gdt.zig
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,7 @@ pub fn setTssStack(esp0: u32) void {
///
pub fn init() void {
log.logInfo("Init gdt\n", .{});
defer log.logInfo("Done gdt\n", .{});
// Initiate TSS
gdt_entries[TSS_INDEX] = makeEntry(@ptrToInt(&tss), @sizeOf(TtsEntry) - 1, TSS_SEGMENT, NULL_FLAGS);

Expand All @@ -437,8 +438,6 @@ pub fn init() void {
// Load the TSS
arch.ltr(TSS_OFFSET);

log.logInfo("Done\n", .{});

if (build_options.rt_test) runtimeTests();
}

Expand Down
2 changes: 1 addition & 1 deletion src/kernel/arch/x86/idt.zig
Original file line number Diff line number Diff line change
Expand Up @@ -180,11 +180,11 @@ pub fn openInterruptGate(index: u8, handler: InterruptHandler) IdtError!void {
///
pub fn init() void {
log.logInfo("Init idt\n", .{});
defer log.logInfo("Done idt\n", .{});

idt_ptr.base = @ptrToInt(&idt_entries);

arch.lidt(&idt_ptr);
log.logInfo("Done\n", .{});

if (build_options.rt_test) runtimeTests();
}
Expand Down
3 changes: 1 addition & 2 deletions src/kernel/arch/x86/irq.zig
Original file line number Diff line number Diff line change
Expand Up @@ -129,14 +129,13 @@ pub fn registerIrq(irq_num: u8, handler: IrqHandler) IrqError!void {
///
pub fn init() void {
log.logInfo("Init irq\n", .{});
defer log.logInfo("Done irq\n", .{});

comptime var i = IRQ_OFFSET;
inline while (i < IRQ_OFFSET + 16) : (i += 1) {
openIrq(i, interrupts.getInterruptStub(i));
}

log.logInfo("Done\n", .{});

if (build_options.rt_test) runtimeTests();
}

Expand Down
3 changes: 1 addition & 2 deletions src/kernel/arch/x86/isr.zig
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ pub fn registerIsr(isr_num: u16, handler: IsrHandler) IsrError!void {
///
pub fn init() void {
log.logInfo("Init isr\n", .{});
defer log.logInfo("Done isr\n", .{});

comptime var i = 0;
inline while (i < 32) : (i += 1) {
Expand All @@ -243,8 +244,6 @@ pub fn init() void {

openIsr(syscalls.INTERRUPT, interrupts.getInterruptStub(syscalls.INTERRUPT));

log.logInfo("Done\n", .{});

if (build_options.rt_test) runtimeTests();
}

Expand Down
9 changes: 5 additions & 4 deletions src/kernel/arch/x86/paging.zig
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,8 @@ fn pageFault(state: *arch.InterruptContext) void {
///
pub fn init(mb_info: *multiboot.multiboot_info_t, mem_profile: *const MemProfile, allocator: *std.mem.Allocator) void {
log.logInfo("Init paging\n", .{});
defer log.logInfo("Done paging\n", .{});

// Calculate start and end of mapping
const v_start = std.mem.alignBackward(@ptrToInt(mem_profile.vaddr_start), PAGE_SIZE_4KB);
const v_end = std.mem.alignForward(@ptrToInt(mem_profile.vaddr_end) + mem_profile.fixed_alloc_size, PAGE_SIZE_4KB);
Expand Down Expand Up @@ -351,7 +353,6 @@ pub fn init(mb_info: *multiboot.multiboot_info_t, mem_profile: *const MemProfile
isr.registerIsr(isr.PAGE_FAULT, if (options.rt_test) rt_pageFault else pageFault) catch |e| {
panic(@errorReturnTrace(), "Failed to register page fault ISR: {}\n", .{e});
};
log.logInfo("Done\n", .{});

if (options.rt_test) runtimeTests(v_end);
}
Expand Down Expand Up @@ -410,7 +411,7 @@ test "virtToTableEntryIdx" {
}

test "mapDirEntry" {
var allocator = std.heap.direct_allocator;
var allocator = std.heap.page_allocator;
var dir: Directory = Directory{ .entries = [_]DirectoryEntry{0} ** ENTRIES_PER_DIRECTORY, .tables = [_]?*Table{null} ** ENTRIES_PER_DIRECTORY };
var phys: usize = 0 * PAGE_SIZE_4MB;
const phys_end: usize = phys + PAGE_SIZE_4MB;
Expand All @@ -425,7 +426,7 @@ test "mapDirEntry" {
}

test "mapDirEntry returns errors correctly" {
var allocator = std.heap.direct_allocator;
var allocator = std.heap.page_allocator;
var dir = Directory{ .entries = [_]DirectoryEntry{0} ** ENTRIES_PER_DIRECTORY, .tables = undefined };
testing.expectError(PagingError.UnalignedVirtAddresses, mapDirEntry(&dir, 1, PAGE_SIZE_4KB + 1, 0, PAGE_SIZE_4KB, allocator));
testing.expectError(PagingError.UnalignedPhysAddresses, mapDirEntry(&dir, 0, PAGE_SIZE_4KB, 1, PAGE_SIZE_4KB + 1, allocator));
Expand All @@ -435,7 +436,7 @@ test "mapDirEntry returns errors correctly" {
}

test "mapDir" {
var allocator = std.heap.direct_allocator;
var allocator = std.heap.page_allocator;
var dir = Directory{ .entries = [_]DirectoryEntry{0} ** ENTRIES_PER_DIRECTORY, .tables = [_]?*Table{null} ** ENTRIES_PER_DIRECTORY };
const phys_start: usize = PAGE_SIZE_4MB * 2;
const virt_start: usize = PAGE_SIZE_4MB * 4;
Expand Down
3 changes: 1 addition & 2 deletions src/kernel/arch/x86/pic.zig
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,7 @@ pub fn clearMask(irq_num: u8) void {
///
pub fn init() void {
log.logInfo("Init pic\n", .{});
defer log.logInfo("Done pic\n", .{});

// Initiate
sendCommandMaster(ICW1_INITIALISATION | ICW1_EXPECT_ICW4);
Expand Down Expand Up @@ -467,8 +468,6 @@ pub fn init() void {
// Clear the IRQ for the slave
clearMask(IRQ_CASCADE_FOR_SLAVE);

log.logInfo("Done\n", .{});

if (build_options.rt_test) runtimeTests();
}

Expand Down
4 changes: 2 additions & 2 deletions src/kernel/arch/x86/pit.zig
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,8 @@ pub fn getFrequency() u32 {
///
pub fn init() void {
log.logInfo("Init pit\n", .{});
defer log.logInfo("Done pit\n", .{});

// Set up counter 0 at 10000hz in a square wave mode counting in binary
const freq: u32 = 10000;
setupCounter(CounterSelect.Counter0, freq, OCW_MODE_SQUARE_WAVE_GENERATOR | OCW_BINARY_COUNT_BINARY) catch |e| {
Expand All @@ -389,8 +391,6 @@ pub fn init() void {
},
};

log.logInfo("Done\n", .{});

if (build_options.rt_test) runtimeTests();
}

Expand Down
7 changes: 2 additions & 5 deletions src/kernel/arch/x86/rtc.zig
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,7 @@ fn enableInterrupts() void {
///
pub fn init() void {
log.logInfo("Init rtc\n", .{});
defer log.logInfo("Done rtc\n", .{});

// Register the interrupt handler
irq.registerIrq(pic.IRQ_REAL_TIME_CLOCK, rtcHandler) catch |err| switch (err) {
Expand All @@ -276,16 +277,12 @@ pub fn init() void {
// Enable RTC interrupts
enableInterrupts();

// Read status register C to clear any interrupts that may have happened during set up
//const reg_c = cmos.readStatusRegister(cmos.StatusRegister.C, false);

// Can now enable interrupts
arch.enableInterrupts();

// Read status register C to clear any interrupts that may have happened during set up
const reg_c = cmos.readStatusRegister(cmos.StatusRegister.C, false);

log.logInfo("Done\n", .{});

if (build_options.rt_test) runtimeTests();
}

Expand Down
3 changes: 2 additions & 1 deletion src/kernel/arch/x86/syscalls.zig
Original file line number Diff line number Diff line change
Expand Up @@ -238,8 +238,9 @@ inline fn syscallArg(ctx: *arch.InterruptContext, comptime arg_idx: u32) u32 {
///
pub fn init() void {
log.logInfo("Init syscalls\n", .{});
defer log.logInfo("Done syscalls\n", .{});

isr.registerIsr(INTERRUPT, handle) catch unreachable;
log.logInfo("Done\n", .{});
if (options.rt_test) runtimeTests();
}

Expand Down
12 changes: 6 additions & 6 deletions src/kernel/bitmap.zig
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ pub fn Bitmap(comptime BitmapType: type) type {
}

test "setEntry" {
var bmp = try Bitmap(u32).init(31, std.heap.direct_allocator);
var bmp = try Bitmap(u32).init(31, std.heap.page_allocator);
testing.expectEqual(@as(u32, 31), bmp.num_free_entries);

try bmp.setEntry(0);
Expand All @@ -178,7 +178,7 @@ test "setEntry" {
}

test "clearEntry" {
var bmp = try Bitmap(u32).init(32, std.heap.direct_allocator);
var bmp = try Bitmap(u32).init(32, std.heap.page_allocator);
testing.expectEqual(@as(u32, 32), bmp.num_free_entries);

try bmp.setEntry(0);
Expand All @@ -204,7 +204,7 @@ test "clearEntry" {
}

test "setFirstFree multiple bitmaps" {
var bmp = try Bitmap(u8).init(9, std.heap.direct_allocator);
var bmp = try Bitmap(u8).init(9, std.heap.page_allocator);

// Allocate the first entry
testing.expectEqual(bmp.setFirstFree() orelse unreachable, 0);
Expand Down Expand Up @@ -239,7 +239,7 @@ test "setFirstFree multiple bitmaps" {
testing.expectEqual(bmp.bitmaps[1], 1);
}
test "setFirstFree" {
var bmp = try Bitmap(u32).init(32, std.heap.direct_allocator);
var bmp = try Bitmap(u32).init(32, std.heap.page_allocator);

// Allocate the first entry
testing.expectEqual(bmp.setFirstFree() orelse unreachable, 0);
Expand All @@ -260,7 +260,7 @@ test "setFirstFree" {
}

test "isSet" {
var bmp = try Bitmap(u32).init(32, std.heap.direct_allocator);
var bmp = try Bitmap(u32).init(32, std.heap.page_allocator);

bmp.bitmaps[0] = 1;
// Make sure that only the set entry is considered set
Expand Down Expand Up @@ -292,7 +292,7 @@ test "isSet" {
}

test "indexToBit" {
var bmp = try Bitmap(u8).init(10, std.heap.direct_allocator);
var bmp = try Bitmap(u8).init(10, std.heap.page_allocator);
testing.expectEqual(bmp.indexToBit(0), 1);
testing.expectEqual(bmp.indexToBit(1), 2);
testing.expectEqual(bmp.indexToBit(2), 4);
Expand Down
6 changes: 4 additions & 2 deletions src/kernel/kmain.zig
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,9 @@ export fn kmain(mb_info: *multiboot.multiboot_info_t, mb_magic: u32) void {
serial.init(serial.DEFAULT_BAUDRATE, serial.Port.COM1) catch |e| {
panic_root.panic(@errorReturnTrace(), "Failed to initialise serial: {}", .{e});
};
if (build_options.rt_test)
log.runtimeTests();

if (build_options.rt_test) log.runtimeTests();

const mem_profile = mem.init(mb_info);
var buffer = mem_profile.vaddr_end[0..mem_profile.fixed_alloc_size];
var fixed_allocator = std.heap.FixedBufferAllocator.init(buffer);
Expand All @@ -56,6 +57,7 @@ export fn kmain(mb_info: *multiboot.multiboot_info_t, mb_magic: u32) void {
tty.init();

log.logInfo("Init done\n", .{});

tty.print("Hello Pluto from kernel :)\n", .{});
// The panic runtime tests must run last as they never return
if (options.rt_test) panic_root.runtimeTests();
Expand Down
14 changes: 11 additions & 3 deletions src/kernel/log.zig
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
const serial = @import("serial.zig");
const fmt = @import("std").fmt;
const std = @import("std");
const fmt = std.fmt;

/// The errors that can occur when logging
const LoggingError = error{};

/// The OutStream for the format function
const OutStream = std.io.OutStream(void, LoggingError, logCallback);

pub const Level = enum {
INFO,
Expand All @@ -8,8 +15,9 @@ pub const Level = enum {
ERROR,
};

fn logCallback(context: void, str: []const u8) anyerror!void {
fn logCallback(context: void, str: []const u8) LoggingError!usize {
serial.writeBytes(str, serial.Port.COM1);
return str.len;
}

///
Expand All @@ -21,7 +29,7 @@ fn logCallback(context: void, str: []const u8) anyerror!void {
/// IN args: var - A struct of the parameters for the format string.
///
pub fn log(comptime level: Level, comptime format: []const u8, args: var) void {
fmt.format({}, anyerror, logCallback, "[" ++ @tagName(level) ++ "] " ++ format, args) catch unreachable;
fmt.format(OutStream{ .context = {} }, "[" ++ @tagName(level) ++ "] " ++ format, args) catch unreachable;
}

///
Expand Down
Loading