commit bb0addad903bc4ffb19bee59f33dd6760152e342
parent 6d2fe46133dbd3d4b2ffbac18a8fac5c4ad03314
Author: Sylvia Ivory <git@sivory.net>
Date: Fri, 13 Mar 2026 13:04:06 -0700
Remap regions
Diffstat:
6 files changed, 120 insertions(+), 30 deletions(-)
diff --git a/boot/root.zig b/boot/root.zig
@@ -22,7 +22,7 @@ export const _start = make(kmain, abort)._start;
export fn kmain() void {
// We don't return so we can modify SP
- // pi.set_sp(@ptrFromInt(pi.get_stack_address()));
+ pi.set_sp(@ptrFromInt(pi.get_stack_address()));
uart.initialize(921600, .Gpio14, .Gpio15) catch {};
diff --git a/pi/interrupts.zig b/pi/interrupts.zig
@@ -3,6 +3,7 @@ const switching = @import("./switching.zig");
const system = @import("./system.zig");
const PSR = @import("./psr.zig").PSR;
const mem = @import("./mem.zig");
+const pi = @import("./root.zig");
const BASE_ADDRESS: usize = mem.BASE_ADDRESS + 0xB200;
@@ -210,7 +211,7 @@ fn create_trampoline(name: []const u8, offset: []const u8, ret: []const u8) []co
name ++ ":\n" ++
" ldr sp, " ++ name ++ "_data\n" ++
" b " ++ name ++ "_skip\n" ++
- " " ++ name ++ "_data: .word 0x09000000\n" ++
+ " " ++ name ++ "_data: .word 0\n" ++
" " ++ name ++ "_skip:\n" ++
" push {r0-r12, lr}\n" ++
" sub lr, lr, #" ++ offset ++ "\n" ++
@@ -270,6 +271,8 @@ pub fn setup_exception_vector(base_address: u32) void {
mem.put_u32(@ptrFromInt(exception_vector), @intFromPtr(&fast_interrupt));
+ rewrite_stacks(pi.get_interrupt_stack_address());
+
// We've just inserted _new_ code
system.flush_self_modifying_code();
}
diff --git a/pi/pt.zig b/pi/pt.zig
@@ -76,6 +76,14 @@ pub fn set(pt: []mmu.FirstLevelDescriptor, va: u32, pa: u32, attr: pinned.Pinned
return &pt[index];
}
+pub fn remove(pt: []mmu.FirstLevelDescriptor, va: u32) !void {
+ const index = va >> 20;
+
+ pt[index] = fault_page;
+
+ mmu.sync_pte();
+}
+
pub fn get(pt: []mmu.FirstLevelDescriptor, va: u32) !?*mmu.FirstLevelDescriptor {
const index = va >> 20;
const page = &pt[index];
diff --git a/pi/root.zig b/pi/root.zig
@@ -42,11 +42,28 @@ extern const __stack_end__: u32;
extern const __int_stack_start__: u32;
extern const __int_stack_end__: u32;
+// Things might get a bit fucky
+var STACK_ADDRESS: u32 = 0;
+var INT_STACK_ADDRESS: u32 = 0;
pub inline fn get_stack_address() u32 {
- return std.mem.alignForward(u32, @intFromPtr(&__stack_end__), 1024 * 1024);
+ if (STACK_ADDRESS == 0) {
+ STACK_ADDRESS = std.mem.alignForward(u32, @intFromPtr(&__stack_end__), 1024 * 1024);
+ }
+
+ return STACK_ADDRESS;
+}
+pub inline fn update_stack_address(address: u32) void {
+ STACK_ADDRESS = address;
}
pub inline fn get_interrupt_stack_address() u32 {
- return std.mem.alignForward(u32, @intFromPtr(&__int_stack_end__), 1024 * 1024);
+ if (INT_STACK_ADDRESS == 0) {
+ INT_STACK_ADDRESS = std.mem.alignForward(u32, @intFromPtr(&__int_stack_end__), 1024 * 1024);
+ }
+
+ return INT_STACK_ADDRESS;
+}
+pub inline fn update_interrupt_stack_address(address: u32) void {
+ INT_STACK_ADDRESS = address;
}
pub inline fn cycle_counter_init() void {
diff --git a/sylveos/memory.zig b/sylveos/memory.zig
@@ -14,6 +14,11 @@ extern const __program_end__: u32;
extern const __heap_start__: u32;
pub const Region = struct {
+ var PROGRAM_START: ?u32 = null;
+ var PROGRAM_END: ?u32 = null;
+ var HEAP_START: ?u32 = null;
+ var HEAP_END: ?u32 = null;
+
start: u32,
end: u32,
size: u32,
@@ -32,21 +37,36 @@ pub const Region = struct {
}
pub fn program() Region {
- const program_start = std.mem.alignBackward(u32, @intFromPtr(&__program_start__), MB);
- const program_end = std.mem.alignForward(u32, @intFromPtr(&__program_end__), MB);
+ if (PROGRAM_START == null) {
+ PROGRAM_START = std.mem.alignBackward(u32, @intFromPtr(&__program_start__), MB);
+ }
+
+ if (PROGRAM_END == null) {
+ PROGRAM_END = std.mem.alignForward(u32, @intFromPtr(&__program_end__), MB);
+ }
+
+ return Region.init(PROGRAM_START orelse unreachable, PROGRAM_END orelse unreachable);
+ }
- return Region.init(program_start, program_end);
+ pub fn update_program_address(start: u32, end: u32) void {
+ PROGRAM_START = start;
+ PROGRAM_END = end;
+ }
+
+ pub fn update_heap_address(start: u32, end: u32) void {
+ HEAP_START = start;
+ HEAP_END = end;
}
pub fn stack() Region {
const stack_end = pi.get_stack_address();
- const stack_start = stack_end - MB;
+ const stack_start = if (stack_end > io().start) io().end else stack_end - MB;
return Region.init(stack_start, stack_end);
}
pub fn stack_boot() Region {
- const stack_end: u32 = 0x8000000;
+ const stack_end: u32 = 0x0800_0000;
const stack_start = stack_end - MB;
return Region.init(stack_start, stack_end);
@@ -54,7 +74,7 @@ pub const Region = struct {
pub fn interrupt_stack() Region {
const int_stack_end = pi.get_interrupt_stack_address();
- const int_stack_start = int_stack_end - MB;
+ const int_stack_start = @max(int_stack_end - MB, stack().end);
return Region.init(int_stack_start, int_stack_end);
}
@@ -75,11 +95,24 @@ pub const Region = struct {
}
pub fn heap() Region {
- const memory_end = memory().end;
- const heap_start = std.mem.alignBackward(u32, @intFromPtr(&__heap_start__), MB);
- const heap_end = std.mem.alignBackward(u32, memory_end, MB);
+ if (HEAP_START == null) {
+ HEAP_START = std.mem.alignBackward(u32, @intFromPtr(&__heap_start__), MB);
+ }
- return Region.init(heap_start, heap_end);
+ if (HEAP_END == null) {
+ const memory_end = memory().end;
+ HEAP_END = std.mem.alignBackward(u32, memory_end, MB);
+ }
+
+ return Region.init(HEAP_START orelse unreachable, HEAP_END orelse unreachable);
+ }
+
+ pub fn unmap(self: *const Region, pt: []mmu.FirstLevelDescriptor) !void {
+ const size = (self.end / MB) - (self.start / MB);
+
+ for (0..size) |offset| {
+ try page_table.remove(pt, self.start + offset * MB);
+ }
}
pub fn map_to(self: *const Region, pt: []mmu.FirstLevelDescriptor, to: u32, attr: pinned.PinnedAttribute) !void {
@@ -95,7 +128,7 @@ pub const Region = struct {
}
};
-pub fn print_regions() void {
+pub fn print_regions_physical() void {
const memory = Region.memory();
const program = Region.program();
const stack = Region.stack();
@@ -122,6 +155,31 @@ pub fn print_regions() void {
});
}
+pub fn print_regions_virtual() void {
+ const program = Region.program();
+ const stack = Region.stack();
+ const int_stack = Region.interrupt_stack();
+ const heap = Region.heap();
+ const io = Region.io();
+
+ uart.print(
+ \\ Virtual Memory Layout:
+ \\ HEAP: 0x{X:0>8} - 0x{X:0>8} ({Bi})
+ \\ BCM2835 IO: 0x{X:0>8} - 0x{X:0>8} ({Bi})
+ \\ KERNEL STACK: 0x{X:0>8} - 0x{X:0>8} ({Bi})
+ \\KERNEL INTERRUPT STACK: 0x{X:0>8} - 0x{X:0>8} ({Bi})
+ \\ KERNEL: 0x{X:0>8} - 0x{X:0>8} ({Bi})
+ \\
+ \\
+ , .{
+ heap.start, heap.end, heap.size,
+ io.start, io.end, io.size,
+ stack.start, stack.end, stack.size,
+ int_stack.start, int_stack.end, int_stack.size,
+ program.start, program.end, program.size,
+ });
+}
+
pub fn get_allocator() std.mem.Allocator {
const heap = Region.heap();
diff --git a/sylveos/root.zig b/sylveos/root.zig
@@ -13,7 +13,7 @@ const Region = memory.Region;
// The whole point of this code is to relocate the kernel into the high addresses
pub fn main() !void {
- memory.print_regions();
+ memory.print_regions_physical();
// Now it's time for the fun
// We want to copy the kernel's code to high address space
@@ -69,20 +69,17 @@ pub fn main() !void {
mmu.enable();
pi.interrupts.disable_interrupts();
- pi.switching.jump(kernel_relocation + new_main_offset, kernel_relocation);
+ pi.switching.jump(kernel_relocation + new_main_offset, kernel_relocation - (memory.MB / 2));
}
fn new_main() noreturn {
const base_address = Region.io().end + memory.MB;
- const stack = base_address;
- const interrupt_stack = base_address - (memory.MB / 2);
+ // Keep interrupt stack on top of normal stack
+ const stack = base_address - (memory.MB / 2);
+ const interrupt_stack = base_address;
- uart.print(
- \\new_main: 0x{X:8>0}
- \\ stack: 0x{X:8>0}
- \\
- \\
- , .{ @intFromPtr(&new_main), stack });
+ var page_table_raw: [*]mmu.FirstLevelDescriptor = @ptrFromInt(base_address - memory.MB);
+ const pt = page_table_raw[0..4096];
// Now we need to:
// 1. Load the new exception handler
@@ -98,11 +95,18 @@ fn new_main() noreturn {
interrupts.rewrite_stacks(interrupt_stack);
interrupts.enable_interrupts();
- uart.print(
- \\interrupts: 0x{X:8>0}
- \\ stack: 0x{X:8>0}
- \\
- , .{ base_address, interrupt_stack });
+ Region.interrupt_stack().unmap(pt) catch {};
+ Region.stack_boot().unmap(pt) catch {};
+ Region.stack().unmap(pt) catch {};
+
+ uart.print("Remapping regions\n\n", .{});
+
+ pi.update_stack_address(stack);
+ pi.update_interrupt_stack_address(interrupt_stack);
+ Region.update_program_address(base_address, base_address + memory.MB);
+ Region.update_heap_address(0, Region.memory().end - memory.MB * 2);
+
+ memory.print_regions_virtual();
pi.reboot();
}