Start using the zig build system
Start using zig build system
This commit is contained in:
parent
def383249e
commit
47f68ceb9c
5 changed files with 145 additions and 33 deletions
5
.gitignore
vendored
5
.gitignore
vendored
|
@ -39,4 +39,7 @@
|
||||||
.idea/
|
.idea/
|
||||||
|
|
||||||
# Zig
|
# Zig
|
||||||
zig-cache/
|
zig-cache
|
||||||
|
|
||||||
|
# Build dir
|
||||||
|
bin/*
|
||||||
|
|
27
README.md
27
README.md
|
@ -1,5 +1,26 @@
|
||||||
Compile: zig build-exe kmain.zig -target i386-freestanding --linker-script link.ld
|
# Pluto
|
||||||
|
|
||||||
Run: qemu-system-i386 -kernel kmain -curses
|
## Build
|
||||||
|
Requires *xorriso* and the grub tools (such as *grub-mkrescue*).
|
||||||
|
```
|
||||||
|
mkdir -p bin/kernel
|
||||||
|
mkdir -p bin/iso/boot/grub
|
||||||
|
zig build
|
||||||
|
```
|
||||||
|
|
||||||
To exit qemu: Esc + 2, type `quit`
|
Note that the `mkdir` invocations are only needed once. See `zig build --help` for a list of options.
|
||||||
|
|
||||||
|
## Run
|
||||||
|
```
|
||||||
|
zig build run
|
||||||
|
```
|
||||||
|
To debug the kernel:
|
||||||
|
```
|
||||||
|
zig build run -Ddebug=true
|
||||||
|
zig build debug
|
||||||
|
```
|
||||||
|
|
||||||
|
# Test
|
||||||
|
```
|
||||||
|
zig build test
|
||||||
|
```
|
||||||
|
|
145
build.zig
145
build.zig
|
@ -1,43 +1,124 @@
|
||||||
// Zig version: 0.4.0
|
// Zig version: 0.4.0
|
||||||
|
|
||||||
const Builder = @import("std").build.Builder;
|
const Builder = @import("std").build.Builder;
|
||||||
|
const Step = @import("std").build.Step;
|
||||||
const builtin = @import("builtin");
|
const builtin = @import("builtin");
|
||||||
const Array = @import("std").ArrayList;
|
const std = @import("std");
|
||||||
|
const ArrayList = std.ArrayList;
|
||||||
|
const warn = std.debug.warn;
|
||||||
|
const mem = std.mem;
|
||||||
|
|
||||||
|
const src_files = [][]const u8{"kernel/kmain"};
|
||||||
|
|
||||||
|
fn concat(allocator: *std.mem.Allocator, str: []const u8, str2: []const u8) !std.Buffer {
|
||||||
|
var b = try std.Buffer.init(allocator, str);
|
||||||
|
try b.append(str2);
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn build(b: *Builder) void {
|
pub fn build(b: *Builder) void {
|
||||||
const kernel_out_dir = "bin/kernel";
|
const debug = b.option(bool, "debug", "build with debug symbols / make qemu wait for a debug connection") orelse false;
|
||||||
const kernel_src = "src/kernel/";
|
var build_path = b.option([]const u8, "build-path", "path to build to") orelse "bin";
|
||||||
|
var src_path = b.option([]const u8, "source-path", "path to source") orelse "src";
|
||||||
|
var target = b.option([]const u8, "target", "target to build/run for") orelse "x86";
|
||||||
|
const builtin_target = if (mem.eql(u8, target, "x86")) builtin.Arch.i386 else unreachable;
|
||||||
|
|
||||||
var kernel = b.addExecutable("pluto.elf", kernel_src ++ "kmain.zig");
|
const iso_path = concat(b.allocator, build_path, "/pluto.iso") catch unreachable;
|
||||||
//kernel.addAssemblyFile(kernel_src ++ "start.s");
|
|
||||||
|
|
||||||
kernel.setOutputDir(kernel_out_dir);
|
var objects_steps = buildObjects(b, builtin_target, build_path, src_path);
|
||||||
kernel.setBuildMode(b.standardReleaseOptions());
|
var link_step = buildLink(b, builtin_target, build_path);
|
||||||
kernel.setTarget(builtin.Arch.i386, builtin.Os.freestanding, builtin.Abi.gnu);
|
const iso_step = buildISO(b, build_path, iso_path.toSlice());
|
||||||
kernel.setLinkerScriptPath("link.ld");
|
|
||||||
|
|
||||||
const run_objcopy = b.addSystemCommand([][]const u8 {
|
for (objects_steps.toSlice()) |step| b.default_step.dependOn(step);
|
||||||
"objcopy", "-O", "binary", "-S", kernel.getOutputPath(), kernel_out_dir ++ "/pluto.bin",
|
b.default_step.dependOn(link_step);
|
||||||
});
|
for (iso_step.toSlice()) |step| b.default_step.dependOn(step);
|
||||||
run_objcopy.step.dependOn(&kernel.step);
|
|
||||||
|
|
||||||
b.default_step.dependOn(&run_objcopy.step);
|
buildRun(b, builtin_target, build_path, iso_path.toSlice(), debug);
|
||||||
|
buildDebug(b);
|
||||||
const run_qemu = b.addSystemCommand([][]const u8 {
|
buildTest(b, src_path);
|
||||||
"qemu-system-i386",
|
}
|
||||||
"-display", "curses",
|
|
||||||
"-kernel", kernel.getOutputPath(),
|
fn buildTest(b: *Builder, src_path: []const u8) void {
|
||||||
});
|
const step = b.step("test", "Run all tests");
|
||||||
|
const src_path2 = concat(b.allocator, src_path, "/") catch unreachable;
|
||||||
const run_qemu_debug = b.addSystemCommand([][]const u8 {
|
for (src_files) |file| {
|
||||||
"qemu-system-i386",
|
var file_src = concat(b.allocator, src_path2.toSlice(), file) catch unreachable;
|
||||||
"-display", "curses",
|
file_src.append(".zig") catch unreachable;
|
||||||
"-kernel", kernel.getOutputPath(),
|
const tst = b.addTest(file_src.toSlice());
|
||||||
"-s", "-S",
|
step.dependOn(&tst.step);
|
||||||
});
|
}
|
||||||
|
}
|
||||||
run_qemu.step.dependOn(&kernel.step);
|
|
||||||
//run_qemu_debug.step.dependOn(&kernel.step);
|
fn buildDebug(b: *Builder) void {
|
||||||
|
const step = b.step("debug", "Debug with gdb");
|
||||||
b.default_step.dependOn(&run_qemu.step);
|
const cmd = b.addSystemCommand([][]const u8{
|
||||||
|
"gdb",
|
||||||
|
"-ex",
|
||||||
|
"symbol-file bin/iso/boot/pluto.elf",
|
||||||
|
"-ex",
|
||||||
|
"target remote localhost:1234",
|
||||||
|
});
|
||||||
|
step.dependOn(&cmd.step);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn buildRun(b: *Builder, target: builtin.Arch, build_path: []const u8, iso_path: []const u8, debug: bool) void {
|
||||||
|
const step = b.step("run", "Run with qemu");
|
||||||
|
const qemu = if (target == builtin.Arch.i386) "qemu-system-i386" else unreachable;
|
||||||
|
var qemu_flags = ArrayList([]const u8).init(b.allocator);
|
||||||
|
qemu_flags.appendSlice([][]const u8{
|
||||||
|
qemu,
|
||||||
|
"-cdrom",
|
||||||
|
iso_path,
|
||||||
|
"-boot",
|
||||||
|
"d",
|
||||||
|
"-serial",
|
||||||
|
"stdio",
|
||||||
|
}) catch unreachable;
|
||||||
|
if (debug)
|
||||||
|
qemu_flags.appendSlice([][]const u8{
|
||||||
|
"-s",
|
||||||
|
"-S",
|
||||||
|
}) catch unreachable;
|
||||||
|
const cmd = b.addSystemCommand(qemu_flags.toSlice());
|
||||||
|
step.dependOn(&cmd.step);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn buildISO(b: *Builder, build_path: []const u8, iso_path: []const u8) ArrayList(*Step) {
|
||||||
|
const grub_build_path = concat(b.allocator, build_path, "/iso/boot/") catch unreachable;
|
||||||
|
const iso_dir_path = concat(b.allocator, build_path, "/iso") catch unreachable;
|
||||||
|
const grub_cmd = b.addSystemCommand([][]const u8{ "cp", "-r", "grub", grub_build_path.toSlice() });
|
||||||
|
const iso_cmd = b.addSystemCommand([][]const u8{ "grub-mkrescue", "-o", iso_path, iso_dir_path.toSlice() });
|
||||||
|
var steps = ArrayList(*Step).init(b.allocator);
|
||||||
|
steps.append(&grub_cmd.step) catch unreachable;
|
||||||
|
steps.append(&iso_cmd.step) catch unreachable;
|
||||||
|
return steps;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn buildLink(b: *Builder, target: builtin.Arch, build_path: []const u8) *Step {
|
||||||
|
const exec = b.addExecutable("pluto.elf", null);
|
||||||
|
const elf_path = concat(b.allocator, build_path, "/iso/boot") catch unreachable;
|
||||||
|
exec.setOutputDir(elf_path.toSlice());
|
||||||
|
exec.setLinkerScriptPath("link.ld");
|
||||||
|
exec.setTarget(target, builtin.Os.freestanding, builtin.Abi.gnu);
|
||||||
|
for (src_files) |file| {
|
||||||
|
var file_obj = concat(b.allocator, build_path, "/") catch unreachable;
|
||||||
|
file_obj.append(file) catch unreachable;
|
||||||
|
file_obj.append(".o") catch unreachable;
|
||||||
|
exec.addObjectFile(file_obj.toSlice());
|
||||||
|
}
|
||||||
|
return &exec.step;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn buildObjects(b: *Builder, target: builtin.Arch, build_path: []const u8, src_path: []const u8) ArrayList(*Step) {
|
||||||
|
var objects = ArrayList(*Step).init(b.allocator);
|
||||||
|
const src_path2 = concat(b.allocator, src_path, "/") catch unreachable;
|
||||||
|
for (src_files) |file| {
|
||||||
|
var file_src = concat(b.allocator, src_path2.toSlice(), file) catch unreachable;
|
||||||
|
file_src.append(".zig") catch unreachable;
|
||||||
|
const obj = b.addObject(file, file_src.toSlice());
|
||||||
|
obj.setOutputDir(build_path);
|
||||||
|
obj.setTarget(target, builtin.Os.freestanding, builtin.Abi.gnu);
|
||||||
|
objects.append(&obj.step) catch unreachable;
|
||||||
|
}
|
||||||
|
return objects;
|
||||||
}
|
}
|
7
grub/grub.cfg
Normal file
7
grub/grub.cfg
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
set timeout=0 # How long grub should wait before booting default menu entry
|
||||||
|
set default=0
|
||||||
|
|
||||||
|
menuentry "pluto" {
|
||||||
|
multiboot /boot/pluto.elf
|
||||||
|
boot
|
||||||
|
}
|
BIN
grub/stage2_eltorito
Normal file
BIN
grub/stage2_eltorito
Normal file
Binary file not shown.
Loading…
Reference in a new issue