Fix CS in IDT
This commit is contained in:
parent
ffdad93fed
commit
6882af0390
@ -160,7 +160,7 @@ args = ["-display", "none", "-drive", "file=build/gila.iso,format=raw,index=0,me
|
||||
[tasks.debug_run]
|
||||
dependencies = ["iso"]
|
||||
command = "${QEMUCOMMAND}"
|
||||
args = ["-s", "-S", "-display", "none", "-drive", "file=build/gila.iso,format=raw,index=0,media=disk", "-no-reboot", "-no-shutdown", "-serial", "stdio", "-d", "int"]
|
||||
args = ["-s", "-S", "-display", "none", "-drive", "file=build/gila.iso,format=raw,index=0,media=disk", "-no-reboot", "-serial", "stdio", "-d", "int"]
|
||||
|
||||
[tasks.debug_view]
|
||||
dependencies = ["iso"]
|
||||
|
||||
@ -8,6 +8,7 @@ pub fn nop() {
|
||||
::x86_64::instructions::nop();
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn long_mode() -> bool {
|
||||
let mut output: u32;
|
||||
unsafe {
|
||||
@ -29,6 +30,7 @@ pub fn ltr(selector: u16) {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn str() -> u16 {
|
||||
let result: u16;
|
||||
unsafe {
|
||||
|
||||
@ -59,9 +59,8 @@ pub struct Selectors {
|
||||
pub gdt: GlobalDescriptorTable<48>,
|
||||
}
|
||||
|
||||
pub const TSS: TaskStateSegment = TaskStateSegment::new();
|
||||
|
||||
lazy_static! {
|
||||
pub static ref TSS: TaskStateSegment = TaskStateSegment::new();
|
||||
#[derive(Debug)]
|
||||
pub static ref SELECTORS: Selectors = {
|
||||
let mut gdt = GlobalDescriptorTable::empty();
|
||||
@ -79,7 +78,8 @@ lazy_static! {
|
||||
let sel_u_cs = gdt.append(Descriptor::user_code_segment());
|
||||
// DO NOT REORDER
|
||||
let sel_tss = gdt.append(
|
||||
Descriptor::tss_segment(&TSS).set_flags(DescriptorFlags::from_bits_retain(0b1010)),
|
||||
Descriptor::tss_segment(&TSS).set_flags(DescriptorFlags::from_bits_retain(0b1010))
|
||||
//.set_access(0b10001011), // This would set the TSS to Busy, but it causes a GPF.
|
||||
);
|
||||
Selectors {
|
||||
sel_kernel_code: sel_k_cs,
|
||||
@ -134,6 +134,7 @@ pub fn read_gdt() -> GlobalDescriptorTable {
|
||||
GlobalDescriptorTable::from_raw_entries(gdt_raw)
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn dump_gdt() {
|
||||
let gdt = crate::arch::x86_64::gdt::read_gdt();
|
||||
log_info!("GDT length: {}", gdt.limit() + 1);
|
||||
|
||||
@ -1,12 +1,14 @@
|
||||
// Copyright (c) 2025 shibedrill
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use crate::arch::x86_64::gdt::SELECTORS;
|
||||
use crate::{LOGGER, format, log_info, log_trace};
|
||||
use crate::{LogLevel, log_error};
|
||||
use lazy_static::lazy_static;
|
||||
use x86_64::PhysAddr;
|
||||
use x86_64::structures::idt::*;
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn get_lapic_addr() -> PhysAddr {
|
||||
let apic_base = x86_64::registers::model_specific::ApicBase::read();
|
||||
let addr: PhysAddr = apic_base.0.start_address();
|
||||
@ -20,9 +22,11 @@ lazy_static! {
|
||||
// TODO: Rewrite using our own x86 interrupt wrapper
|
||||
// code. The x86_interrupt ABI is always breaking, and this
|
||||
// approach will fall apart once multiarch support is re-added.
|
||||
idt.double_fault.set_handler_fn(double_fault);
|
||||
idt.page_fault.set_handler_fn(page_fault);
|
||||
idt.general_protection_fault.set_handler_fn(gen_prot_fault);
|
||||
unsafe {
|
||||
idt.double_fault.set_handler_fn(double_fault).set_code_selector(SELECTORS.sel_kernel_code).set_privilege_level(x86_64::PrivilegeLevel::Ring0);
|
||||
idt.page_fault.set_handler_fn(page_fault).set_code_selector(SELECTORS.sel_kernel_code).set_privilege_level(x86_64::PrivilegeLevel::Ring0);
|
||||
idt.general_protection_fault.set_handler_fn(gen_prot_fault).set_code_selector(SELECTORS.sel_kernel_code).set_privilege_level(x86_64::PrivilegeLevel::Ring0);
|
||||
}
|
||||
idt
|
||||
};
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
// Copyright (c) 2025 shibedrill
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use crate::{SERIAL_3F8, log::*};
|
||||
use crate::log::*;
|
||||
use crate::{format, log_error, memory::alloc::string::String};
|
||||
|
||||
pub fn double_fault(info: String) -> ! {
|
||||
@ -13,6 +13,5 @@ pub fn page_fault_fatal(addr: usize, info: String) -> ! {
|
||||
}
|
||||
|
||||
pub fn gen_prot_fault(info: String) {
|
||||
SERIAL_3F8.lock().log_writeln("Ohhhhh shit double fault");
|
||||
log_error!("General protection fault: {}", info);
|
||||
}
|
||||
|
||||
@ -31,26 +31,18 @@ use limine::firmware::{
|
||||
FIRMWARE_TYPE_EFI32, FIRMWARE_TYPE_EFI64, FIRMWARE_TYPE_SBI, FIRMWARE_TYPE_X86BIOS,
|
||||
};
|
||||
use spin::mutex::Mutex;
|
||||
use x86_64::{
|
||||
VirtAddr,
|
||||
registers::rflags::RFlags,
|
||||
structures::{
|
||||
idt::InterruptStackFrameValue,
|
||||
paging::{PageTableFlags, page_table::PageTableEntry},
|
||||
},
|
||||
};
|
||||
use x86_64::{VirtAddr, registers::rflags::RFlags, structures::idt::InterruptStackFrameValue};
|
||||
|
||||
use crate::{
|
||||
arch::{
|
||||
asm::{self, ltr, str},
|
||||
asm::ltr,
|
||||
x86_64::{
|
||||
cpuid::{CPUID, virt_supported},
|
||||
gdt::{SELECTORS, dump_gdt},
|
||||
interrupts::get_lapic_addr,
|
||||
gdt::SELECTORS,
|
||||
},
|
||||
},
|
||||
boot::modules::MODULE_RESPONSE,
|
||||
memory::paging::{self, active_root_table, map_page, phys_to_virt},
|
||||
memory::paging::active_root_table,
|
||||
};
|
||||
|
||||
lazy_static! {
|
||||
@ -95,19 +87,11 @@ unsafe extern "C" fn main() -> ! {
|
||||
// Initialize all statics so the bootloader memory can be reclaimed
|
||||
memory::init_statics();
|
||||
|
||||
log_info!(
|
||||
"Long mode: {}",
|
||||
if asm::long_mode() {
|
||||
"enabled"
|
||||
} else {
|
||||
"disabled"
|
||||
}
|
||||
);
|
||||
// Ensure IDT exists
|
||||
IDT.load();
|
||||
log_info!("IDT loaded!");
|
||||
SELECTORS.gdt.load();
|
||||
log_info!("GDT loaded!");
|
||||
IDT.load();
|
||||
log_info!("IDT loaded!");
|
||||
|
||||
log_info!(
|
||||
"Kernel cmdline: {}",
|
||||
@ -205,22 +189,11 @@ unsafe extern "C" fn main() -> ! {
|
||||
addr_of!(*root_ptable_info.0) as usize
|
||||
);
|
||||
// This is an expensive function. Only run it if we're actually logging the results.
|
||||
let loglevel = LOGGER.lock().level;
|
||||
if loglevel <= LogLevel::Trace {
|
||||
paging::walk_tables();
|
||||
//let loglevel = LOGGER.lock().level;
|
||||
//if loglevel <= LogLevel::Trace {
|
||||
// paging::walk_tables();
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
dump_gdt();
|
||||
|
||||
let lapic = get_lapic_addr();
|
||||
let mapping = {
|
||||
let mut m = PageTableEntry::new();
|
||||
m.set_addr(lapic, PageTableFlags::PRESENT);
|
||||
m
|
||||
};
|
||||
let res = map_page(phys_to_virt(lapic), mapping);
|
||||
log_info!("Map status: {:?}", res);
|
||||
|
||||
if let Some(modules_list) = *MODULE_RESPONSE
|
||||
&& modules_list.modules()[0].path().ends_with("/userboot.bin")
|
||||
@ -232,23 +205,6 @@ unsafe extern "C" fn main() -> ! {
|
||||
let start_addr = VirtAddr::from_ptr(usermode_fn as *const fn());
|
||||
log_info!("Start address: 0x{:x}", start_addr);
|
||||
|
||||
// This does not work :/
|
||||
/*unsafe {
|
||||
InterruptStackFrameValue::new(
|
||||
start_addr,
|
||||
GDT_SELECTOR_USER_CODE,
|
||||
RFlags::empty(),
|
||||
phys_to_virt(PhysAddr::new(0x1000)),
|
||||
GDT_SELECTOR_USER_DATA,
|
||||
)
|
||||
.iretq()
|
||||
};*/
|
||||
log_trace!("Segment offsets:");
|
||||
log_trace!("GDT_SELECTOR_USER_CODE: {}", SELECTORS.sel_user_code.0);
|
||||
log_trace!("GDT_SELECTOR_USER_DATA: {}", SELECTORS.sel_user_stack.0);
|
||||
log_trace!("GDT_SELECTOR_KERNEL_CODE: {}", SELECTORS.sel_kernel_code.0);
|
||||
log_trace!("GDT_SELECTOR_KERNEL_DATA: {}", SELECTORS.sel_kernel_stack.0);
|
||||
log_trace!("GDT_SELECTOR_TSS: {}", SELECTORS.sel_tss.0);
|
||||
x86_64::registers::model_specific::Star::write(
|
||||
SELECTORS.sel_user_code,
|
||||
SELECTORS.sel_user_stack,
|
||||
@ -256,9 +212,7 @@ unsafe extern "C" fn main() -> ! {
|
||||
SELECTORS.sel_kernel_stack,
|
||||
)
|
||||
.expect("fuck");
|
||||
log_trace!("STR before loading new TSS: {}", str());
|
||||
ltr(SELECTORS.sel_tss.0);
|
||||
log_trace!("STR after loading new TSS: {}", str());
|
||||
ltr(SELECTORS.sel_tss.index());
|
||||
unsafe {
|
||||
InterruptStackFrameValue::new(
|
||||
VirtAddr::from_ptr(usermode_fn as *const fn()),
|
||||
|
||||
@ -115,6 +115,7 @@ pub unsafe fn active_root_table() -> (&'static mut PageTable, usize) {
|
||||
)
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn walk_tables() {
|
||||
iter_table(
|
||||
match control::Cr4::read().contains(Cr4Flags::L5_PAGING) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user