fixing GPFs
This commit is contained in:
parent
108ddb7cf9
commit
f9fd19b6d0
@ -54,7 +54,6 @@ pub struct Selectors {
|
|||||||
pub sel_kernel_stack: SegmentSelector,
|
pub sel_kernel_stack: SegmentSelector,
|
||||||
pub sel_user_code: SegmentSelector,
|
pub sel_user_code: SegmentSelector,
|
||||||
pub sel_user_stack: SegmentSelector,
|
pub sel_user_stack: SegmentSelector,
|
||||||
#[allow(unused)]
|
|
||||||
pub sel_tss: SegmentSelector,
|
pub sel_tss: SegmentSelector,
|
||||||
pub gdt: GlobalDescriptorTable<48>,
|
pub gdt: GlobalDescriptorTable<48>,
|
||||||
}
|
}
|
||||||
@ -79,7 +78,7 @@ lazy_static! {
|
|||||||
// DO NOT REORDER
|
// DO NOT REORDER
|
||||||
let sel_tss = gdt.append(
|
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.
|
.set_access(0b10001011), // This would set the TSS to Busy, but it causes a GPF.
|
||||||
);
|
);
|
||||||
Selectors {
|
Selectors {
|
||||||
sel_kernel_code: sel_k_cs,
|
sel_kernel_code: sel_k_cs,
|
||||||
|
|||||||
@ -23,9 +23,9 @@ lazy_static! {
|
|||||||
// code. The x86_interrupt ABI is always breaking, and this
|
// code. The x86_interrupt ABI is always breaking, and this
|
||||||
// approach will fall apart once multiarch support is re-added.
|
// approach will fall apart once multiarch support is re-added.
|
||||||
unsafe {
|
unsafe {
|
||||||
idt.double_fault.set_handler_fn(double_fault).set_code_selector(SELECTORS.sel_kernel_code).set_privilege_level(x86_64::PrivilegeLevel::Ring0);
|
idt.double_fault.set_handler_fn(double_fault).set_code_selector(SELECTORS.sel_kernel_code);
|
||||||
idt.page_fault.set_handler_fn(page_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);
|
||||||
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.general_protection_fault.set_handler_fn(gen_prot_fault).set_code_selector(SELECTORS.sel_kernel_code);
|
||||||
}
|
}
|
||||||
idt
|
idt
|
||||||
};
|
};
|
||||||
@ -35,6 +35,7 @@ lazy_static! {
|
|||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
extern "x86-interrupt" fn double_fault(info: InterruptStackFrame, _: u64) -> ! {
|
extern "x86-interrupt" fn double_fault(info: InterruptStackFrame, _: u64) -> ! {
|
||||||
crate::interrupt::double_fault(format!("{info:#?}"));
|
crate::interrupt::double_fault(format!("{info:#?}"));
|
||||||
|
unsafe { info.iretq() }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
@ -68,11 +69,13 @@ extern "x86-interrupt" fn page_fault(info: InterruptStackFrame, errcode: PageFau
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
extern "x86-interrupt" fn gen_prot_fault(info: InterruptStackFrame, _: u64) {
|
extern "x86-interrupt" fn gen_prot_fault(info: InterruptStackFrame, error: u64) {
|
||||||
crate::interrupt::gen_prot_fault(format!(
|
crate::interrupt::gen_prot_fault(format!(
|
||||||
"RIP 0x{:x}, CS {} ({:?})",
|
"RIP 0x{:x}, CS {} ({:?}), error: 0x{:x}",
|
||||||
info.instruction_pointer,
|
info.instruction_pointer,
|
||||||
info.code_segment.index(),
|
info.code_segment.index(),
|
||||||
info.code_segment.rpl()
|
info.code_segment.rpl(),
|
||||||
|
error
|
||||||
));
|
));
|
||||||
|
unsafe { info.iretq() }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,7 +3,10 @@ use x86_64::{VirtAddr, registers::rflags::RFlags, structures::idt::InterruptStac
|
|||||||
use crate::{
|
use crate::{
|
||||||
arch::{
|
arch::{
|
||||||
asm::ltr,
|
asm::ltr,
|
||||||
x86_64::{gdt::SELECTORS, interrupts::IDT},
|
x86_64::{
|
||||||
|
gdt::{SELECTORS, dump_gdt},
|
||||||
|
interrupts::IDT,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
log::{LOGGER, LogLevel},
|
log::{LOGGER, LogLevel},
|
||||||
log_info,
|
log_info,
|
||||||
@ -24,6 +27,7 @@ pub fn init() -> Result<(), ()> {
|
|||||||
SELECTORS.sel_kernel_stack,
|
SELECTORS.sel_kernel_stack,
|
||||||
)
|
)
|
||||||
.expect("Segment order in GDT is bad");
|
.expect("Segment order in GDT is bad");
|
||||||
|
dump_gdt();
|
||||||
ltr(SELECTORS.sel_tss.index());
|
ltr(SELECTORS.sel_tss.index());
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,8 +4,8 @@
|
|||||||
use crate::log::*;
|
use crate::log::*;
|
||||||
use crate::{format, log_error, memory::alloc::string::String};
|
use crate::{format, log_error, memory::alloc::string::String};
|
||||||
|
|
||||||
pub fn double_fault(info: String) -> ! {
|
pub fn double_fault(info: String) {
|
||||||
panic!("Double fault: {}", info);
|
log_error!("Double fault: {}", info);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn page_fault_fatal(addr: usize, info: String) -> ! {
|
pub fn page_fault_fatal(addr: usize, info: String) -> ! {
|
||||||
|
|||||||
@ -177,6 +177,7 @@ unsafe extern "C" fn main() -> ! {
|
|||||||
{
|
{
|
||||||
let ub = modules_list.modules()[0];
|
let ub = modules_list.modules()[0];
|
||||||
log_info!("Found userboot: {} {}", ub.path(), ub.cmdline());
|
log_info!("Found userboot: {} {}", ub.path(), ub.cmdline());
|
||||||
|
// TODO: remap userboot as user pages
|
||||||
|
|
||||||
let start_addr = VirtAddr::from_ptr(ub.data() as *const [u8]);
|
let start_addr = VirtAddr::from_ptr(ub.data() as *const [u8]);
|
||||||
arch::startup::jump_to_usermode(VirtAddr::new(0xfffffff800000000), start_addr)
|
arch::startup::jump_to_usermode(VirtAddr::new(0xfffffff800000000), start_addr)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user