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:
parent
2825c1ff5e
commit
fc2c73225b
@ -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=""
|
||||||
|
@ -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");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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) {
|
||||||
|
@ -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
|
||||||
|
@ -186,4 +186,3 @@ uint32_t Process::count_allocations(uint32_t address) {
|
|||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user