Updated ISR code to properly handle interrupts with error codes. Fixed bug where page faults would clobber the kernel stack

This commit is contained in:
Xnoe 2022-01-09 12:10:57 +00:00
parent 2825c1ff5e
commit fc2c73225b
Signed by: xnoe
GPG Key ID: 45AC398F44F0DAFE
6 changed files with 31 additions and 25 deletions

View File

@ -4,13 +4,14 @@ test -f isr.S && rm isr.S
cp isr.S.base isr.S cp isr.S.base isr.S
for i ({0..255}); do for i ({0..255}); do
cat >> isr.S << EOF echo "isr$i:" >> isr.S
isr$i: echo " push ebp" >> isr.S
push ebp echo " mov ebp, esp" >> isr.S
mov ebp, esp if (( !(i == 8 || i == 17 || (i >= 10 && i <= 14) ) )); then
push $i echo " push 0" >> isr.S
jmp catchall fi
EOF echo " push $i" >> isr.S
echo " jmp catchall" >> isr.S
done done
x="" x=""

View File

@ -21,37 +21,36 @@ void set_entry(uint8_t interrupt_number, uint16_t code_segment, void(*handler)()
}; };
} }
void page_fault(frame_struct* frame, uint32_t err_code) { void page_fault(frame_struct* frame) {
// Clear interrupts, we don't want to perform a context switch during a page fault.
asm ("cli");
uint32_t problem_address; uint32_t problem_address;
asm("mov %%cr2, %0" : "=a" (problem_address) :); asm("mov %%cr2, %0" : "=a" (problem_address) :);
Global::kernel->terminal->printf("(EIP %x): Page Fault at %x\n", frame->eip, problem_address); Global::kernel->terminal->printf("(CS %x EIP %x): Page Fault at %x Error Code: %x Gate: %d\n", frame->cs, frame->eip, problem_address, frame->errcode, frame->gate);
if (frame->cs & 3 == 0) { if (!(frame->cs & 3)) {
Global::kernel->terminal->printf("[FATAL] Kernel Page Fault!!!\n"); Global::kernel->terminal->printf("[FATAL] Kernel Page Fault!!!\n");
while (1) asm("hlt"); while (1) asm("hlt");
} else { } else {
// Print an error message. // Print an error message.
Global::kernel->terminal->printf("PID %d Terminated due to page fault!\n", Global::currentProc->PID); Global::kernel->terminal->printf("PID %d Terminated due to page fault!\n", Global::currentProc->PID);
// We are currently in the kernel stack for the current process so we need to load the main kernel stack in to esp. asm volatile ("mov %0, %%esp" ::"m"(Global::kernel->globalISRStack));
//Global::kernel->loadPrimaryStack(); Global::kernel->PD->select();
asm volatile ("mov %0, %%esp" ::"m"(Global::kernel->stack));
// We can now safely delete the current process // We can now safely delete the current process
Global::kernel->destroyProcess(Global::currentProc); Global::kernel->destroyProcess(Global::currentProc);
// We want to load the kernel's page directory too. Global::currentProcValid = false;
//Global::kernel->PD->select();
//Global::currentProcValid = false; // Go in to an infinite loop
asm ("int $0x20"); // Call context switch. asm ("sti");
while (1) asm ("hlt"); while (1) asm ("hlt");
} }
} }
void ignore_interrupt(frame_struct* frame) {} void ignore_interrupt(frame_struct* frame) {}
void gpf(frame_struct* frame, uint32_t err_code) { void gpf(frame_struct* frame) {
printf("General Protection Fault %x\n", err_code); printf("(EIP %x) General Protection Fault %x\n", frame->eip, frame->errcode);
while (1) asm("hlt"); while (1) asm("hlt");
} }

View File

@ -16,6 +16,11 @@ struct __attribute__((packed)) frame_struct {
uint32_t edx; uint32_t edx;
uint32_t ecx; uint32_t ecx;
uint32_t eax; uint32_t eax;
uint32_t gate;
uint32_t __ignored2;
uint32_t errcode;
uint32_t eip; uint32_t eip;
uint16_t cs; uint16_t cs;
uint16_t _ignored0; uint16_t _ignored0;

View File

@ -16,6 +16,7 @@ Kernel::Kernel(PageDirectory* page_directory, PageMap* phys, PageMap* virt, uint
void Kernel::init_kernel() { void Kernel::init_kernel() {
this->pid_map = new xnoe::hashtable<uint32_t, Process*>(); this->pid_map = new xnoe::hashtable<uint32_t, Process*>();
this->globalISRStack = (new uint8_t[0x8000]) + 0x8000;
} }
Process* Kernel::createProcess(char* filename) { Process* Kernel::createProcess(char* filename) {

View File

@ -10,6 +10,7 @@ class Kernel : public Process {
public: public:
uint32_t currentPID; uint32_t currentPID;
uint32_t stack; uint32_t stack;
uint32_t globalISRStack;
Terminal* terminal; Terminal* terminal;
xnoe::hashtable<uint32_t, Process*>* pid_map; // Map of PIDs -> Process*s xnoe::hashtable<uint32_t, Process*>* pid_map; // Map of PIDs -> Process*s

View File

@ -186,4 +186,3 @@ uint32_t Process::count_allocations(uint32_t address) {
else else
return 0; return 0;
} }