From 63edda1d28e08584bcacaaa21d149e5ee0d7439b Mon Sep 17 00:00:00 2001 From: August Date: Thu, 8 Oct 2026 18:33:18 +0000 Subject: [PATCH] Fix badly loaded TSS descriptor --- src/kernel/arch/x86_64/gdt.rs | 18 ++++++++++-------- src/kernel/arch/x86_64/interrupts.rs | 6 +++++- src/kernel/arch/x86_64/startup.rs | 9 +++++++-- src/kernel/main.rs | 6 +++++- 4 files changed, 27 insertions(+), 12 deletions(-) diff --git a/src/kernel/arch/x86_64/gdt.rs b/src/kernel/arch/x86_64/gdt.rs index 57cfd5b..74b9218 100644 --- a/src/kernel/arch/x86_64/gdt.rs +++ b/src/kernel/arch/x86_64/gdt.rs @@ -79,16 +79,18 @@ lazy_static! { let sel_tss = gdt.append( { let tss_addr = addr_of!(TSS) as u128; - let tss_size = size_of_val(&TSS) as u128; + log_trace!("TSS address: 0x{:032x}", tss_addr); + let tss_size = size_of::() as u128 - 1; + log_trace!("TSS size: 0x{:x}", tss_size); let mut tss_descriptor: u128 = 0; - tss_descriptor.set_bits(0..=15, tss_size.bits(0..=15)); // Limit bits 0..=15 + tss_descriptor.set_bits(56..=95, tss_addr.bits(24..=63)); // Base bits 24..=63 + tss_descriptor.set_bits(52..=55, 0b0000); // Flags: 1-byte granularity tss_descriptor.set_bits(48..=51, tss_size.bits(16..=19)); // Limit bits 16..=19 - tss_descriptor.set_bits(16..=39, tss_addr.bits(0..=24)); // Base bits 0..=24 - tss_descriptor.set_bits(56..=95, tss_addr.bits(25..=63)); // Base bits 25..=63 - tss_descriptor.set_bits(40..=47, 0b10110001); - tss_descriptor.set_bits(52..=55, 0b1010); - log_info!("TSS descriptor (calculated manually): 0x{:032x}", tss_descriptor); - Descriptor::SystemSegment(tss_descriptor.bits(64..=127) as u64, tss_descriptor.bits(0..=63) as u64) + tss_descriptor.set_bits(40..=47, 0b10001001); // Access: Present, ring 0, system segment + tss_descriptor.set_bits(16..=39, tss_addr.bits(0..=23)); // Base bits 0..=23 + tss_descriptor.set_bits(0..=15, tss_size.bits(0..=15)); // Limit bits 0..=15 + // MAKE SURE that the lower half is the first byte! This is loaded little-endian into the GDT! + Descriptor::SystemSegment(tss_descriptor.bits(0..=63) as u64, tss_descriptor.bits(64..=127) as u64) } ); Selectors { diff --git a/src/kernel/arch/x86_64/interrupts.rs b/src/kernel/arch/x86_64/interrupts.rs index e270c29..cf966c8 100644 --- a/src/kernel/arch/x86_64/interrupts.rs +++ b/src/kernel/arch/x86_64/interrupts.rs @@ -51,7 +51,11 @@ lazy_static! { } extern "x86-interrupt" fn div_zero(info: InterruptStackFrame) { - log_error!("Divide by zero error: 0x{:x}, {:?}", info.instruction_pointer, info.code_segment.rpl()); + log_error!( + "Divide by zero error: 0x{:x}, {:?}", + info.instruction_pointer, + info.code_segment.rpl() + ); unsafe { info.iretq() } } diff --git a/src/kernel/arch/x86_64/startup.rs b/src/kernel/arch/x86_64/startup.rs index e951a08..a39d7b4 100644 --- a/src/kernel/arch/x86_64/startup.rs +++ b/src/kernel/arch/x86_64/startup.rs @@ -1,4 +1,8 @@ -use x86_64::{VirtAddr, registers::{rflags::RFlags, segmentation::Segment}, structures::idt::InterruptStackFrameValue}; +use x86_64::{ + VirtAddr, + registers::{rflags::RFlags, segmentation::Segment}, + structures::idt::InterruptStackFrameValue, +}; use crate::{ arch::{ @@ -28,8 +32,9 @@ pub fn init() -> Result<(), ()> { x86_64::registers::segmentation::CS::set_reg(SELECTORS.sel_kernel_code); x86_64::registers::segmentation::SS::set_reg(SELECTORS.sel_kernel_stack); } - //ltr(SELECTORS.sel_tss.index()) // THIS WILL CAUSE A GPF, YOU STUPID WHORE + log_info!("Segment registers loaded!"); ltr(SELECTORS.sel_tss.0); + log_info!("Task register loaded!"); Ok(()) } diff --git a/src/kernel/main.rs b/src/kernel/main.rs index e7c8b42..f58a715 100644 --- a/src/kernel/main.rs +++ b/src/kernel/main.rs @@ -97,7 +97,11 @@ unsafe extern "C" fn main() -> ! { memory::log_memory(); memory::log_address(); - log_info!("TSS descriptor: 0x{:08x} {:08x}", SELECTORS.gdt.entries()[SELECTORS.sel_tss.index() as usize + 1].raw(), SELECTORS.gdt.entries()[SELECTORS.sel_tss.index() as usize].raw()); + log_info!( + "TSS descriptor: 0x{:08x} {:08x}", + SELECTORS.gdt.entries()[SELECTORS.sel_tss.index() as usize + 1].raw(), + SELECTORS.gdt.entries()[SELECTORS.sel_tss.index() as usize].raw() + ); if let Some(modules_list) = *MODULE_RESPONSE && modules_list.modules()[0].path().ends_with("/userboot.bin") {