-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathbuild.zig
More file actions
executable file
·195 lines (158 loc) · 8.05 KB
/
Copy pathbuild.zig
File metadata and controls
executable file
·195 lines (158 loc) · 8.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
const std = @import("std");
pub fn build(b: *std.Build) void {
const target = b.resolveTargetQuery(.{
.cpu_arch = .riscv32,
.os_tag = .freestanding,
.abi = .none,
});
// Bare-metal target: always optimise. Debug builds hang due to safety-check
// panic machinery running before the console is ready. Use --release=safe or
// --release=fast to override the default ReleaseSmall.
const optimize = b.standardOptimizeOption(.{
.preferred_optimize_mode = .ReleaseSmall,
});
const effective_optimize = if (optimize == .Debug) .ReleaseSmall else optimize;
// Build-time log level. Controls which log calls are compiled in.
// Usage: zig build -Dlog_level=debug
const log_level = b.option(
[]const u8,
"log_level",
"Logging level: err, warn, info, debug (default: info)",
) orelse "info";
// Inject log_level as a comptime-accessible build option.
const build_opts = b.addOptions();
build_opts.addOption([]const u8, "log_level", log_level);
// Target architecture selection. Only riscv32 is supported today.
const arch_name = b.option([]const u8, "arch", "Target architecture (default: riscv32)") orelse "riscv32";
const arch_path = if (std.mem.eql(u8, arch_name, "riscv32"))
"src/arch/rv32/arch.zig"
else
std.debug.panic("unsupported architecture: {s}", .{arch_name});
// Helper to reduce boilerplate for bare-metal modules.
const Mod = struct {
b: *std.Build,
target: std.Build.ResolvedTarget,
optimize: std.builtin.OptimizeMode,
fn create(self: @This(), path: []const u8) *std.Build.Module {
return self.b.createModule(.{
.root_source_file = self.b.path(path),
.target = self.target,
.optimize = self.optimize,
});
}
};
const mod = Mod{ .b = b, .target = target, .optimize = effective_optimize };
// Low-level platform I/O: RISC-V SBI ecalls (putChar, getChar, shutdown).
// No kernel dependencies — safe for the lowest layers to import.
const sbi_module = mod.create("src/arch/rv32/sbi.zig");
// Architecture-neutral Console API wrapping the platform I/O.
// This is the narrow module that the low-level driver stack and the arch
// facade both import, avoiding dependency cycles.
const arch_console_module = mod.create("src/arch/rv32/console.zig");
arch_console_module.addImport("sbi", sbi_module);
const arch_module = mod.create(arch_path);
arch_module.addImport("arch_console", arch_console_module);
const drivers_console_module = mod.create("src/drivers/console.zig");
drivers_console_module.addImport("arch_console", arch_console_module);
// Logger depends only on console and the build options.
const lib_logger_module = mod.create("src/lib/logger.zig");
lib_logger_module.addImport("console", drivers_console_module);
lib_logger_module.addOptions("build_options", build_opts);
const lib_panic_module = mod.create("src/lib/panic.zig");
lib_panic_module.addImport("console", drivers_console_module);
lib_panic_module.addImport("arch_console", arch_console_module);
lib_panic_module.addImport("logger", lib_logger_module);
const mm_layout_module = mod.create("src/mm/layout.zig");
const mm_allocator_module = mod.create("src/mm/allocator.zig");
mm_allocator_module.addImport("layout", mm_layout_module);
mm_allocator_module.addImport("logger", lib_logger_module);
arch_module.addImport("allocator", mm_allocator_module);
arch_module.addImport("logger", lib_logger_module);
const lib_math_module = mod.create("src/lib/math.zig");
const drivers_virtio_module = mod.create("src/drivers/virtio_blk.zig");
drivers_virtio_module.addImport("logger", lib_logger_module);
drivers_virtio_module.addImport("allocator", mm_allocator_module);
drivers_virtio_module.addImport("layout", mm_layout_module);
drivers_virtio_module.addImport("math", lib_math_module);
const fs_module = mod.create("src/fs/fs.zig");
fs_module.addImport("allocator", mm_allocator_module);
fs_module.addImport("virtio", drivers_virtio_module);
fs_module.addImport("logger", lib_logger_module);
fs_module.addImport("math", lib_math_module);
const proc_process_module = mod.create("src/proc/process.zig");
proc_process_module.addImport("allocator", mm_allocator_module);
proc_process_module.addImport("layout", mm_layout_module);
proc_process_module.addImport("arch", arch_module);
proc_process_module.addImport("virtio", drivers_virtio_module);
proc_process_module.addImport("logger", lib_logger_module);
const sched_scheduler_module = mod.create("src/sched/round_robin.zig");
sched_scheduler_module.addImport("arch", arch_module);
sched_scheduler_module.addImport("process", proc_process_module);
sched_scheduler_module.addImport("logger", lib_logger_module);
const abi_module = mod.create("src/abi/syscall.zig");
const kernel_context_module = mod.create("src/kernel/context.zig");
kernel_context_module.addImport("process", proc_process_module);
kernel_context_module.addImport("scheduler", sched_scheduler_module);
const kernel_syscall_module = mod.create("src/kernel/syscall.zig");
kernel_syscall_module.addImport("arch", arch_module);
kernel_syscall_module.addImport("kernel_context", kernel_context_module);
kernel_syscall_module.addImport("abi", abi_module);
kernel_syscall_module.addImport("fs", fs_module);
kernel_syscall_module.addImport("logger", lib_logger_module);
kernel_syscall_module.addImport("layout", mm_layout_module);
const kernel_trap_module = mod.create("src/kernel/trap.zig");
kernel_trap_module.addImport("arch", arch_module);
kernel_trap_module.addImport("kernel_context", kernel_context_module);
kernel_trap_module.addImport("kernel_syscall", kernel_syscall_module);
kernel_trap_module.addImport("logger", lib_logger_module);
kernel_trap_module.addImport("panic", lib_panic_module);
const kernel_main_module = mod.create("src/kernel/main.zig");
kernel_main_module.addImport("arch", arch_module);
kernel_main_module.addImport("logger", lib_logger_module);
kernel_main_module.addImport("panic", lib_panic_module);
kernel_main_module.addImport("allocator", mm_allocator_module);
kernel_main_module.addImport("layout", mm_layout_module);
kernel_main_module.addImport("kernel_context", kernel_context_module);
kernel_main_module.addImport("virtio", drivers_virtio_module);
kernel_main_module.addImport("trap", kernel_trap_module);
kernel_main_module.addImport("fs", fs_module);
const exe = b.addExecutable(.{
.name = "kernel.elf",
.root_module = kernel_main_module,
});
exe.setLinkerScript(b.path("src/linker/kernel.ld"));
exe.entry = .disabled;
b.installArtifact(exe);
const user_module = mod.create("src/user/main.zig");
user_module.addImport("abi", abi_module);
const user = b.addExecutable(.{
.name = "user.elf",
.root_module = user_module,
});
user.entry = .disabled;
user.setLinkerScript(b.path("src/linker/user.ld"));
b.installArtifact(user);
const elf2bin = b.addSystemCommand(&.{
"llvm-objcopy",
"--set-section-flags",
".bss=alloc,contents",
"-O",
"binary",
});
elf2bin.addArtifactArg(user);
const bin_file_name = "user.bin";
const bin = elf2bin.addOutputFileArg(bin_file_name);
kernel_main_module.addAnonymousImport("user.bin", .{
.root_source_file = bin,
});
exe.step.dependOn(&elf2bin.step);
const run_cmd = b.addSystemCommand(&.{"qemu-system-riscv32"});
run_cmd.addArgs(&.{ "-machine", "virt", "-bios", "default", "-nographic", "-serial", "mon:stdio", "--no-reboot", "-kernel" });
run_cmd.addArtifactArg(exe);
run_cmd.addArgs(&.{
"-drive", "id=drive0,file=disk.img,format=raw,if=none",
"-device", "virtio-blk-device,drive=drive0,bus=virtio-mmio-bus.0",
});
const run_step = b.step("run", "Run QEMU");
run_step.dependOn(&run_cmd.step);
}