I am in the process of writing an x86_64 BIOS/UEFI kernelin rust, loosely using Philipp Oppermann's websiteas a guide. I am currently using the 8259 PIC to manage interrupts (planning to switch to APIC soon), and I have a basic PS/2 controller/keyboard driver.
My kernel works perfectly fine on BIOS and UEFI builds on QEMU. However, on real hardware, when utilising the keyboard at a high rate, a Segment Not Present exception occurs, with error code 0x13B. This doesn't seem to make any sense to me however, as the instruction causing this exception is RET, which does not alter segment registers (at least to my understanding). I have included an image of the exception and a video of the process leading to its occurrence in my github repository, as I do not seem able to attach files that large here for now.
Stranger still is that the presence of the error code means that this can't be due to a mismapped PIC, as otherwise the given interrupt stack frame would display nonsense values, which it doesn't.
Exception trace:
Code: Select all
I: CCCCCCCCCCCCCCCC3
S: 80000009EFF
PANIC: panicked at kernel/src/interrupts.rs:149:5:
EXCEPTION: SEGMENT NOT PRESENT
InterruptStackFrame {
instruction_pointer: VirtAddr(
0x80000009e11,
),
code_segment: SegmentSelector {
index: 1,
rpl: Ring0,
},
cpu_flags: RFlags(
RESUME_FLAG | INTERRUPT_FLAG | 0x2,
),
stack_pointer: VirtAddr(
0x10000014f98,
),
stack_segment: SegmentSelector {
index: 2,
rpl: Ring0,
},
}
Error: 0x13b
S is the top of the stack, aka the address that would have been returned to
Code: Select all
addr2lineCode: Select all
x86_64-0.15.4/src/instructions/mod.rs:21Code: Select all
hlt()The address on the stack likewise is
Code: Select all
kernel/src/main.rs:31I am lost at how to proceed from here given the infancy of my kernel - I have little to mess up and little to debug with.
FWIW, my older, messier C++ 32-bit BIOS kernel does work on my test machine.
My test machine is a HP Notebook from 2017 with a Insyde BIOS (v F.21).
