From c7d92071e1dd11c45999457b16554b4abaa73b28 Mon Sep 17 00:00:00 2001 From: salmonik Date: Sun, 2 Aug 2026 15:21:34 +0200 Subject: v0.5.5: crash reports go to a dedicated CRASHLOG USB stick The fault handler now writes crash.log to the volume labeled CRASHLOG (label-selected via fat::crash_vol), falling back to slot 0. On real hardware the boot USB may be unwritable, so a second stick labeled CRASHLOG survives the write; the shell auto-prints the previous crash report from it at next boot (read_crash_log resolves /disk//crash.log through the FAT path, since Disk nodes hold no cached children). - fat.rs: volume_label() + crash_vol() (no allocation) - fs.rs: write_crash_log targets crash_vol(); read_crash_log prefers the CRASHLOG disk node; drop now-unused first_disk() - mkdisk.sh: --label option - test-fault.sh: boots with a dedicated CRASHLOG stick (mkfs -F 32 -n CRASHLOG), verifies crash.log lands there and NOT on the ESP --- rsnix/src/gdt.rs | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) (limited to 'rsnix/src/gdt.rs') diff --git a/rsnix/src/gdt.rs b/rsnix/src/gdt.rs index 514ed2e..f3d8b9a 100644 --- a/rsnix/src/gdt.rs +++ b/rsnix/src/gdt.rs @@ -116,12 +116,14 @@ impl Tss { } } -/// 4 KiB page-aligned block for the IST stacks. -#[repr(align(4096))] -struct Page([u8; 4096]); +/// IST stack size: the fault path (fault dump + best-effort crash-log +/// FAT write) is deep, so each IST stack is 32 KiB, allocated from the +/// heap at init. They must NOT live in .bss: a 4 KiB .bss stack placed +/// next to kernel statics silently overwrites them on overflow (the FAT +/// ACTIVE_VOL was clobbered this way — a "no volume at slot 8" crash in +/// the fault path). The heap region is far from the kernel image. +const IST_STACK_SIZE: usize = 32 * 1024; -static mut PF_STACK: Page = Page([0; 4096]); -static mut DF_STACK: Page = Page([0; 4096]); static mut TSS: Tss = Tss::zero(); // GDT slots are 8 bytes except the TSS descriptor at index 63, which is // 16 bytes — total 64*8 + 16. @@ -193,8 +195,16 @@ pub fn init() -> bool { // TSS descriptor (16 bytes) at index 63. let tss_base = core::ptr::addr_of_mut!(TSS) as usize as u64; - TSS.ist1 = core::ptr::addr_of_mut!(PF_STACK.0[0]) as usize as u64 + 4096; - TSS.ist2 = core::ptr::addr_of_mut!(DF_STACK.0[0]) as usize as u64 + 4096; + // IST stacks come from the heap (see IST_STACK_SIZE): 32 KiB each, + // well away from the kernel image/.bss so an overflowing fault + // path can't silently overwrite statics. + let pf = crate::memory::allocate(IST_STACK_SIZE); + let df = crate::memory::allocate(IST_STACK_SIZE); + if pf.is_null() || df.is_null() { + return false; + } + TSS.ist1 = pf as u64 + IST_STACK_SIZE as u64; + TSS.ist2 = df as u64 + IST_STACK_SIZE as u64; TSS.iomap_base = TSS_SIZE as u16; // no I/O bitmap let mut td = [0u8; 16]; -- cgit v1.2.3