ke: rework kernel initialization

This commit is contained in:
Loïc Grégoire
2026-08-05 16:10:37 -04:00
parent 4aaae63349
commit 2a09642f4d
11 changed files with 58 additions and 31 deletions
+4 -9
View File
@@ -11,8 +11,7 @@ const rtl = @import("rtl");
// XXX
const fbconsole = @import("../dev/fbconsole.zig");
export fn kmain(boot_info: *r.BootInfo) callconv(.c) void {
ke.init(boot_info);
pub fn init() void {
mm.init();
ps.init();
@@ -23,11 +22,11 @@ export fn kmain(boot_info: *r.BootInfo) callconv(.c) void {
exp.console.init();
exp.string.init();
if (boot_info.cmdline) |cline| {
if (r.boot_info.cmdline) |cline| {
if (rtl.cmdline.get_string(cline, "test")) |tst| {
// Run a test if specified.
if (r.tests.tests.get(tst)) |func| {
const t = ps.thread.create_kernel(ke.Thread.Priority.default, func, boot_info) catch @panic("oom");
const t = ps.thread.create_kernel(ke.Thread.Priority.default, func, r.boot_info) catch @panic("oom");
ke.sched.enqueue(&t.kern);
} else {
std.log.info("invalid test: \"{s}\"", .{tst});
@@ -35,11 +34,7 @@ export fn kmain(boot_info: *r.BootInfo) callconv(.c) void {
}
}
if (boot_info.framebuffer != null) {
if (r.boot_info.framebuffer != null) {
// fbconsole.init(boot_info);
}
while (true) {
std.atomic.spinLoopHint();
}
}
+2
View File
@@ -7,6 +7,8 @@ pub const DelayedWorkItem = p.work.DelayedWorkItem;
pub const Console = p.console.Console;
pub const InternedString = p.string.InternedString;
pub const init = p.init;
pub const work = struct {
pub const enqueue = p.work.enqueue;
pub const enqueue_in = p.work.enqueue_in;
+5 -1
View File
@@ -26,6 +26,7 @@ const ThreadFrame = extern struct {
extern fn asm_thread_entry() void;
extern fn do_context_switch(old: *ThreadContext, new: *ThreadContext, lock: *u8, switching: *bool) callconv(.c) void;
extern fn do_context_load(td: *ThreadContext) callconv(.c) void;
pub const ThreadContext = extern struct {
rsp: u64 align(1),
@@ -35,7 +36,6 @@ pub const ThreadContext = extern struct {
const entry_fn: *const fn (?*anyopaque) void = @ptrFromInt(entry);
ke.ipl.lower(.Passive);
entry_fn(@ptrFromInt(arg));
// TODO: This shouldn't be reached!!!
}
pub fn init(stack: r.VAddr, stack_size: usize, entry: *const fn (?*anyopaque) void, arg: ?*anyopaque) @This() {
@@ -62,6 +62,10 @@ pub const ThreadContext = extern struct {
const thread: *ke.Thread = @alignCast(@fieldParentPtr("context", self));
do_context_switch(self, new, &thread.lock.inner.locked.raw, &thread.switching.raw);
}
pub fn load(self: *ThreadContext) callconv(.c) void {
do_context_load(self);
}
};
inline fn percpu_ptr_for(variable: anytype, cpu: u32) @TypeOf(variable) {
+5 -4
View File
@@ -91,16 +91,17 @@ pub fn ap_entry(cpu_id: u32, booted: *std.atomic.Value(usize)) noreturn {
ki.cpu.init_cpu(cpu_id);
pl.impl.init_ap();
ki.sched.percpu.local().current_thread = pl.impl.smp.start_thread.local().*;
const sched = ki.sched.percpu.local();
sched.current_thread = pl.impl.smp.start_thread.local().*;
sched.idle_thread = sched.current_thread;
amd64.sti();
_ = booted.fetchAdd(1, .monotonic);
ke.ipl.lower(.Passive);
while (true) {
std.atomic.spinLoopHint();
}
ki.sched.idle(null);
}
var initial_offsets: [1]usize = .{0};
+13
View File
@@ -166,6 +166,19 @@ do_context_switch:
pop %r15
ret
.global do_context_load
do_context_load:
/* Load new stack pointer. */
mov (%rdi), %rsp
/* Restore callee-saved registers. */
pop %rbp
pop %rbx
pop %r12
pop %r13
pop %r14
pop %r15
ret
.extern thread_entry
.global asm_thread_entry
+21 -14
View File
@@ -7,10 +7,24 @@ const ki = ke.private;
const ex = r.ex;
var thread0: ke.Thread = undefined;
var stack: [r.kib(16)]u8 align(16) = undefined;
pub fn init(boot_info: *r.BootInfo) linksection(r.init) void {
export fn kmain(boot_info: *r.BootInfo) callconv(.c) void {
r.boot_info = boot_info;
thread0.init(
boot_info.kernel_stack,
boot_info.kernel_stack_size,
ke.Thread.Priority.idle_low,
init,
null,
);
thread0.pinned = true;
// Jump into the thread.
thread0.context.load();
}
pub fn init(_: ?*anyopaque) linksection(r.init) void {
ke.ncpus = 1;
ki.impl.early_init();
ki.tunable.init();
@@ -20,18 +34,11 @@ pub fn init(boot_info: *r.BootInfo) linksection(r.init) void {
ki.cpu.init_cpu(0);
ki.turnstile.init_turnstiles();
thread0.init(
@intFromPtr(&stack),
r.kib(16),
ke.Thread.Priority.idle_low,
ki.sched.idle,
null,
);
thread0.priority = 0;
thread0.base_priority = 0;
thread0.pinned = true;
ki.sched.percpu.local().current_thread = &thread0;
ki.sched.percpu.local().idle_thread = &thread0;
std.log.info("Zag for {s} ({s}), cmdline is \"{?s}\"", .{ pl.name, arch.name, boot_info.cmdline });
std.log.info("Zag for {s} ({s}), cmdline is \"{?s}\"", .{ pl.name, arch.name, r.boot_info.cmdline });
ex.init();
ki.sched.idle(null);
}
+3
View File
@@ -34,6 +34,9 @@ pub const Framebuffer = struct {
// Kept in sync with the kernel
pub const page_struct_size = 16;
kernel_stack: usize,
kernel_stack_size: usize,
/// RSDP on ACPI machines
rsdp: ?usize,
+3
View File
@@ -93,6 +93,9 @@ pub fn loader_main(kernel: *anyopaque) void {
const memmap = &r.loader_info.memory_map;
r.loader_info.kernel_stack = stack;
r.loader_info.kernel_stack_size = stack_size;
// Finally, sort the memory map once we're done allocating everything.
std.mem.sort(Entry, memmap.entries[0..memmap.entry_count], {}, cmp_entries);
+1 -1
View File
@@ -172,7 +172,7 @@ pub const PMap = struct {
/// Choose the largest page size that satisfies the alignment and
/// size constraints of the current VA, PA, and remaining byte count.
/// Tries large pages first; falls back to 4K.
/// Tries large pages first, falls back to 4K.
fn choose_target_level(self: *Cursor, pa: usize, remain: usize) usize {
var level: usize = num_levels;
while (level > 0) {
-1
View File
@@ -110,7 +110,6 @@ pub fn init() linksection(r.init) void {
const stack_top = @intFromPtr(mm.heap.alloc(r.kib(32), .DontWaitForMemory) catch @panic("Failed to allocate AP stack")) + r.kib(32);
start_stack.remote(@intCast(cpu_id)).* = stack_top & ~@as(usize, 15);
start_thread.remote(@intCast(cpu_id)).* = make_thread(@ptrCast(&ap_entry), stack_top - r.kib(32));
rtl.barrier.fence(.release);
+1 -1
View File
@@ -67,5 +67,5 @@ pub const panic = std.debug.FullPanic(ke.panic);
comptime {
// Ensure the entry point is linked in.
_ = @import("ex/init.zig");
_ = @import("kern/init.zig");
}