/// <summary> /// Throws a stack exception. /// </summary> /// <remarks> /// Used by CPU interrupts to handle the creation of the exception object and calling Throw. /// </remarks> public static void Throw_StackException() { HaltReason = "Stack exception."; BasicConsole.SetTextColour(BasicConsole.error_colour); BasicConsole.WriteLine(HaltReason); BasicConsole.SetTextColour(BasicConsole.default_colour); Throw(new FOS_System.Exceptions.StackException()); }
/// <summary> /// Throws an invalid op code exception. /// </summary> /// <remarks> /// Used by CPU interrupts to handle the creation of the exception object and calling Throw. /// </remarks> public static void Throw_InvalidOpCodeException() { HaltReason = "Invalid op code exception."; BasicConsole.SetTextColour(BasicConsole.error_colour); BasicConsole.WriteLine(HaltReason); BasicConsole.SetTextColour(BasicConsole.default_colour); Throw(new FOS_System.Exceptions.InvalidOpCodeException()); }
/// <summary> /// Throws an overflow exception. /// </summary> /// <remarks> /// Used by CPU interrupts to handle the creation of the exception object and calling Throw. /// </remarks> public static void Throw_OverflowException() { HaltReason = "Overflow exception."; BasicConsole.SetTextColour(BasicConsole.error_colour); BasicConsole.WriteLine(HaltReason); BasicConsole.SetTextColour(BasicConsole.default_colour); Throw(new FOS_System.Exceptions.OverflowException("Processor reported an overflow.")); }
/// <summary> /// Throws a divide by zero exception storing the specified exception address. /// </summary> /// <param name="address">The address of the code that caused the exception.</param> /// <remarks> /// Used by CPU interrupts to handle the creation of the exception object and calling Throw. /// </remarks> public static void Throw_DivideByZeroException(uint address) { HaltReason = "Divide by zero exception."; BasicConsole.SetTextColour(BasicConsole.error_colour); BasicConsole.WriteLine(HaltReason); BasicConsole.SetTextColour(BasicConsole.default_colour); Throw(new FOS_System.Exceptions.DivideByZeroException(address)); }
static unsafe void Main() { ExceptionMethods.AddExceptionHandlerInfo(null, null); try { Hardware.IO.Serial.Serial.InitCOM1(); Hardware.IO.Serial.Serial.InitCOM2(); Hardware.IO.Serial.Serial.InitCOM3(); BasicConsole.SecondaryOutput = BasicConsole_SecondaryOutput; BasicConsole.SecondaryOutputEnabled = true; Hardware.Devices.CPU.InitDefault(); BasicConsole.WriteLine("Creating kernel process..."); Process KernelProcess = ProcessManager.CreateProcess(Tasks.KernelTask.Main, "Kernel Task", false); KernelProcess.TheMemoryLayout.NoUnload = true; ProcessManager.KernelProcess = KernelProcess; BasicConsole.WriteLine("Getting kernel thread..."); Thread KernelThread = ((Thread)KernelProcess.Threads[0]); BasicConsole.WriteLine("Initialising kernel thread stack..."); Hardware.VirtMemManager.Unmap(KernelThread.State->ThreadStackTop - 4092); KernelProcess.TheMemoryLayout.RemovePage((uint)KernelThread.State->ThreadStackTop - 4092); KernelThread.State->ThreadStackTop = GetKernelStackPtr(); KernelThread.State->ESP = (uint)KernelThread.State->ThreadStackTop; BasicConsole.WriteLine("Initialising kernel process heap..."); KernelProcess.HeapLock = Heap.AccessLock; KernelProcess.HeapPtr = Heap.FBlock; BasicConsole.WriteLine("Initialising kernel process GC..."); KernelProcess.TheGCState = FOS_System.GC.State; BasicConsole.WriteLine("Registering kernel process..."); ProcessManager.RegisterProcess(KernelProcess, Scheduler.Priority.Normal); BasicConsole.WriteLine("Initialising kernel ISRs..."); KernelProcess.ISRHandler = Tasks.KernelTask.HandleISR; KernelProcess.SwitchProcessForISRs = false; KernelProcess.ISRsToHandle.Set(48); BasicConsole.WriteLine("Initialising kernel IRQs..."); KernelProcess.IRQHandler = Tasks.KernelTask.HandleIRQ; KernelProcess.SwitchProcessForIRQs = false; KernelProcess.IRQsToHandle.Set(0); BasicConsole.WriteLine("Initialising default timer..."); Hardware.Devices.Timer.InitDefault(); BasicConsole.PrimaryOutputEnabled = true; BasicConsole.SecondaryOutputEnabled = false; BasicConsole.WriteLine(); BasicConsole.WriteLine(); BasicConsole.WriteLine(TextSplashScreen); BasicConsole.SecondaryOutputEnabled = true; BasicConsole.PrimaryOutputEnabled = false; for (int i = 0; i < TextSplashScreen.length; i += 80) { TextSplashScreen[i] = '\n'; } BasicConsole.WriteLine(TextSplashScreen); BasicConsole.PrimaryOutputEnabled = true; BasicConsole.SecondaryOutputEnabled = true; for (int i = 0; i < 37; i++) { BasicConsole.Write(' '); } char num = '1'; for (int i = 0; i < 3; i++) { BasicConsole.Write(num++); Hardware.Devices.Timer.Default.Wait(1000); BasicConsole.Write(' '); } BasicConsole.WriteLine(); BasicConsole.WriteLine("FlingOS(TM)"); BasicConsole.WriteLine("Copyright (C) 2014-15 Edward Nutting"); BasicConsole.WriteLine("This program comes with ABSOLUTELY NO WARRANTY;."); BasicConsole.WriteLine("This is free software, and you are welcome to redistribute it"); BasicConsole.WriteLine("under certain conditions; See GPL V2 for details, a copy of"); BasicConsole.WriteLine("which should have been provided with the executable."); BasicConsole.WriteLine("Fling OS Running..."); BasicConsole.WriteLine(); #if MIPS BasicConsole.WriteLine("MIPS Kernel"); #elif x86 || AnyCPU BasicConsole.WriteLine("x86 Kernel"); #endif BasicConsole.WriteLine(); //uint bpm = 140; //Hardware.Timers.PIT.ThePIT.PlayNote( // Hardware.Timers.PIT.MusicalNote.C4, // Hardware.Timers.PIT.MusicalNoteValue.Quaver, // bpm); //Hardware.Timers.PIT.ThePIT.PlayNote( // Hardware.Timers.PIT.MusicalNote.Silent, // Hardware.Timers.PIT.MusicalNoteValue.Minim, // bpm); //Hardware.Timers.PIT.ThePIT.PlayNote( // Hardware.Timers.PIT.MusicalNote.E4, // Hardware.Timers.PIT.MusicalNoteValue.Quaver, // bpm); //Hardware.Timers.PIT.ThePIT.PlayNote( // Hardware.Timers.PIT.MusicalNote.Silent, // Hardware.Timers.PIT.MusicalNoteValue.Minim, // bpm); //Hardware.Timers.PIT.ThePIT.PlayNote( // Hardware.Timers.PIT.MusicalNote.G4, // Hardware.Timers.PIT.MusicalNoteValue.Quaver, // bpm); //Hardware.Timers.PIT.ThePIT.PlayNote( // Hardware.Timers.PIT.MusicalNote.Silent, // Hardware.Timers.PIT.MusicalNoteValue.Minim, // bpm); //Hardware.Timers.PIT.ThePIT.PlayNote( // Hardware.Timers.PIT.MusicalNote.C5, // Hardware.Timers.PIT.MusicalNoteValue.Minim, // bpm); //Hardware.Timers.PIT.ThePIT.PlayNote( // Hardware.Timers.PIT.MusicalNote.Silent, // Hardware.Timers.PIT.MusicalNoteValue.Minim, // bpm); //Hardware.Timers.PIT.ThePIT.PlayNote( // Hardware.Timers.PIT.MusicalNote.G4, // Hardware.Timers.PIT.MusicalNoteValue.Minim, // bpm); //Hardware.Timers.PIT.ThePIT.PlayNote( // Hardware.Timers.PIT.MusicalNote.C5, // Hardware.Timers.PIT.MusicalNoteValue.Minim, // bpm); BasicConsole.WriteLine("Initialising scheduler..."); Scheduler.Init(); // Busy wait until the scheduler interrupts us. while (true) { ; } // We will never return to this point since there is no way for the scheduler to point // to it. } catch { BasicConsole.SetTextColour(BasicConsole.error_colour); if (ExceptionMethods.CurrentException is FOS_System.Exceptions.PageFaultException) { BasicConsole.WriteLine("Page fault exception unhandled!"); } else { BasicConsole.WriteLine("Startup error! " + ExceptionMethods.CurrentException.Message); } BasicConsole.WriteLine("FlingOS forced to halt!"); BasicConsole.SetTextColour(BasicConsole.default_colour); } BasicConsole.WriteLine("Fling OS Ended."); //Necessary - no way of returning from this method since add exception info // at start cannot be "undone" so stack is "corrupted" if we try // to "ret" //So we just halt the CPU for want of a better solution later when ACPI is //implemented. ExceptionMethods.HaltReason = "End of Main"; Halt(0xFFFFFFFF); //TODO: Proper shutdown method }
public static void Halt(uint lastAddress) { BasicConsole.PrimaryOutputEnabled = true; try { Hardware.Devices.Keyboard.CleanDefault(); Hardware.Devices.Timer.CleanDefault(); } catch { } BasicConsole.SetTextColour(BasicConsole.warning_colour); BasicConsole.Write("Halt Reason: "); BasicConsole.WriteLine(ExceptionMethods.HaltReason); FOS_System.String LastAddressStr = "Last address: 0x "; uint y = lastAddress; int offset = 23; #region Address while (offset > 15) { uint rem = y & 0xFu; switch (rem) { case 0: LastAddressStr[offset] = '0'; break; case 1: LastAddressStr[offset] = '1'; break; case 2: LastAddressStr[offset] = '2'; break; case 3: LastAddressStr[offset] = '3'; break; case 4: LastAddressStr[offset] = '4'; break; case 5: LastAddressStr[offset] = '5'; break; case 6: LastAddressStr[offset] = '6'; break; case 7: LastAddressStr[offset] = '7'; break; case 8: LastAddressStr[offset] = '8'; break; case 9: LastAddressStr[offset] = '9'; break; case 10: LastAddressStr[offset] = 'A'; break; case 11: LastAddressStr[offset] = 'B'; break; case 12: LastAddressStr[offset] = 'C'; break; case 13: LastAddressStr[offset] = 'D'; break; case 14: LastAddressStr[offset] = 'E'; break; case 15: LastAddressStr[offset] = 'F'; break; } y >>= 4; offset--; } #endregion BasicConsole.WriteLine(LastAddressStr); BasicConsole.SetTextColour(BasicConsole.default_colour); if (ExceptionMethods.CurrentException != null) { BasicConsole.SetTextColour(BasicConsole.error_colour); BasicConsole.WriteLine(ExceptionMethods.CurrentException.Message); if (ExceptionMethods.CurrentException is FOS_System.Exceptions.PageFaultException) { BasicConsole.Write("Address: "); BasicConsole.WriteLine(((FOS_System.Exceptions.PageFaultException)ExceptionMethods.CurrentException).address); BasicConsole.Write("Code: "); BasicConsole.WriteLine(((FOS_System.Exceptions.PageFaultException)ExceptionMethods.CurrentException).errorCode); } else if (ExceptionMethods.CurrentException is FOS_System.Exceptions.DoubleFaultException) { BasicConsole.Write("Code: "); BasicConsole.WriteLine(((FOS_System.Exceptions.DoubleFaultException)ExceptionMethods.CurrentException).ErrorCode); } BasicConsole.SetTextColour(BasicConsole.default_colour); } BasicConsole.SetTextColour(BasicConsole.error_colour); BasicConsole.WriteLine("Kernel halting!"); BasicConsole.SetTextColour(BasicConsole.default_colour); PreReqs.Reset(); }
public static unsafe void AddExceptionHandlerInfo( void *handlerPtr, void *filterPtr) { if (State == null) { BasicConsole.SetTextColour(BasicConsole.error_colour); BasicConsole.WriteLine("Error! ExceptionMethods.State is null."); BasicConsole.DelayOutput(10); BasicConsole.SetTextColour(BasicConsole.default_colour); } State->depth++; //if (filterPtr != null) //{ // BasicConsole.WriteLine("Enter try-catch block"); //} //else //{ // BasicConsole.WriteLine("Enter try-finally block"); //} AddExceptionHandlerInfo_EntryStackState *BasePtr = (AddExceptionHandlerInfo_EntryStackState *)BasePointer; uint LocalsSize = (uint)BasePtr - (uint)StackPointer; // Create space for setting up handler info StackPointer -= sizeof(ExceptionHandlerInfo); // Setup handler info ExceptionHandlerInfo *ExHndlrPtr = (ExceptionHandlerInfo *)StackPointer; ExHndlrPtr->EBP = BasePtr->EBP; // EBP + 8 (for ret addr, ebp) + 8 (for args) - sizeof(ExceptionHandlerInfo) ExHndlrPtr->ESP = (uint)BasePtr + 8 + 8 - (uint)sizeof(ExceptionHandlerInfo); ExHndlrPtr->FilterAddress = (byte *)filterPtr; ExHndlrPtr->HandlerAddress = (byte *)handlerPtr; ExHndlrPtr->PrevHandlerPtr = State->CurrentHandlerPtr; ExHndlrPtr->InHandler = 0; ExHndlrPtr->ExPending = 0; ExHndlrPtr->Ex = null; State->CurrentHandlerPtr = (ExceptionHandlerInfo *)((byte *)ExHndlrPtr + (LocalsSize + 12)); StackPointer -= 8; // For duplicate (empty) args StackPointer -= 8; // For duplicate ebp, ret addr // Setup the duplicate stack data // - Nothing to do for args - duplicate values don't matter // - Copy over ebp and return address uint *DuplicateValsStackPointer = (uint *)StackPointer; *DuplicateValsStackPointer = BasePtr->EBP; *(DuplicateValsStackPointer + 1) = BasePtr->RetAddr; ShiftStack((byte *)ExHndlrPtr + sizeof(ExceptionHandlerInfo) - 4, LocalsSize + 12); // Shift stack pointer to correct position - eliminates "empty space" of duplicates StackPointer += 16; // MethodEnd will: // - Add size of locals to esp // - Pop EBP // - Ret to ret address // Caller will: // - Add size of args to esp // Which should leave the stack at the bottom of the (shifted up) ex handler info }
/// <summary> /// Throws a page fault exception. /// </summary> /// <param name="errorCode">The error code associated with the page fault.</param> /// <param name="address">The address which caused the fault.</param> /// <remarks> /// Used by CPU interrupts to handle the creation of the exception object and calling Throw. /// </remarks> public static void Throw_PageFaultException(uint eip, uint errorCode, uint address) { if (ThePageFaultHandler != null) { ThePageFaultHandler(eip, errorCode, address); } else { BasicConsole.SetTextColour(BasicConsole.error_colour); BasicConsole.WriteLine("Page fault exception!"); BasicConsole.DelayOutput(10); HaltReason = "Page fault exception. Address: 0x , errorCode: 0x , eip: 0x "; uint y = address; int offset = 40; #region Address while (offset > 32) { uint rem = y & 0xFu; switch (rem) { case 0: HaltReason[offset] = '0'; break; case 1: HaltReason[offset] = '1'; break; case 2: HaltReason[offset] = '2'; break; case 3: HaltReason[offset] = '3'; break; case 4: HaltReason[offset] = '4'; break; case 5: HaltReason[offset] = '5'; break; case 6: HaltReason[offset] = '6'; break; case 7: HaltReason[offset] = '7'; break; case 8: HaltReason[offset] = '8'; break; case 9: HaltReason[offset] = '9'; break; case 10: HaltReason[offset] = 'A'; break; case 11: HaltReason[offset] = 'B'; break; case 12: HaltReason[offset] = 'C'; break; case 13: HaltReason[offset] = 'D'; break; case 14: HaltReason[offset] = 'E'; break; case 15: HaltReason[offset] = 'F'; break; } y >>= 4; offset--; } #endregion y = errorCode; offset = 63; #region Error Code while (offset > 55) { uint rem = y & 0xFu; switch (rem) { case 0: HaltReason[offset] = '0'; break; case 1: HaltReason[offset] = '1'; break; case 2: HaltReason[offset] = '2'; break; case 3: HaltReason[offset] = '3'; break; case 4: HaltReason[offset] = '4'; break; case 5: HaltReason[offset] = '5'; break; case 6: HaltReason[offset] = '6'; break; case 7: HaltReason[offset] = '7'; break; case 8: HaltReason[offset] = '8'; break; case 9: HaltReason[offset] = '9'; break; case 10: HaltReason[offset] = 'A'; break; case 11: HaltReason[offset] = 'B'; break; case 12: HaltReason[offset] = 'C'; break; case 13: HaltReason[offset] = 'D'; break; case 14: HaltReason[offset] = 'E'; break; case 15: HaltReason[offset] = 'F'; break; } y >>= 4; offset--; } #endregion y = eip; offset = 80; #region EIP while (offset > 72) { uint rem = y & 0xFu; switch (rem) { case 0: HaltReason[offset] = '0'; break; case 1: HaltReason[offset] = '1'; break; case 2: HaltReason[offset] = '2'; break; case 3: HaltReason[offset] = '3'; break; case 4: HaltReason[offset] = '4'; break; case 5: HaltReason[offset] = '5'; break; case 6: HaltReason[offset] = '6'; break; case 7: HaltReason[offset] = '7'; break; case 8: HaltReason[offset] = '8'; break; case 9: HaltReason[offset] = '9'; break; case 10: HaltReason[offset] = 'A'; break; case 11: HaltReason[offset] = 'B'; break; case 12: HaltReason[offset] = 'C'; break; case 13: HaltReason[offset] = 'D'; break; case 14: HaltReason[offset] = 'E'; break; case 15: HaltReason[offset] = 'F'; break; } y >>= 4; offset--; } #endregion BasicConsole.WriteLine(HaltReason); BasicConsole.SetTextColour(BasicConsole.default_colour); Throw(new FOS_System.Exceptions.PageFaultException(errorCode, address)); } }
/// <summary> /// Throws a double fault exception. /// </summary> /// <remarks> /// Used by CPU interrupts to handle the creation of the exception object and calling Throw. /// </remarks> public static void Throw_DoubleFaultException(uint address, uint errorCode) { HaltReason = "Double fault exception. Address: 0x Error code: 0x "; uint y = address; int offset = 42; #region Address while (offset > 34) { uint rem = y & 0xFu; switch (rem) { case 0: HaltReason[offset] = '0'; break; case 1: HaltReason[offset] = '1'; break; case 2: HaltReason[offset] = '2'; break; case 3: HaltReason[offset] = '3'; break; case 4: HaltReason[offset] = '4'; break; case 5: HaltReason[offset] = '5'; break; case 6: HaltReason[offset] = '6'; break; case 7: HaltReason[offset] = '7'; break; case 8: HaltReason[offset] = '8'; break; case 9: HaltReason[offset] = '9'; break; case 10: HaltReason[offset] = 'A'; break; case 11: HaltReason[offset] = 'B'; break; case 12: HaltReason[offset] = 'C'; break; case 13: HaltReason[offset] = 'D'; break; case 14: HaltReason[offset] = 'E'; break; case 15: HaltReason[offset] = 'F'; break; } y >>= 4; offset--; } #endregion y = errorCode; offset = 65; #region Error Code while (offset > 57) { uint rem = y & 0xFu; switch (rem) { case 0: HaltReason[offset] = '0'; break; case 1: HaltReason[offset] = '1'; break; case 2: HaltReason[offset] = '2'; break; case 3: HaltReason[offset] = '3'; break; case 4: HaltReason[offset] = '4'; break; case 5: HaltReason[offset] = '5'; break; case 6: HaltReason[offset] = '6'; break; case 7: HaltReason[offset] = '7'; break; case 8: HaltReason[offset] = '8'; break; case 9: HaltReason[offset] = '9'; break; case 10: HaltReason[offset] = 'A'; break; case 11: HaltReason[offset] = 'B'; break; case 12: HaltReason[offset] = 'C'; break; case 13: HaltReason[offset] = 'D'; break; case 14: HaltReason[offset] = 'E'; break; case 15: HaltReason[offset] = 'F'; break; } y >>= 4; offset--; } #endregion BasicConsole.SetTextColour(BasicConsole.error_colour); BasicConsole.WriteLine(HaltReason); BasicConsole.SetTextColour(BasicConsole.default_colour); Throw(new FOS_System.Exceptions.DoubleFaultException(errorCode)); }