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(); }
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 unsafe void HandleLeave(void *continuePtr) { if (State == null || State->CurrentHandlerPtr == null) { // If we get to here, it's an unhandled exception HaltReason = ""; if (State == null) { HaltReason = "Cannot leave on null handler! Address: 0x - Null state"; } else if (State->CurrentHandlerPtr == null) { HaltReason = "Cannot leave on null handler! Address: 0x - Null handler"; } else { HaltReason = "Cannot leave on null handler! Address: 0x - Unexpected reason"; } uint y = *((uint *)(BasePointer + 4)); int offset = 48; #region Address while (offset > 40) { 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); if (State != null) { if (State->depth > 0) { BasicConsole.WriteLine(" -- Positive depth"); } else if (State->depth == 0) { BasicConsole.WriteLine(" -- Zero depth"); } else if (State->depth < 0) { BasicConsole.WriteLine(" -- Negative depth"); } int pos = State->history_pos; do { BasicConsole.Write(State->history[pos]); BasicConsole.Write(" "); pos--; if (pos == -1) { pos = 31; } }while (pos != State->history_pos); } BasicConsole.DelayOutput(5); // Try to cause fault *((byte *)0x800000000) = 0; } // Leaving a critical section cleanly // We need to handle 2 cases: // Case 1 : Leaving "try" or "catch" of a try-catch // Case 2 : Leaving the "try" of a try-finally if ((uint)State->CurrentHandlerPtr->FilterAddress != 0x0u) { // Case 1 : Leaving "try" or "catch" of a try-catch //BasicConsole.WriteLine("Leave try or catch of try-catch"); if (State->CurrentHandlerPtr->Ex != null) { FOS_System.GC.DecrementRefCount((FOS_System.Object)Utilities.ObjectUtilities.GetObject(State->CurrentHandlerPtr->Ex)); State->CurrentHandlerPtr->Ex = null; } State->CurrentHandlerPtr->InHandler = 0; uint EBP = State->CurrentHandlerPtr->EBP; uint ESP = State->CurrentHandlerPtr->ESP; State->CurrentHandlerPtr = State->CurrentHandlerPtr->PrevHandlerPtr; State->depth--; State->history[State->history_pos++] = (uint)State->CurrentHandlerPtr->HandlerAddress; if (State->history_pos > 31) { State->history_pos = 0; } ArbitaryReturn(EBP, ESP + (uint)sizeof(ExceptionHandlerInfo), (byte *)continuePtr); } else { // Case 2 : Leaving the "try" of a try-finally State->CurrentHandlerPtr->InHandler = 1; byte *handlerAddress = State->CurrentHandlerPtr->HandlerAddress; //BasicConsole.WriteLine("Leave try of try-finally"); //BasicConsole.Write("Handler address: "); //BasicConsole.WriteLine((uint)handlerAddress); //BasicConsole.Write("Continue ptr: "); //BasicConsole.WriteLine((uint)continuePtr); State->CurrentHandlerPtr->HandlerAddress = (byte *)continuePtr; ArbitaryReturn(State->CurrentHandlerPtr->EBP, State->CurrentHandlerPtr->ESP, handlerAddress); } }