From 2500b7889626e6f42241f5a368a627b19cf3391a Mon Sep 17 00:00:00 2001 From: David Gonzalez Martin Date: Fri, 14 Jul 2023 09:56:05 -0600 Subject: [PATCH] log: fix log issue which hurt console badly --- .gitignore | 1 + build.zig | 9 ++- config/default.json | 2 +- config/qemu.json | 1 - logs/.gitkeep | 0 src/common.zig | 2 + src/host.zig | 5 ++ src/host/disk_image_builder/test.zig | 16 ++--- src/host/runner/main.zig | 96 ++++++++++++++++++++-------- tools/format_loopback_fat32.sh | 2 +- 10 files changed, 97 insertions(+), 37 deletions(-) create mode 100644 logs/.gitkeep diff --git a/.gitignore b/.gitignore index a54d037..7fbc9af 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ bochsout.txt *.hdd loopback_device tools/OVMF.fd +logs/*.log diff --git a/build.zig b/build.zig index eba8606..5d0d0c7 100644 --- a/build.zig +++ b/build.zig @@ -467,6 +467,8 @@ pub fn build(b_arg: *Build) !void { const user_init = user_module_list.items[0]; + const is_default = architecture == default_configuration.architecture and bootloader == default_configuration.bootloader and boot_protocol == default_configuration.boot_protocol and optimize_mode == default_configuration.optimize_mode and execution_environment == default_configuration.execution_environment and execution_type == default_configuration.execution_type; + const runner_run = try newRunnerRunArtifact(.{ .configuration = configuration, .disk_image_path = disk_image_path, @@ -479,7 +481,9 @@ pub fn build(b_arg: *Build) !void { .is_test = is_test, }, .ovmf_path = ovmf_path, + .is_default = is_default, }); + const runner_debug = try newRunnerRunArtifact(.{ .configuration = configuration, .disk_image_path = disk_image_path, @@ -492,13 +496,14 @@ pub fn build(b_arg: *Build) !void { .is_test = is_test, }, .ovmf_path = ovmf_path, + .is_default = is_default, }); if (is_test) { build_steps.test_all.dependOn(&runner_run.step); } - if (architecture == default_configuration.architecture and bootloader == default_configuration.bootloader and boot_protocol == default_configuration.boot_protocol and optimize_mode == default_configuration.optimize_mode and execution_environment == default_configuration.execution_environment and execution_type == default_configuration.execution_type) { + if (is_default) { if (is_test) { build_steps.test_run.dependOn(&runner_run.step); build_steps.test_debug.dependOn(&runner_debug.step); @@ -592,6 +597,7 @@ fn newRunnerRunArtifact(arguments: struct { user_init: *CompileStep, qemu_options: QEMUOptions, ovmf_path: FileSource, + is_default: bool, }) !*RunStep { const runner = b.addRunArtifact(arguments.runner); @@ -609,6 +615,7 @@ fn newRunnerRunArtifact(arguments: struct { .debug_user => runner.addArg(if (debug_user) "true" else "false"), .debug_loader => runner.addArg(if (debug_loader) "true" else "false"), .ovmf_path => runner.addFileSourceArg(arguments.ovmf_path), + .is_default => runner.addArg(if (arguments.is_default) "true" else "false"), }; return runner; diff --git a/config/default.json b/config/default.json index b263f83..6a813cb 100644 --- a/config/default.json +++ b/config/default.json @@ -1,6 +1,6 @@ { "architecture": "x86_64", - "bootloader": "birth", + "bootloader": "limine", "boot_protocol": "uefi", "execution_environment": "qemu", "optimize_mode": "Debug", diff --git a/config/qemu.json b/config/qemu.json index 7dac633..926a6cc 100644 --- a/config/qemu.json +++ b/config/qemu.json @@ -8,7 +8,6 @@ "smp": 2, "debugcon": "stdio", "log": { - "file": null, "guest_errors": true, "assembly": false, "interrupts": true diff --git a/logs/.gitkeep b/logs/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/src/common.zig b/src/common.zig index afc9d1d..66f6d8e 100644 --- a/src/common.zig +++ b/src/common.zig @@ -481,6 +481,7 @@ pub const ArgumentParser = struct { debug_loader, init, ovmf_path, + is_default, }; pub const Result = struct { @@ -495,6 +496,7 @@ pub const ArgumentParser = struct { debug_loader: bool, init: []const u8, ovmf_path: []const u8, + is_default: bool, }; }; }; diff --git a/src/host.zig b/src/host.zig index 699da13..c40edea 100644 --- a/src/host.zig +++ b/src/host.zig @@ -57,6 +57,11 @@ pub fn allocateZeroMemory(bytes: u64) ![]align(0x1000) u8 { pub const ExecutionError = error{failed}; pub fn spawnProcess(arguments: []const []const u8, allocator: lib.ZigAllocator) !void { var process = ChildProcess.init(arguments, allocator); + // std.log.err("Spawning process:", .{}); + // for (arguments) |arg| { + // std.log.err("Arg: {s}", .{arg}); + // } + process.stdout_behavior = .Ignore; const execution_result = try process.spawnAndWait(); diff --git a/src/host/disk_image_builder/test.zig b/src/host/disk_image_builder/test.zig index fb88212..ead5ff3 100644 --- a/src/host/disk_image_builder/test.zig +++ b/src/host/disk_image_builder/test.zig @@ -39,29 +39,29 @@ const MountedPartition = struct { loopback_device: LoopbackDevice, fn mkdir(partition: MountedPartition, allocator: lib.ZigAllocator, dir: []const u8) !void { - try host.spawnProcess(&.{ "sudo", "mkdir", "-p", try partition.join_with_root(allocator, dir) }, allocator); + try host.spawnProcess(&.{ "sudo", "mkdir", "-p", try partition.joinWithRoot(allocator, dir) }, allocator); } - fn join_with_root(partition: MountedPartition, allocator: lib.ZigAllocator, path: []const u8) ![]const u8 { - const mount_dir = partition.get_mount_dir(); + fn joinWithRoot(partition: MountedPartition, allocator: lib.ZigAllocator, path: []const u8) ![]const u8 { + const mount_dir = partition.getMountDir(); const slices_to_join: []const []const u8 = if (path[0] == '/') &.{ mount_dir, path } else &.{ mount_dir, "/", path }; const joint_path = try lib.concat(allocator, u8, slices_to_join); return joint_path; } - pub fn get_mount_dir(partition: MountedPartition) []const u8 { - const mount_dir = partition.loopback_device.mount_dir orelse @panic("get_mount_dir"); + pub fn getMountDir(partition: MountedPartition) []const u8 { + const mount_dir = partition.loopback_device.mount_dir orelse @panic("getMountDir"); return mount_dir; } - fn copy_file(partition: MountedPartition, allocator: lib.ZigAllocator, file_path: []const u8, file_content: []const u8) !void { + fn copyFile(partition: MountedPartition, allocator: lib.ZigAllocator, file_path: []const u8, file_content: []const u8) !void { // TODO: make this work for Windows? const last_slash_index = lib.lastIndexOf(u8, file_path, "/") orelse @panic("fat32: copy file last slash"); const file_name = host.basename(file_path); assert(file_name.len > 0); try host.cwd().writeFile(file_name, file_content); const dir = file_path[0..if (last_slash_index == 0) 1 else last_slash_index]; - const destination_dir = try partition.join_with_root(allocator, dir); + const destination_dir = try partition.joinWithRoot(allocator, dir); const mkdir_process_args = &.{ "sudo", "mkdir", "-p", destination_dir }; try host.spawnProcess(mkdir_process_args, allocator); const copy_process_args = &.{ "sudo", "cp", "-v", file_name, destination_dir }; @@ -167,7 +167,7 @@ test "Limine barebones" { } for (limine_files) |file| { - try partition.copy_file(wrapped_allocator.zigUnwrap(), file.path, file.content); + try partition.copyFile(wrapped_allocator.zigUnwrap(), file.path, file.content); } try partition.end(wrapped_allocator.zigUnwrap()); diff --git a/src/host/runner/main.zig b/src/host/runner/main.zig index a31e6be..2b1befc 100644 --- a/src/host/runner/main.zig +++ b/src/host/runner/main.zig @@ -22,8 +22,17 @@ const Error = error{ architecture_not_supported, execution_environment_not_supported, ovmf_path_not_found, + is_default_not_found, }; +const ParseBoolError = error{ + not_found, +}; + +fn parseBool(argument: []const u8) !bool { + return if (lib.equal(u8, argument, "true")) true else if (lib.equal(u8, argument, "false")) false else ParseBoolError.not_found; +} + pub fn main() anyerror!void { const max_file_length = lib.maxInt(usize); var arena_allocator = host.ArenaAllocator.init(host.page_allocator); @@ -46,6 +55,7 @@ pub fn main() anyerror!void { var argument_init_path: ?[]const u8 = null; var argument_index: usize = 0; var argument_ovmf_path: ?[]const u8 = null; + var argument_is_default: ?bool = null; while (argument_parser.next()) |argument_type| switch (argument_type) { .disk_image_path => { @@ -66,7 +76,7 @@ pub fn main() anyerror!void { argument_qemu_options = undefined; inline for (lib.fields(lib.QEMUOptions), 0..) |field, field_index| { - @field(argument_qemu_options.?, field.name) = if (lib.equal(u8, boolean_argument_strings[field_index], "true")) true else if (lib.equal(u8, boolean_argument_strings[field_index], "false")) false else return Error.qemu_options_not_found; + @field(argument_qemu_options.?, field.name) = parseBool(boolean_argument_strings[field_index]) catch return Error.qemu_options_not_found; } }, .configuration => { @@ -82,15 +92,15 @@ pub fn main() anyerror!void { argument_index += 1; }, .ci => { - argument_ci = if (lib.equal(u8, arguments[argument_index], "true")) true else if (lib.equal(u8, arguments[argument_index], "false")) false else return Error.ci_not_found; + argument_ci = parseBool(arguments[argument_index]) catch return Error.ci_not_found; argument_index += 1; }, .debug_user => { - argument_debug_user = if (lib.equal(u8, arguments[argument_index], "true")) true else if (lib.equal(u8, arguments[argument_index], "false")) false else return Error.debug_user_not_found; + argument_debug_user = parseBool(arguments[argument_index]) catch return Error.debug_user_not_found; argument_index += 1; }, .debug_loader => { - argument_debug_loader = if (lib.equal(u8, arguments[argument_index], "true")) true else if (lib.equal(u8, arguments[argument_index], "false")) false else return Error.debug_loader_not_found; + argument_debug_loader = parseBool(arguments[argument_index]) catch return Error.debug_loader_not_found; argument_index += 1; }, .init => { @@ -101,6 +111,10 @@ pub fn main() anyerror!void { argument_ovmf_path = arguments[argument_index]; argument_index += 1; }, + .is_default => { + argument_is_default = parseBool(arguments[argument_index]) catch return Error.is_default_not_found; + argument_index += 1; + }, }; if (argument_index != arguments.len) return Error.wrong_argument_count; @@ -117,6 +131,7 @@ pub fn main() anyerror!void { .debug_loader = argument_debug_loader orelse return Error.debug_loader_not_found, .init = argument_init_path orelse return Error.init_not_found, .ovmf_path = argument_ovmf_path orelse return Error.ovmf_path_not_found, + .is_default = argument_is_default orelse return Error.is_default_not_found, }; }; @@ -124,6 +139,21 @@ pub fn main() anyerror!void { .qemu => { const qemu_options = arguments_result.qemu_options; + const unique_base_name = blk: { + var list = host.ArrayList(u8).init(wrapped_allocator.zigUnwrap()); + inline for (lib.fields(Configuration)) |conf_field| { + try list.appendSlice(@tagName(@field(arguments_result.configuration, conf_field.name))); + try list.append('_'); + } + + break :blk list.items; + }; + + const debugcon_file = try lib.concat(wrapped_allocator.zigUnwrap(), u8, &.{ "logs/", unique_base_name, "debugcon.log" }); + const qemu_debug_file = try lib.concat(wrapped_allocator.zigUnwrap(), u8, &.{ "logs/", unique_base_name, "debug.log" }); + var debugcon_file_used = false; + var qemu_debug_file_used = false; + const config_file = try host.cwd().readFileAlloc(wrapped_allocator.zigUnwrap(), "config/qemu.json", max_file_length); const parsed_arguments = try lib.json.parseFromSlice(Arguments, wrapped_allocator.zigUnwrap(), config_file, .{}); const arguments = parsed_arguments.value; @@ -169,7 +199,12 @@ pub fn main() anyerror!void { if (arguments.debugcon) |debugcon| { try argument_list.append("-debugcon"); - try argument_list.append(@tagName(debugcon)); + if (arguments_result.is_default) { + try argument_list.append(@tagName(debugcon)); + } else { + debugcon_file_used = true; + try argument_list.append(try lib.concat(wrapped_allocator.zigUnwrap(), u8, &.{ "file:", debugcon_file })); + } } if (arguments.memory) |memory| { @@ -213,30 +248,29 @@ pub fn main() anyerror!void { } } - if (!arguments_result.ci) { - if (arguments.log) |log_configuration| { - var log_what = host.ArrayList(u8).init(wrapped_allocator.zigUnwrap()); + if (arguments.log) |log_configuration| { + var log_what = host.ArrayList(u8).init(wrapped_allocator.zigUnwrap()); - if (log_configuration.guest_errors) try log_what.appendSlice("guest_errors,"); - if (log_configuration.interrupts) try log_what.appendSlice("int,"); - if (!arguments_result.ci and log_configuration.assembly) try log_what.appendSlice("in_asm,"); + if (log_configuration.guest_errors) try log_what.appendSlice("guest_errors,"); + if (log_configuration.interrupts) try log_what.appendSlice("int,"); + if (!arguments_result.ci and log_configuration.assembly) try log_what.appendSlice("in_asm,"); - if (log_what.items.len > 0) { - // Delete the last comma - _ = log_what.pop(); + if (log_what.items.len > 0) { + // Delete the last comma + _ = log_what.pop(); - try argument_list.append("-d"); - try argument_list.append(log_what.items); + try argument_list.append("-d"); + try argument_list.append(log_what.items); - if (log_configuration.interrupts) { - try argument_list.appendSlice(&.{ "-machine", "smm=off" }); - } + if (log_configuration.interrupts) { + try argument_list.appendSlice(&.{ "-machine", "smm=off" }); } + } - if (log_configuration.file) |log_file| { - try argument_list.append("-D"); - try argument_list.append(log_file); - } + if (!arguments_result.is_default) { + qemu_debug_file_used = true; + try argument_list.append("-D"); + try argument_list.append(qemu_debug_file); } } } @@ -298,6 +332,7 @@ pub fn main() anyerror!void { } var process = host.ChildProcess.init(argument_list.items, wrapped_allocator.zigUnwrap()); + //process.stdout_behavior = .I; const result = try process.spawnAndWait(); if (result == .Exited) { @@ -310,7 +345,9 @@ pub fn main() anyerror!void { const qemu_exit_code = @as(lib.QEMU.ExitCode, @enumFromInt(masked_exit_code >> 1)); switch (qemu_exit_code) { - .success => return log.info("Success!", .{}), + .success => { + return; + }, .failure => log.err("QEMU exited with failure code 0x{x}", .{exit_code}), _ => log.err("Totally unexpected value", .{}), } @@ -320,6 +357,16 @@ pub fn main() anyerror!void { log.err("QEMU was {s}", .{@tagName(result)}); } + if (debugcon_file_used) { + const debugcon_file_content = try host.cwd().readFileAlloc(wrapped_allocator.zigUnwrap(), debugcon_file, lib.maxInt(usize)); + @import("std").debug.print("\n{s}\n", .{debugcon_file_content}); + } + + if (qemu_debug_file_used) { + const debug_file_content = try host.cwd().readFileAlloc(wrapped_allocator.zigUnwrap(), qemu_debug_file, lib.maxInt(usize)); + @import("std").debug.print("\n{s}\n", .{debug_file_content}); + } + return Error.qemu_error; }, } @@ -348,7 +395,6 @@ const Arguments = struct { stdio, }, log: ?struct { - file: ?[]const u8, guest_errors: bool, assembly: bool, interrupts: bool, diff --git a/tools/format_loopback_fat32.sh b/tools/format_loopback_fat32.sh index 461dff7..1fbd5f1 100755 --- a/tools/format_loopback_fat32.sh +++ b/tools/format_loopback_fat32.sh @@ -1,4 +1,4 @@ #!/bin/sh # $1 Loopback device set -e -sudo mkfs.fat -F 32 `cat $1`p1 1>2 +sudo mkfs.fat -F 32 `cat $1`p1