diff --git a/src/kernel/arch/x86/arch.zig b/src/kernel/arch/x86/arch.zig index 4aa782b..1372a37 100644 --- a/src/kernel/arch/x86/arch.zig +++ b/src/kernel/arch/x86/arch.zig @@ -339,11 +339,10 @@ pub fn initMem(mb_info: BootPayload) Allocator.Error!MemProfile { mem.ADDR_OFFSET = @ptrToInt(&KERNEL_ADDR_OFFSET); const mmap_addr = mb_info.mmap_addr; const num_mmap_entries = mb_info.mmap_length / @sizeOf(multiboot.multiboot_memory_map_t); - const vaddr_end = @ptrCast([*]u8, &KERNEL_VADDR_END); - var allocator = std.heap.FixedBufferAllocator.init(vaddr_end[0..mem.FIXED_ALLOC_SIZE]); - var reserved_physical_mem = std.ArrayList(mem.Range).init(&allocator.allocator); - var reserved_virtual_mem = std.ArrayList(mem.Map).init(&allocator.allocator); + const allocator = &mem.fixed_buffer_allocator.allocator; + var reserved_physical_mem = std.ArrayList(mem.Range).init(allocator); + var reserved_virtual_mem = std.ArrayList(mem.Map).init(allocator); const mem_map = @intToPtr([*]multiboot.multiboot_memory_map_t, mmap_addr)[0..num_mmap_entries]; // Reserve the unavailable sections from the multiboot memory map @@ -351,7 +350,10 @@ pub fn initMem(mb_info: BootPayload) Allocator.Error!MemProfile { if (entry.@"type" != multiboot.MULTIBOOT_MEMORY_AVAILABLE) { // If addr + len is greater than maxInt(usize) just ignore whatever comes after maxInt(usize) since it can't be addressed anyway const end: usize = if (entry.addr > std.math.maxInt(usize) - entry.len) std.math.maxInt(usize) else @intCast(usize, entry.addr + entry.len); - try reserved_physical_mem.append(.{ .start = @intCast(usize, entry.addr), .end = end }); + try reserved_physical_mem.append(.{ + .start = @intCast(usize, entry.addr), + .end = end, + }); } } @@ -360,8 +362,14 @@ pub fn initMem(mb_info: BootPayload) Allocator.Error!MemProfile { .start = @ptrToInt(mb_info), .end = @ptrToInt(mb_info) + @sizeOf(multiboot.multiboot_info_t), }; - const mb_physical = mem.Range{ .start = mem.virtToPhys(mb_region.start), .end = mem.virtToPhys(mb_region.end) }; - try reserved_virtual_mem.append(.{ .virtual = mb_region, .physical = mb_physical }); + const mb_physical = mem.Range{ + .start = mem.virtToPhys(mb_region.start), + .end = mem.virtToPhys(mb_region.end), + }; + try reserved_virtual_mem.append(.{ + .virtual = mb_region, + .physical = mb_physical, + }); // Map the tty buffer const tty_addr = mem.virtToPhys(tty.getVideoBufferAddress()); @@ -379,16 +387,56 @@ pub fn initMem(mb_info: BootPayload) Allocator.Error!MemProfile { // Map the boot modules const boot_modules = @intToPtr([*]multiboot.multiboot_mod_list, mem.physToVirt(mb_info.mods_addr))[0..mods_count]; - var modules = std.ArrayList(mem.Module).init(&allocator.allocator); + var modules = std.ArrayList(mem.Module).init(allocator); for (boot_modules) |module| { - const virtual = mem.Range{ .start = mem.physToVirt(module.mod_start), .end = mem.physToVirt(module.mod_end) }; - const physical = mem.Range{ .start = module.mod_start, .end = module.mod_end }; - try modules.append(.{ .region = virtual, .name = std.mem.span(mem.physToVirt(@intToPtr([*:0]u8, module.cmdline))) }); - try reserved_virtual_mem.append(.{ .physical = physical, .virtual = virtual }); + const virtual = mem.Range{ + .start = mem.physToVirt(module.mod_start), + .end = mem.physToVirt(module.mod_end), + }; + const physical = mem.Range{ + .start = module.mod_start, + .end = module.mod_end, + }; + try modules.append(.{ + .region = virtual, + .name = std.mem.span(mem.physToVirt(@intToPtr([*:0]u8, module.cmdline))), + }); + try reserved_virtual_mem.append(.{ + .physical = physical, + .virtual = virtual, + }); } + // Map the kernel stack + const kernel_stack_virt = mem.Range{ + .start = @ptrToInt(&KERNEL_STACK_START), + .end = @ptrToInt(&KERNEL_STACK_END), + }; + const kernel_stack_phy = mem.Range{ + .start = mem.virtToPhys(kernel_stack_virt.start), + .end = mem.virtToPhys(kernel_stack_virt.end), + }; + try reserved_virtual_mem.append(.{ + .virtual = kernel_stack_virt, + .physical = kernel_stack_phy, + }); + + // Map the rest of the kernel + const kernel_virt = mem.Range{ + .start = @ptrToInt(&KERNEL_VADDR_START), + .end = @ptrToInt(&KERNEL_STACK_START), + }; + const kernel_phy = mem.Range{ + .start = mem.virtToPhys(kernel_virt.start), + .end = mem.virtToPhys(kernel_virt.end), + }; + try reserved_virtual_mem.append(.{ + .virtual = kernel_virt, + .physical = kernel_phy, + }); + return MemProfile{ - .vaddr_end = vaddr_end, + .vaddr_end = @ptrCast([*]u8, &KERNEL_VADDR_END), .vaddr_start = @ptrCast([*]u8, &KERNEL_VADDR_START), .physaddr_end = @ptrCast([*]u8, &KERNEL_PHYSADDR_END), .physaddr_start = @ptrCast([*]u8, &KERNEL_PHYSADDR_START), @@ -397,7 +445,7 @@ pub fn initMem(mb_info: BootPayload) Allocator.Error!MemProfile { .modules = modules.items, .physical_reserved = reserved_physical_mem.items, .virtual_reserved = reserved_virtual_mem.items, - .fixed_allocator = allocator, + .fixed_allocator = mem.fixed_buffer_allocator, }; } @@ -452,12 +500,10 @@ pub fn initTaskStack(entry_point: usize, allocator: *Allocator) Allocator.Error! /// Initialise the architecture /// /// Arguments: -/// IN boot_payload: BootPayload - The multiboot information from the GRUB bootloader. /// IN mem_profile: *const MemProfile - The memory profile of the computer. Used to set up /// paging. -/// IN allocator: *Allocator - The allocator use to handle memory. /// -pub fn init(boot_payload: BootPayload, mem_profile: *const MemProfile, allocator: *Allocator) void { +pub fn init(mem_profile: *const MemProfile) void { gdt.init(); idt.init(); @@ -465,7 +511,7 @@ pub fn init(boot_payload: BootPayload, mem_profile: *const MemProfile, allocator isr.init(); irq.init(); - paging.init(boot_payload, mem_profile, allocator); + paging.init(mem_profile); pit.init(); rtc.init(); diff --git a/src/kernel/arch/x86/boot.zig b/src/kernel/arch/x86/boot.zig index 22d36a7..30280d4 100644 --- a/src/kernel/arch/x86/boot.zig +++ b/src/kernel/arch/x86/boot.zig @@ -101,6 +101,7 @@ export fn start_higher_half() callconv(.Naked) noreturn { asm volatile ( \\.extern KERNEL_STACK_END \\mov $KERNEL_STACK_END, %%esp + \\sub $32, %%esp \\mov %%esp, %%ebp ); diff --git a/src/kernel/arch/x86/paging.zig b/src/kernel/arch/x86/paging.zig index 328c2b2..a8306c6 100644 --- a/src/kernel/arch/x86/paging.zig +++ b/src/kernel/arch/x86/paging.zig @@ -387,9 +387,8 @@ fn pageFault(state: *arch.CpuState) u32 { /// /// Arguments: /// IN mem_profile: *const MemProfile - The memory profile of the system and kernel -/// IN allocator: *std.mem.Allocator - The allocator to use /// -pub fn init(mb_info: *multiboot.multiboot_info_t, mem_profile: *const MemProfile, allocator: *std.mem.Allocator) void { +pub fn init(mem_profile: *const MemProfile) void { std.log.info(.paging, "Init\n", .{}); defer std.log.info(.paging, "Done\n", .{}); @@ -401,7 +400,7 @@ pub fn init(mb_info: *multiboot.multiboot_info_t, mem_profile: *const MemProfile : : [addr] "{eax}" (dir_physaddr) ); - const v_end = std.mem.alignForward(@ptrToInt(mem_profile.vaddr_end) + mem.FIXED_ALLOC_SIZE, PAGE_SIZE_4KB); + const v_end = std.mem.alignForward(@ptrToInt(mem_profile.vaddr_end), PAGE_SIZE_4KB); switch (build_options.test_mode) { .Initialisation => runtimeTests(v_end), else => {}, diff --git a/src/kernel/heap.zig b/src/kernel/heap.zig index c17c55a..411ec5e 100644 --- a/src/kernel/heap.zig +++ b/src/kernel/heap.zig @@ -414,6 +414,8 @@ const FreeListAllocator = struct { var free_list = &(try FreeListAllocator.init(start, size)); var allocator = &free_list.allocator; + std.debug.warn("", .{}); + const alloc0 = try alloc(allocator, 64, 0, 0); const alloc0_addr = @ptrToInt(alloc0.ptr); // Should be at the start of the heap @@ -424,6 +426,8 @@ const FreeListAllocator = struct { testing.expectEqual(header.next_free, null); testing.expectEqual(free_list.first_free, header); + std.debug.warn("", .{}); + // 64 bytes aligned to 4 bytes const alloc1 = try alloc(allocator, 64, 4, 0); const alloc1_addr = @ptrToInt(alloc1.ptr); diff --git a/src/kernel/kmain.zig b/src/kernel/kmain.zig index 0aa2ac6..ac09fc5 100644 --- a/src/kernel/kmain.zig +++ b/src/kernel/kmain.zig @@ -61,7 +61,9 @@ export fn kmain(boot_payload: arch.BootPayload) void { log_root.init(serial_stream); - const mem_profile = arch.initMem(boot_payload) catch |e| panic_root.panic(@errorReturnTrace(), "Failed to initialise memory profile: {}", .{e}); + const mem_profile = arch.initMem(boot_payload) catch |e| { + panic_root.panic(@errorReturnTrace(), "Failed to initialise memory profile: {}", .{e}); + }; var fixed_allocator = mem_profile.fixed_allocator; panic_root.init(&mem_profile, &fixed_allocator.allocator) catch |e| { @@ -69,10 +71,12 @@ export fn kmain(boot_payload: arch.BootPayload) void { }; pmm.init(&mem_profile, &fixed_allocator.allocator); - kernel_vmm = vmm.init(&mem_profile, &fixed_allocator.allocator) catch |e| panic_root.panic(@errorReturnTrace(), "Failed to initialise kernel VMM: {}", .{e}); + kernel_vmm = vmm.init(&mem_profile, &fixed_allocator.allocator) catch |e| { + panic_root.panic(@errorReturnTrace(), "Failed to initialise kernel VMM: {}", .{e}); + }; std.log.info(.kmain, "Init arch " ++ @tagName(builtin.arch) ++ "\n", .{}); - arch.init(boot_payload, &mem_profile, &fixed_allocator.allocator); + arch.init(&mem_profile); std.log.info(.kmain, "Arch init done\n", .{}); // Give the kernel heap 10% of the available memory. This can be fine-tuned as time goes on. diff --git a/src/kernel/mem.zig b/src/kernel/mem.zig index f3896e3..6579db3 100644 --- a/src/kernel/mem.zig +++ b/src/kernel/mem.zig @@ -53,7 +53,10 @@ pub const MemProfile = struct { }; /// The size of the fixed allocator used before the heap is set up. Set to 1MiB. -pub const FIXED_ALLOC_SIZE: usize = 1024 * 1024; +pub var fixed_buffer: [1024 * 1024]u8 = undefined; + +/// The fixed allocator used before the heap is set up. +pub var fixed_buffer_allocator: std.heap.FixedBufferAllocator = std.heap.FixedBufferAllocator.init(fixed_buffer[0..]); /// The kernel's virtual address offset. It's assigned in the init function and this file's tests. /// We can't just use KERNEL_ADDR_OFFSET since using externs in the virtToPhys test is broken in diff --git a/src/kernel/panic.zig b/src/kernel/panic.zig index 5c286f9..5ba6885 100644 --- a/src/kernel/panic.zig +++ b/src/kernel/panic.zig @@ -6,6 +6,7 @@ const multiboot = @import("multiboot.zig"); const mem = @import("mem.zig"); const build_options = @import("build_options"); const ArrayList = std.ArrayList; +const Allocator = std.mem.Allocator; const testing = std.testing; /// The possible errors from panic code @@ -31,12 +32,12 @@ const SymbolMap = struct { /// Initialise an empty symbol map. /// /// Arguments: - /// IN allocator: *std.mem.Allocator - The allocator to use to initialise the array list. + /// IN allocator: *Allocator - The allocator to use to initialise the array list. /// /// Return: SymbolMap /// The symbol map. /// - pub fn init(allocator: *std.mem.Allocator) SymbolMap { + pub fn init(allocator: *Allocator) SymbolMap { return SymbolMap{ .symbols = ArrayList(MapEntry).init(allocator), }; @@ -56,14 +57,23 @@ const SymbolMap = struct { /// IN name: []const u8 - The name of the entry. /// IN addr: usize - The address for the entry. /// - /// Error: std.mem.Allocator.Error - /// * - See ArrayList.append + /// Error: Allocator.Error + /// error.OutOfMemory - If there isn't enough memory to append a map entry. /// - pub fn add(self: *SymbolMap, name: []const u8, addr: usize) !void { + pub fn add(self: *SymbolMap, name: []const u8, addr: usize) Allocator.Error!void { try self.addEntry(MapEntry{ .addr = addr, .func_name = name }); } - pub fn addEntry(self: *SymbolMap, entry: MapEntry) !void { + /// + /// Add a symbol map entry. + /// + /// Arguments: + /// IN entry: MapEntry - The entry. + /// + /// Error: Allocator.Error + /// error.OutOfMemory - If there isn't enough memory to append a map entry. + /// + pub fn addEntry(self: *SymbolMap, entry: MapEntry) Allocator.Error!void { try self.symbols.append(entry); } @@ -104,6 +114,168 @@ fn logTraceAddress(addr: usize) void { std.log.emerg(.panic, "{x}: {}\n", .{ addr, str }); } +/// +/// Parse a hexadecimal address from the pointer up until the end pointer. Must be terminated by a +/// whitespace character. +/// +/// Arguments: +/// IN/OUT ptr: *[*]const u8 - The address at which to start looking, updated after all +/// characters have been consumed. +/// IN end: *const u8 - The end address at which to start looking. A whitespace character must +/// be found before this. +/// +/// Return: usize +/// The address parsed. +/// +/// Error: PanicError || std.fmt.ParseIntError +/// PanicError.InvalidSymbolFile - A terminating whitespace wasn't found before the end address. +/// std.fmt.ParseIntError - See std.fmt.parseInt +/// +fn parseAddr(ptr: *[*]const u8, end: *const u8) (PanicError || std.fmt.ParseIntError)!usize { + const addr_start = ptr.*; + ptr.* = try parseNonWhitespace(ptr.*, end); + const len = @ptrToInt(ptr.*) - @ptrToInt(addr_start); + const addr_str = addr_start[0..len]; + return std.fmt.parseInt(usize, addr_str, 16); +} + +/// +/// Parse a single character. The address given cannot be greater than or equal to the end address +/// given. +/// +/// Arguments: +/// IN ptr: [*]const u8 - The address at which to get the character from. +/// IN end: *const u8 - The end address at which to start looking. ptr cannot be greater than or +/// equal to this. +/// +/// Return: u8 +/// The character parsed. +/// +/// Error: PanicError +/// PanicError.InvalidSymbolFile - The address given is greater than or equal to the end address. +/// +fn parseChar(ptr: [*]const u8, end: *const u8) PanicError!u8 { + if (@ptrToInt(ptr) >= @ptrToInt(end)) { + return PanicError.InvalidSymbolFile; + } + return ptr[0]; +} + +/// +/// Parse until a non-whitespace character. Must be terminated by a non-whitespace character before +/// the end address. +/// +/// Arguments: +/// IN ptr: [*]const u8 - The address at which to start looking. +/// IN end: *const u8 - The end address at which to start looking. A non-whitespace character +/// must be found before this. +/// +/// Return: [*]const u8 +/// ptr plus the number of whitespace characters consumed. +/// +/// Error: PanicError +/// PanicError.InvalidSymbolFile - A terminating non-whitespace character wasn't found before +/// the end address. +/// +fn parseWhitespace(ptr: [*]const u8, end: *const u8) PanicError![*]const u8 { + var i: u32 = 0; + while (std.fmt.isWhiteSpace(try parseChar(ptr + i, end))) : (i += 1) {} + return ptr + i; +} + +/// +/// Parse until a whitespace character. Must be terminated by a whitespace character before the end +/// address. +/// +/// Arguments: +/// IN ptr: [*]const u8 - The address at which to start looking. +/// IN end: *const u8 - The end address at which to start looking. A whitespace character must +/// be found before this. +/// +/// Return: [*]const u8 +/// ptr plus the number of non-whitespace characters consumed. +/// +/// Error: PanicError +/// PanicError.InvalidSymbolFile - A terminating whitespace character wasn't found before the +/// end address. +/// +fn parseNonWhitespace(ptr: [*]const u8, end: *const u8) PanicError![*]const u8 { + var i: u32 = 0; + while (!std.fmt.isWhiteSpace(try parseChar(ptr + i, end))) : (i += 1) {} + return ptr + i; +} + +/// +/// Parse until a newline character. Must be terminated by a newline character before the end +/// address. +/// +/// Arguments: +/// IN ptr: [*]const u8 - The address at which to start looking. +/// IN end: *const u8 - The end address at which to start looking. A newline character must +/// be found before this. +/// +/// Return: [*]const u8 +/// ptr plus the number of non-newline characters consumed. +/// +/// Error: PanicError +/// PanicError.InvalidSymbolFile - A terminating newline character wasn't found before the +/// end address. +/// +fn parseNonNewLine(ptr: [*]const u8, end: *const u8) PanicError![*]const u8 { + var i: u32 = 0; + while ((try parseChar(ptr + i, end)) != '\n') : (i += 1) {} + return ptr + i; +} + +/// +/// Parse a name from the pointer up until the end pointer. Must be terminated by a whitespace +/// character. +/// +/// Arguments: +/// IN/OUT ptr: *[*]const u8 - The address at which to start looking, updated after all +/// characters have been consumed. +/// IN end: *const u8 - The end address at which to start looking. A whitespace character must +/// be found before this. +/// +/// Return: []const u8 +/// The name parsed. +/// +/// Error: PanicError +/// PanicError.InvalidSymbolFile - A terminating whitespace wasn't found before the end address. +/// +fn parseName(ptr: *[*]const u8, end: *const u8) PanicError![]const u8 { + const name_start = ptr.*; + ptr.* = try parseNonNewLine(ptr.*, end); + const len = @ptrToInt(ptr.*) - @ptrToInt(name_start); + return name_start[0..len]; +} + +/// +/// Parse a symbol map entry from the pointer up until the end pointer, +/// in the format of '\d+\w+[a-zA-Z0-9]+'. Must be terminated by a whitespace character. +/// +/// Arguments: +/// IN/OUT ptr: *[*]const u8 - The address at which to start looking, updated once after the +/// address has been consumed and once again after the name has been consumed. +/// IN end: *const u8 - The end address at which to start looking. A whitespace character must +/// be found before this. +/// +/// Return: MapEntry +/// The entry parsed. +/// +/// Error: PanicError || std.fmt.ParseIntError +/// PanicError.InvalidSymbolFile - A terminating whitespace wasn't found before the end address. +/// std.fmt.ParseIntError - See parseAddr. +/// +fn parseMapEntry(start: *[*]const u8, end: *const u8) (PanicError || std.fmt.ParseIntError)!MapEntry { + var ptr = try parseWhitespace(start.*, end); + defer start.* = ptr; + const addr = try parseAddr(&ptr, end); + ptr = try parseWhitespace(ptr, end); + const name = try parseName(&ptr, end); + return MapEntry{ .addr = addr, .func_name = name }; +} + pub fn panic(trace: ?*builtin.StackTrace, comptime format: []const u8, args: anytype) noreturn { @setCold(true); std.log.emerg(.panic, "Kernel panic: " ++ format ++ "\n", args); @@ -125,168 +297,6 @@ pub fn panic(trace: ?*builtin.StackTrace, comptime format: []const u8, args: any arch.haltNoInterrupts(); } -/// -/// Parse a hexadecimal address from the pointer up until the end pointer. Must be terminated by a -/// whitespace character. -/// -/// Arguments: -/// IN/OUT ptr: *[*]const u8 - The address at which to start looking, updated after all -/// characters have been consumed. -/// IN end: *const u8 - The end address at which to start looking. A whitespace character must -/// be found before this. -/// -/// Return: usize -/// The address parsed. -/// -/// Error: PanicError || std.fmt.ParseUnsignedError -/// PanicError.InvalidSymbolFile: A terminating whitespace wasn't found before the end address. -/// std.fmt.ParseUnsignedError: See std.fmt.parseInt -/// -fn parseAddr(ptr: *[*]const u8, end: *const u8) !usize { - const addr_start = ptr.*; - ptr.* = try parseNonWhitespace(ptr.*, end); - const len = @ptrToInt(ptr.*) - @ptrToInt(addr_start); - const addr_str = addr_start[0..len]; - return try std.fmt.parseInt(usize, addr_str, 16); -} - -/// -/// Parse a single character. The address given cannot be greater than or equal to the end address -/// given. -/// -/// Arguments: -/// IN ptr: [*]const u8 - The address at which to get the character from. -/// IN end: *const u8 - The end address at which to start looking. ptr cannot be greater than or -/// equal to this. -/// -/// Return: u8 -/// The character parsed. -/// -/// Error: PanicError -/// PanicError.InvalidSymbolFile: The address given is greater than or equal to the end address. -/// -fn parseChar(ptr: [*]const u8, end: *const u8) PanicError!u8 { - if (@ptrToInt(ptr) >= @ptrToInt(end)) { - return PanicError.InvalidSymbolFile; - } - return ptr[0]; -} - -/// -/// Parse until a non-whitespace character. Must be terminated by a non-whitespace character before -/// the end address. -/// -/// Arguments: -/// IN ptr: [*]const u8 - The address at which to start looking. -/// IN end: *const u8 - The end address at which to start looking. A non-whitespace character -/// must be found before this. -/// -/// Return: [*]const u8 -/// ptr plus the number of whitespace characters consumed. -/// -/// Error: PanicError -/// PanicError.InvalidSymbolFile: A terminating non-whitespace character wasn't found before the -/// end address. -/// -fn parseWhitespace(ptr: [*]const u8, end: *const u8) PanicError![*]const u8 { - var i: u32 = 0; - while (std.fmt.isWhiteSpace(try parseChar(ptr + i, end))) : (i += 1) {} - return ptr + i; -} - -/// -/// Parse until a whitespace character. Must be terminated by a whitespace character before the end -/// address. -/// -/// Arguments: -/// IN ptr: [*]const u8 - The address at which to start looking. -/// IN end: *const u8 - The end address at which to start looking. A whitespace character must -/// be found before this. -/// -/// Return: [*]const u8 -/// ptr plus the number of non-whitespace characters consumed. -/// -/// Error: PanicError -/// PanicError.InvalidSymbolFile: A terminating whitespace character wasn't found before the end -/// address. -/// -fn parseNonWhitespace(ptr: [*]const u8, end: *const u8) PanicError![*]const u8 { - var i: u32 = 0; - while (!std.fmt.isWhiteSpace(try parseChar(ptr + i, end))) : (i += 1) {} - return ptr + i; -} - -/// -/// Parse until a newline character. Must be terminated by a newline character before the end -/// address. -/// -/// Arguments: -/// IN ptr: [*]const u8 - The address at which to start looking. -/// IN end: *const u8 - The end address at which to start looking. A newline character must -/// be found before this. -/// -/// Return: [*]const u8 -/// ptr plus the number of non-newline characters consumed. -/// -/// Error: PanicError -/// PanicError.InvalidSymbolFile: A terminating newline character wasn't found before the end -/// address. -/// -fn parseNonNewLine(ptr: [*]const u8, end: *const u8) PanicError![*]const u8 { - var i: u32 = 0; - while ((try parseChar(ptr + i, end)) != '\n') : (i += 1) {} - return ptr + i; -} - -/// -/// Parse a name from the pointer up until the end pointer. Must be terminated by a whitespace -/// character. -/// -/// Arguments: -/// IN/OUT ptr: *[*]const u8 - The address at which to start looking, updated after all -/// characters have been consumed. -/// IN end: *const u8 - The end address at which to start looking. A whitespace character must -/// be found before this. -/// -/// Return: []const u8 -/// The name parsed. -/// -/// Error: PanicError -/// PanicError.InvalidSymbolFile: A terminating whitespace wasn't found before the end address. -/// -fn parseName(ptr: *[*]const u8, end: *const u8) PanicError![]const u8 { - const name_start = ptr.*; - ptr.* = try parseNonNewLine(ptr.*, end); - const len = @ptrToInt(ptr.*) - @ptrToInt(name_start); - return name_start[0..len]; -} - -/// -/// Parse a symbol map entry from the pointer up until the end pointer, -/// in the format of '\d+\w+[a-zA-Z0-9]+'. Must be terminated by a whitespace character. -/// -/// Arguments: -/// IN/OUT ptr: *[*]const u8 - The address at which to start looking, updated once after the -/// address has been consumed and once again after the name has been consumed. -/// IN end: *const u8 - The end address at which to start looking. A whitespace character must -/// be found before this. -/// -/// Return: MapEntry -/// The entry parsed. -/// -/// Error: PanicError || std.fmt.ParseUnsignedError -/// PanicError.InvalidSymbolFile: A terminating whitespace wasn't found before the end address. -/// std.fmt.ParseUnsignedError: See parseAddr. -/// -fn parseMapEntry(start: *[*]const u8, end: *const u8) !MapEntry { - var ptr = try parseWhitespace(start.*, end); - defer start.* = ptr; - const addr = try parseAddr(&ptr, end); - ptr = try parseWhitespace(ptr, end); - const name = try parseName(&ptr, end); - return MapEntry{ .addr = addr, .func_name = name }; -} - /// /// Initialise the panic subsystem by looking for a boot module called "kernel.map" and loading the /// symbols from it. Exits early if no such module was found. @@ -294,13 +304,14 @@ fn parseMapEntry(start: *[*]const u8, end: *const u8) !MapEntry { /// Arguments: /// IN mem_profile: *const mem.MemProfile - The memory profile from which to get the loaded boot /// modules. -/// IN allocator: *std.mem.Allocator - The allocator to use to store the symbol map. +/// IN allocator: *Allocator - The allocator to use to store the symbol map. /// -/// Error: PanicError || std.fmt.ParseUnsignedError -/// PanicError.InvalidSymbolFile: A terminating whitespace wasn't found before the end address. -/// std.fmt.ParseUnsignedError: See parseMapEntry. +/// Error: PanicError || Allocator.Error || std.fmt.ParseIntError +/// PanicError.InvalidSymbolFile - A terminating whitespace wasn't found before the end address. +/// Allocator.Error.OutOfMemory - If there wasn't enough memory. +/// std.fmt.ParseIntError - See parseMapEntry. /// -pub fn init(mem_profile: *const mem.MemProfile, allocator: *std.mem.Allocator) !void { +pub fn init(mem_profile: *const mem.MemProfile, allocator: *Allocator) (PanicError || Allocator.Error || std.fmt.ParseIntError)!void { std.log.info(.panic, "Init\n", .{}); defer std.log.info(.panic, "Done\n", .{}); diff --git a/src/kernel/pmm.zig b/src/kernel/pmm.zig index 7036233..65c24d0 100644 --- a/src/kernel/pmm.zig +++ b/src/kernel/pmm.zig @@ -7,6 +7,7 @@ const MemProfile = (if (is_test) @import(mock_path ++ "mem_mock.zig") else @impo const testing = std.testing; const panic = @import("panic.zig").panic; const Bitmap = @import("bitmap.zig").Bitmap; +const Allocator = std.mem.Allocator; const PmmBitmap = Bitmap(u32); @@ -94,16 +95,18 @@ pub fn blocksFree() usize { /// /// Arguments: /// IN mem: *const MemProfile - The system's memory profile. -/// IN allocator: *std.mem.Allocator - The allocator to use to allocate the bitmaps. +/// IN allocator: *Allocator - The allocator to use to allocate the bitmaps. /// -pub fn init(mem: *const MemProfile, allocator: *std.mem.Allocator) void { +pub fn init(mem_profile: *const MemProfile, allocator: *Allocator) void { std.log.info(.pmm, "Init\n", .{}); defer std.log.info(.pmm, "Done\n", .{}); - bitmap = PmmBitmap.init(mem.mem_kb * 1024 / BLOCK_SIZE, allocator) catch @panic("Bitmap allocation failed"); + bitmap = PmmBitmap.init(mem_profile.mem_kb * 1024 / BLOCK_SIZE, allocator) catch |e| { + panic(@errorReturnTrace(), "Bitmap allocation failed: {}\n", .{e}); + }; // Occupy the regions of memory that the memory map describes as reserved - for (mem.physical_reserved) |entry| { + for (mem_profile.physical_reserved) |entry| { var addr = std.mem.alignBackward(entry.start, BLOCK_SIZE); var end = entry.end - 1; // If the end address can be aligned without overflowing then align it @@ -120,7 +123,7 @@ pub fn init(mem: *const MemProfile, allocator: *std.mem.Allocator) void { } switch (build_options.test_mode) { - .Initialisation => runtimeTests(mem, allocator), + .Initialisation => runtimeTests(mem_profile, allocator), else => {}, } } @@ -200,10 +203,10 @@ test "setAddr and isSet" { /// Allocate all blocks and make sure they don't overlap with any reserved addresses. /// /// Arguments: -/// IN mem: *const MemProfile - The memory profile to check for reserved memory regions. -/// IN/OUT allocator: *std.mem.Allocator - The allocator to use when needing to create intermediate structures used for testing +/// IN mem_profile: *const MemProfile - The memory profile to check for reserved memory regions. +/// IN/OUT allocator: *Allocator - The allocator to use when needing to create intermediate structures used for testing /// -fn runtimeTests(mem: *const MemProfile, allocator: *std.mem.Allocator) void { +fn runtimeTests(mem_profile: *const MemProfile, allocator: *Allocator) void { // Make sure that occupied memory can't be allocated var prev_alloc: usize = std.math.maxInt(usize); var alloc_list = std.ArrayList(usize).init(allocator); @@ -213,17 +216,21 @@ fn runtimeTests(mem: *const MemProfile, allocator: *std.mem.Allocator) void { panic(null, "FAILURE: PMM allocated the same address twice: 0x{x}", .{alloced}); } prev_alloc = alloced; - for (mem.physical_reserved) |entry| { + for (mem_profile.physical_reserved) |entry| { var addr = std.mem.alignBackward(@intCast(usize, entry.start), BLOCK_SIZE); if (addr == alloced) { panic(null, "FAILURE: PMM allocated an address that should be reserved by the memory map: 0x{x}", .{addr}); } } - alloc_list.append(alloced) catch |e| panic(@errorReturnTrace(), "FAILURE: Failed to add PMM allocation to list: {}", .{e}); + alloc_list.append(alloced) catch |e| { + panic(@errorReturnTrace(), "FAILURE: Failed to add PMM allocation to list: {}", .{e}); + }; } // Clean up for (alloc_list.items) |alloced| { - free(alloced) catch |e| panic(@errorReturnTrace(), "FAILURE: Failed freeing allocation in PMM rt test: {}", .{e}); + free(alloced) catch |e| { + panic(@errorReturnTrace(), "FAILURE: Failed freeing allocation in PMM rt test: {}", .{e}); + }; } std.log.info(.pmm, "Tested allocation\n", .{}); } diff --git a/src/kernel/vmm.zig b/src/kernel/vmm.zig index acd201f..36ad9bc 100644 --- a/src/kernel/vmm.zig +++ b/src/kernel/vmm.zig @@ -9,6 +9,7 @@ const mem = if (is_test) @import(mock_path ++ "mem_mock.zig") else @import("mem. const tty = @import("tty.zig"); const panic = @import("panic.zig").panic; const arch = @import("arch.zig").internals; +const Allocator = std.mem.Allocator; /// Attributes for a virtual memory allocation pub const Attributes = struct { @@ -63,13 +64,13 @@ pub fn Mapper(comptime Payload: type) type { /// IN physical_start: usize - The start of the physical memory to map to /// IN physical_end: usize - The end of the physical memory to map to /// IN attrs: Attributes - The attributes to apply to this region of memory - /// IN/OUT allocator: std.mem.Allocator - The allocator to use when mapping, if required + /// IN/OUT allocator: Allocator - The allocator to use when mapping, if required /// IN spec: Payload - The payload to pass to the mapper /// - /// Error: std.mem.AllocatorError || MapperError + /// Error: AllocatorError || MapperError /// The causes depend on the mapper used /// - mapFn: fn (virtual_start: usize, virtual_end: usize, physical_start: usize, physical_end: usize, attrs: Attributes, allocator: *std.mem.Allocator, spec: Payload) (std.mem.Allocator.Error || MapperError)!void, + mapFn: fn (virtual_start: usize, virtual_end: usize, physical_start: usize, physical_end: usize, attrs: Attributes, allocator: *Allocator, spec: Payload) (Allocator.Error || MapperError)!void, /// /// Unmap a region (can span more than one block) of virtual memory from its physical memory. After a call to this function, the memory should not be accessible without error. @@ -79,10 +80,10 @@ pub fn Mapper(comptime Payload: type) type { /// IN virtual_end: usize - The end of the virtual region to unmap /// IN spec: Payload - The payload to pass to the mapper /// - /// Error: std.mem.AllocatorError || MapperError + /// Error: AllocatorError || MapperError /// The causes depend on the mapper used /// - unmapFn: fn (virtual_start: usize, virtual_end: usize, spec: Payload) (std.mem.Allocator.Error || MapperError)!void, + unmapFn: fn (virtual_start: usize, virtual_end: usize, spec: Payload) (Allocator.Error || MapperError)!void, }; } @@ -132,7 +133,7 @@ pub fn VirtualMemoryManager(comptime Payload: type) type { end: usize, /// The allocator to use when allocating and freeing regions - allocator: *std.mem.Allocator, + allocator: *Allocator, /// All allocations that have been made with this manager allocations: std.hash_map.AutoHashMap(usize, Allocation), @@ -151,17 +152,17 @@ pub fn VirtualMemoryManager(comptime Payload: type) type { /// Arguments: /// IN start: usize - The start of the memory region to manage /// IN end: usize - The end of the memory region to manage. Must be greater than the start - /// IN/OUT allocator: *std.mem.Allocator - The allocator to use when allocating and freeing regions + /// IN/OUT allocator: *Allocator - The allocator to use when allocating and freeing regions /// IN mapper: Mapper - The mapper to use when allocating and freeing regions /// IN payload: Payload - The payload data to be passed to the mapper /// /// Return: Self /// The manager constructed /// - /// Error: std.mem.Allocator.Error - /// std.mem.Allocator.Error.OutOfMemory - The allocator cannot allocate the memory required + /// Error: Allocator.Error + /// error.OutOfMemory - The allocator cannot allocate the memory required /// - pub fn init(start: usize, end: usize, allocator: *std.mem.Allocator, mapper: Mapper(Payload), payload: Payload) std.mem.Allocator.Error!Self { + pub fn init(start: usize, end: usize, allocator: *Allocator, mapper: Mapper(Payload), payload: Payload) Allocator.Error!Self { const size = end - start; var bmp = try bitmap.Bitmap(usize).init(std.mem.alignForward(size, pmm.BLOCK_SIZE) / pmm.BLOCK_SIZE, allocator); return Self{ @@ -189,7 +190,7 @@ pub fn VirtualMemoryManager(comptime Payload: type) type { /// Bitmap(u32).Error.OutOfBounds - The address given is outside of the memory managed /// pub fn isSet(self: *const Self, virt: usize) bitmap.Bitmap(u32).BitmapError!bool { - return try self.bmp.isSet((virt - self.start) / BLOCK_SIZE); + return self.bmp.isSet((virt - self.start) / BLOCK_SIZE); } /// @@ -201,21 +202,22 @@ pub fn VirtualMemoryManager(comptime Payload: type) type { /// IN physical: ?mem.Range - The physical region to map to or null if only the virtual region is to be set /// IN attrs: Attributes - The attributes to apply to the memory regions /// - /// Error: VmmError || Bitmap(u32).BitmapError || std.mem.Allocator.Error || MapperError + /// Error: VmmError || Bitmap(u32).BitmapError || Allocator.Error || MapperError /// VmmError.AlreadyAllocated - The virtual address has already been allocated /// VmmError.PhysicalAlreadyAllocated - The physical address has already been allocated /// VmmError.PhysicalVirtualMismatch - The physical region and virtual region are of different sizes /// VmmError.InvalidVirtAddresses - The start virtual address is greater than the end address /// VmmError.InvalidPhysicalAddresses - The start physical address is greater than the end address /// Bitmap.BitmapError.OutOfBounds - The physical or virtual addresses are out of bounds - /// std.mem.Allocator.Error.OutOfMemory - Allocating the required memory failed + /// Allocator.Error.OutOfMemory - Allocating the required memory failed /// MapperError.* - The causes depend on the mapper used /// - pub fn set(self: *Self, virtual: mem.Range, physical: ?mem.Range, attrs: Attributes) (VmmError || bitmap.Bitmap(u32).BitmapError || std.mem.Allocator.Error || MapperError)!void { + pub fn set(self: *Self, virtual: mem.Range, physical: ?mem.Range, attrs: Attributes) (VmmError || bitmap.Bitmap(u32).BitmapError || Allocator.Error || MapperError)!void { var virt = virtual.start; while (virt < virtual.end) : (virt += BLOCK_SIZE) { - if (try self.isSet(virt)) + if (try self.isSet(virt)) { return VmmError.AlreadyAllocated; + } } if (virtual.start > virtual.end) { return VmmError.InvalidVirtAddresses; @@ -266,12 +268,13 @@ pub fn VirtualMemoryManager(comptime Payload: type) type { /// Return: ?usize /// The address at the start of the allocated region, or null if no region could be allocated due to a lack of contiguous blocks. /// - /// Error: std.mem.Allocator.Error - /// std.mem.AllocatorError.OutOfMemory: The required amount of memory couldn't be allocated + /// Error: Allocator.Error + /// error.OutOfMemory: The required amount of memory couldn't be allocated /// - pub fn alloc(self: *Self, num: usize, attrs: Attributes) std.mem.Allocator.Error!?usize { - if (num == 0) + pub fn alloc(self: *Self, num: usize, attrs: Attributes) Allocator.Error!?usize { + if (num == 0) { return null; + } // Ensure that there is both enough physical and virtual address space free if (pmm.blocksFree() >= num and self.bmp.num_free_entries >= num) { // The virtual address space must be contiguous @@ -312,19 +315,23 @@ pub fn VirtualMemoryManager(comptime Payload: type) type { const entry = (vaddr - self.start) / BLOCK_SIZE; if (try self.bmp.isSet(entry)) { // There will be an allocation associated with this virtual address - const allocation = self.allocations.get(vaddr) orelse unreachable; + const allocation = self.allocations.get(vaddr).?; const physical = allocation.physical; defer physical.deinit(); const num_physical_allocations = physical.items.len; for (physical.items) |block, i| { // Clear the address space entry and free the physical memory try self.bmp.clearEntry(entry + i); - pmm.free(block) catch |e| panic(@errorReturnTrace(), "Failed to free PMM reserved memory at 0x{X}: {}\n", .{ block * BLOCK_SIZE, e }); + pmm.free(block) catch |e| { + panic(@errorReturnTrace(), "Failed to free PMM reserved memory at 0x{X}: {}\n", .{ block * BLOCK_SIZE, e }); + }; } // Unmap the entire range const region_start = entry * BLOCK_SIZE; const region_end = (entry + num_physical_allocations) * BLOCK_SIZE; - self.mapper.unmapFn(region_start, region_end, self.payload) catch |e| panic(@errorReturnTrace(), "Failed to unmap VMM reserved memory from 0x{X} to 0x{X}: {}\n", .{ region_start, region_end, e }); + self.mapper.unmapFn(region_start, region_end, self.payload) catch |e| { + panic(@errorReturnTrace(), "Failed to unmap VMM reserved memory from 0x{X} to 0x{X}: {}\n", .{ region_start, region_end, e }); + }; // The allocation is freed so remove from the map self.allocations.removeAssertDiscard(vaddr); } else { @@ -339,31 +346,33 @@ pub fn VirtualMemoryManager(comptime Payload: type) type { /// /// Arguments: /// IN mem_profile: *const mem.MemProfile - The system's memory profile. This is used to find the kernel code region and boot modules -/// IN/OUT allocator: *std.mem.Allocator - The allocator to use when needing to allocate memory +/// IN/OUT allocator: *Allocator - The allocator to use when needing to allocate memory /// /// Return: VirtualMemoryManager /// The virtual memory manager created with all reserved virtual regions allocated /// -/// Error: std.mem.Allocator.Error -/// std.mem.Allocator.Error.OutOfMemory - The allocator cannot allocate the memory required +/// Error: Allocator.Error +/// error.OutOfMemory - The allocator cannot allocate the memory required /// -pub fn init(mem_profile: *const mem.MemProfile, allocator: *std.mem.Allocator) std.mem.Allocator.Error!VirtualMemoryManager(arch.VmmPayload) { - std.log.info(.tty, "Init\n", .{}); - defer std.log.info(.tty, "Done\n", .{}); +pub fn init(mem_profile: *const mem.MemProfile, allocator: *Allocator) Allocator.Error!VirtualMemoryManager(arch.VmmPayload) { + std.log.info(.vmm, "Init\n", .{}); + defer std.log.info(.vmm, "Done\n", .{}); var vmm = try VirtualMemoryManager(arch.VmmPayload).init(@ptrToInt(&KERNEL_ADDR_OFFSET), 0xFFFFFFFF, allocator, arch.VMM_MAPPER, arch.KERNEL_VMM_PAYLOAD); - // Map in kernel - // Calculate start and end of mapping - const v_start = std.mem.alignBackward(@ptrToInt(mem_profile.vaddr_start), BLOCK_SIZE); - const v_end = std.mem.alignForward(@ptrToInt(mem_profile.vaddr_end) + mem.FIXED_ALLOC_SIZE, BLOCK_SIZE); - const p_start = std.mem.alignBackward(@ptrToInt(mem_profile.physaddr_start), BLOCK_SIZE); - const p_end = std.mem.alignForward(@ptrToInt(mem_profile.physaddr_end) + mem.FIXED_ALLOC_SIZE, BLOCK_SIZE); - vmm.set(.{ .start = v_start, .end = v_end }, mem.Range{ .start = p_start, .end = p_end }, .{ .kernel = true, .writable = false, .cachable = true }) catch |e| panic(@errorReturnTrace(), "Failed mapping kernel code in VMM: {}", .{e}); - + // Map all the reserved virtual addresses. for (mem_profile.virtual_reserved) |entry| { - const virtual = mem.Range{ .start = std.mem.alignBackward(entry.virtual.start, BLOCK_SIZE), .end = std.mem.alignForward(entry.virtual.end, BLOCK_SIZE) }; - const physical: ?mem.Range = if (entry.physical) |phys| mem.Range{ .start = std.mem.alignBackward(phys.start, BLOCK_SIZE), .end = std.mem.alignForward(phys.end, BLOCK_SIZE) } else null; + const virtual = mem.Range{ + .start = std.mem.alignBackward(entry.virtual.start, BLOCK_SIZE), + .end = std.mem.alignForward(entry.virtual.end, BLOCK_SIZE), + }; + const physical: ?mem.Range = if (entry.physical) |phys| + mem.Range{ + .start = std.mem.alignBackward(phys.start, BLOCK_SIZE), + .end = std.mem.alignForward(phys.end, BLOCK_SIZE), + } + else + null; vmm.set(virtual, physical, .{ .kernel = true, .writable = true, .cachable = true }) catch |e| switch (e) { VmmError.AlreadyAllocated => {}, else => panic(@errorReturnTrace(), "Failed mapping region in VMM {}: {}\n", .{ entry, e }), @@ -380,7 +389,7 @@ pub fn init(mem_profile: *const mem.MemProfile, allocator: *std.mem.Allocator) s test "alloc and free" { const num_entries = 512; var vmm = try testInit(num_entries); - var allocations = test_allocations orelse unreachable; + var allocations = test_allocations.?; var virtual_allocations = std.ArrayList(usize).init(std.testing.allocator); defer virtual_allocations.deinit(); @@ -399,7 +408,7 @@ test "alloc and free" { } else { // Else it should have succeeded and allocated the correct address std.testing.expectEqual(@as(?usize, vmm.start + entry * BLOCK_SIZE), result); - try virtual_allocations.append(result orelse unreachable); + try virtual_allocations.append(result.?); } // Make sure that the entries are set or not depending on the allocation success @@ -471,7 +480,7 @@ test "set" { // Make sure it put the correct address in the map std.testing.expect(vmm.allocations.get(vstart) != null); - var allocations = test_allocations orelse unreachable; + var allocations = test_allocations.?; // The entries before the virtual start shouldn't be set var vaddr = vmm.start; while (vaddr < vstart) : (vaddr += BLOCK_SIZE) { @@ -499,10 +508,10 @@ var test_mapper = Mapper(u8){ .mapFn = testMap, .unmapFn = testUnmap }; /// Return: VirtualMemoryManager(u8) /// The VMM constructed /// -/// Error: std.mem.Allocator.Error +/// Error: Allocator.Error /// OutOfMemory: The allocator couldn't allocate the structures needed /// -fn testInit(num_entries: u32) std.mem.Allocator.Error!VirtualMemoryManager(u8) { +fn testInit(num_entries: u32) Allocator.Error!VirtualMemoryManager(u8) { if (test_allocations == null) { test_allocations = try bitmap.Bitmap(u64).init(num_entries, std.heap.page_allocator); } else |allocations| { @@ -524,7 +533,7 @@ fn testInit(num_entries: u32) std.mem.Allocator.Error!VirtualMemoryManager(u8) { .modules = &[_]mem.Module{}, }; pmm.init(&mem_profile, std.heap.page_allocator); - return try VirtualMemoryManager(u8).init(0, num_entries * BLOCK_SIZE, std.heap.page_allocator, test_mapper, 39); + return VirtualMemoryManager(u8).init(0, num_entries * BLOCK_SIZE, std.heap.page_allocator, test_mapper, 39); } /// @@ -536,14 +545,14 @@ fn testInit(num_entries: u32) std.mem.Allocator.Error!VirtualMemoryManager(u8) { /// IN pstart: usize - The start of the physical region to map /// IN pend: usize - The end of the physical region to map /// IN attrs: Attributes - The attributes to map with -/// IN/OUT allocator: *std.mem.Allocator - The allocator to use. Ignored +/// IN/OUT allocator: *Allocator - The allocator to use. Ignored /// IN payload: u8 - The payload value. Expected to be 39 /// -fn testMap(vstart: usize, vend: usize, pstart: usize, pend: usize, attrs: Attributes, allocator: *std.mem.Allocator, payload: u8) (std.mem.Allocator.Error || MapperError)!void { +fn testMap(vstart: usize, vend: usize, pstart: usize, pend: usize, attrs: Attributes, allocator: *Allocator, payload: u8) (Allocator.Error || MapperError)!void { std.testing.expectEqual(@as(u8, 39), payload); var vaddr = vstart; while (vaddr < vend) : (vaddr += BLOCK_SIZE) { - (test_allocations orelse unreachable).setEntry(vaddr / BLOCK_SIZE) catch unreachable; + (test_allocations.?).setEntry(vaddr / BLOCK_SIZE) catch unreachable; } } @@ -555,11 +564,11 @@ fn testMap(vstart: usize, vend: usize, pstart: usize, pend: usize, attrs: Attrib /// IN vend: usize - The end of the virtual region to unmap /// IN payload: u8 - The payload value. Expected to be 39 /// -fn testUnmap(vstart: usize, vend: usize, payload: u8) (std.mem.Allocator.Error || MapperError)!void { +fn testUnmap(vstart: usize, vend: usize, payload: u8) (Allocator.Error || MapperError)!void { std.testing.expectEqual(@as(u8, 39), payload); var vaddr = vstart; while (vaddr < vend) : (vaddr += BLOCK_SIZE) { - (test_allocations orelse unreachable).clearEntry(vaddr / BLOCK_SIZE) catch unreachable; + (test_allocations.?).clearEntry(vaddr / BLOCK_SIZE) catch unreachable; } } @@ -574,7 +583,7 @@ fn testUnmap(vstart: usize, vend: usize, payload: u8) (std.mem.Allocator.Error | /// fn runtimeTests(comptime Payload: type, vmm: VirtualMemoryManager(Payload), mem_profile: *const mem.MemProfile) void { const v_start = std.mem.alignBackward(@ptrToInt(mem_profile.vaddr_start), BLOCK_SIZE); - const v_end = std.mem.alignForward(@ptrToInt(mem_profile.vaddr_end) + mem.FIXED_ALLOC_SIZE, BLOCK_SIZE); + const v_end = std.mem.alignForward(@ptrToInt(mem_profile.vaddr_end), BLOCK_SIZE); var vaddr = vmm.start; while (vaddr < vmm.end - BLOCK_SIZE) : (vaddr += BLOCK_SIZE) { @@ -597,5 +606,5 @@ fn runtimeTests(comptime Payload: type, vmm: VirtualMemoryManager(Payload), mem_ } } - std.log.info(.tty, "Tested allocations\n", .{}); + std.log.info(.vmm, "Tested allocations\n", .{}); } diff --git a/test/mock/kernel/arch_mock.zig b/test/mock/kernel/arch_mock.zig index 47e7740..66ad6da 100644 --- a/test/mock/kernel/arch_mock.zig +++ b/test/mock/kernel/arch_mock.zig @@ -122,7 +122,7 @@ pub fn initTTY(boot_payload: BootPayload) TTY { }; } -pub fn initMem(payload: BootPayload) std.mem.Allocator.Error!mem.MemProfile { +pub fn initMem(payload: BootPayload) Allocator.Error!mem.MemProfile { return MemProfile{ .vaddr_end = @ptrCast([*]u8, &KERNEL_VADDR_END), .vaddr_start = @ptrCast([*]u8, &KERNEL_VADDR_START), @@ -142,7 +142,7 @@ pub fn initTaskStack(entry_point: usize, allocator: *Allocator) Allocator.Error! return ret; } -pub fn init(payload: BootPayload, mem_profile: *const MemProfile, allocator: *Allocator) void { +pub fn init(mem_profile: *const MemProfile) void { // I'll get back to this as this doesn't effect the current testing. // When I come on to the mem.zig testing, I'll fix :) //return mock_framework.performAction("init", void, mem_profile, allocator); diff --git a/test/mock/kernel/mem_mock.zig b/test/mock/kernel/mem_mock.zig index cfe7f36..15d0fe5 100644 --- a/test/mock/kernel/mem_mock.zig +++ b/test/mock/kernel/mem_mock.zig @@ -28,7 +28,6 @@ pub const MemProfile = struct { fixed_allocator: std.heap.FixedBufferAllocator, }; -// The size of the fixed allocator used before the heap is set up. Set to 1MiB. const FIXED_ALLOC_SIZE = 1024 * 1024; pub fn virtToPhys(virt: anytype) @TypeOf(virt) { diff --git a/test/runtime_test.zig b/test/runtime_test.zig index 9ceb4a8..8a7812b 100644 --- a/test/runtime_test.zig +++ b/test/runtime_test.zig @@ -120,6 +120,8 @@ pub const RuntimeStep = struct { std.debug.warn("{}\n", .{msg}); if (std.mem.indexOf(u8, msg, "FAILURE")) |_| { return false; + } else if (std.mem.indexOf(u8, msg, "Kernel panic")) |_| { + return false; } else if (std.mem.eql(u8, msg, "[info] (kmain): SUCCESS")) { return true; }