public static void Error(string message) { IDT.SetInterruptHandler(null); Screen.BackgroundColor = Color.Blue; Screen.Clear(); Screen.Goto(1, 0); Screen.Color = Color.White; Screen.Write("*** Kernel Panic ***"); if (firstError) { firstError = false; } else { Screen.Write(" (multiple)"); } Screen.NextLine(); Screen.NextLine(); Screen.Write(message); Screen.NextLine(); Screen.NextLine(); Screen.Write("REGISTERS:"); Screen.NextLine(); Screen.NextLine(); DumpRegisters(); Screen.NextLine(); Screen.Write("STACK TRACE:"); Screen.NextLine(); Screen.NextLine(); DumpStackTrace(); while (true) { // keep debugger running unsafe { Debugger.Process(null); } //Native.Hlt(); } }
/// <summary> /// Interrupts the handler. /// </summary> /// <param name="stackStatePointer">The stack state pointer.</param> private unsafe static void ProcessInterrupt(uint stackStatePointer) { var stack = (IDTStack *)stackStatePointer; Debugger.Process(stack); switch (stack->Interrupt) { case 0: Error(stack, "Divide Error"); break; case 4: Error(stack, "Arithmetic Overflow Exception"); break; case 5: Error(stack, "Bound Check Error"); break; case 6: Error(stack, "Invalid Opcode"); break; case 7: Error(stack, "Co-processor Not Available"); break; case 8: //TODO: Analyze the double fault Error(stack, "Double Fault"); break; case 9: Error(stack, "Co-processor Segment Overrun"); break; case 10: Error(stack, "Invalid TSS"); break; case 11: Error(stack, "Segment Not Present"); break; case 12: Error(stack, "Stack Exception"); break; case 13: Error(stack, "General Protection Exception"); break; case 14: // Check if Null Pointer Exception // Otherwise handle as Page Fault var cr2 = Native.GetCR2(); if ((cr2 >> 5) < 0x1000) { Error(stack, "Null Pointer Exception"); } if (cr2 >= 0xF0000000u) { Error(stack, "Invalid Access Above 0xF0000000"); break; } var physicalpage = PageFrameAllocator.Allocate(); if (physicalpage == IntPtr.Zero) { Error(stack, "Out of Memory"); break; } PageTable.MapVirtualAddressToPhysical(cr2, (uint)physicalpage.ToInt32()); break; case 16: Error(stack, "Co-processor Error"); break; case 19: Error(stack, "SIMD Floating-Point Exception"); break; case Scheduler.ClockIRQ: Interrupt?.Invoke(stack->Interrupt, stack->ErrorCode); Scheduler.ClockInterrupt(new IntPtr(stackStatePointer)); break; case Scheduler.ThreadTerminationSignalIRQ: Scheduler.TerminateCurrentThread(); break; default: { Interrupt?.Invoke(stack->Interrupt, stack->ErrorCode); break; } } PIC.SendEndOfInterrupt(stack->Interrupt); }
/// <summary> /// Interrupts the handler. /// </summary> /// <param name="stack">The stack.</param> private unsafe static void ProcessInterrupt(IDTStack *stack) { Debugger.Process(stack); switch (stack->Interrupt) { case 0: Error(stack, "Divide Error"); break; case 4: Error(stack, "Arithmetic Overflow Exception"); break; case 5: Error(stack, "Bound Check Error"); break; case 6: Error(stack, "Invalid Opcode"); break; case 7: Error(stack, "Co-processor Not Available"); break; case 8: //TODO: Analyze the double fault Error(stack, "Double Fault"); break; case 9: Error(stack, "Co-processor Segment Overrun"); break; case 10: Error(stack, "Invalid TSS"); break; case 11: Error(stack, "Segment Not Present"); break; case 12: Error(stack, "Stack Exception"); break; case 13: Error(stack, "General Protection Exception"); break; case 14: // Check if Null Pointer Exception // Otherwise handle as Page Fault var cr2 = Native.GetCR2(); if ((cr2 >> 5) < 0x1000) { Error(stack, "Null Pointer Exception"); } uint physicalpage = PageFrameAllocator.Allocate(); if (physicalpage == 0x0) { Error(stack, "Out of Memory"); } PageTable.MapVirtualAddressToPhysical(cr2, physicalpage); break; case 16: Error(stack, "Co-processor Error"); break; case 19: Error(stack, "SIMD Floating-Point Exception"); break; default: interruptHandler?.Invoke(stack->Interrupt, stack->ErrorCode); break; } PIC.SendEndOfInterrupt(stack->Interrupt); }