Esempio n. 1
0
        /// <summary>
        /// Initializes the GDT
        /// </summary>
        public static unsafe void Init()
        {
            // Allocate data
            m_entries = new GDT_Entry[6];
            m_ptr     = new GDT_Pointer();

            // Set GDT table pointer
            m_ptr.Limit = (ushort)((6 * sizeof(GDT_Entry)) - 1);
            fixed(GDT_Entry *ptr = m_entries)
            {
                m_ptr.BaseAddress = (uint)ptr;
            }

            // NULL segment
            setEntry(0, 0, 0, 0, 0);

            // Kernel code segment
            setEntry(1, 0, 0xFFFFFFFF, (int)GDT_Data.ER | (int)GDTFlags.DescriptorCodeOrData | Privilege(0) | (int)GDTFlags.Present, (int)GDTFlags.Size32 | (int)GDTFlags.Granularity);

            // Kernel data segment
            setEntry(2, 0, 0xFFFFFFFF, (int)GDT_Data.RW | (int)GDTFlags.DescriptorCodeOrData | Privilege(0) | (int)GDTFlags.Present, (int)GDTFlags.Size32 | (int)GDTFlags.Granularity);

            // User code segment
            setEntry(3, 0, 0xFFFFFFFF, (int)GDT_Data.ER | (int)GDTFlags.DescriptorCodeOrData | Privilege(3) | (int)GDTFlags.Present, (int)GDTFlags.Size32 | (int)GDTFlags.Granularity);

            // User data segment
            setEntry(4, 0, 0xFFFFFFFF, (int)GDT_Data.RW | (int)GDTFlags.DescriptorCodeOrData | Privilege(3) | (int)GDTFlags.Present, (int)GDTFlags.Size32 | (int)GDTFlags.Granularity);

            // TSS
            TSS_Entry = (TSS *)Heap.Alloc(sizeof(TSS));
            setTSS(5, TSS_Entry);

            // Flush GDT
            fixed(GDT_Pointer *ptr = &m_ptr)
            {
                flushGDT(ptr);
            }

            // Flush TSS
            flushTSS();
        }
Esempio n. 2
0
        /// <summary>
        /// Writes a TSS entry into the GDT
        /// </summary>
        /// <param name="num">The index of the corresponding GDT entry</param>
        /// <param name="tss">The TSS</param>
        private static unsafe void setTSS(int num, TSS *tss)
        {
            // Base and limit
            uint baseAddr = (uint)tss;
            uint limit    = (uint)(baseAddr + sizeof(TSS));

            // Set TSS
            // Kernel Data Selector = 0x10, Kernel Code Selector = 0x08
            Memory.Memclear(tss, sizeof(TSS));
            tss->SS0   = 0x10;
            tss->IOMap = (ushort)sizeof(TSS);
            tss->CS    = 0x08;
            tss->DS    = 0x10;
            tss->ES    = 0x10;
            tss->FS    = 0x10;
            tss->GS    = 0x10;
            tss->SS    = 0x10;

            // Add TSS descriptor to GDT
            setEntry(num, baseAddr, limit, (int)GDT_Data.EA | Privilege(3) | (int)GDTFlags.Present, 0);
        }
Esempio n. 3
0
        public static void Init()
        {
            //ExceptionMethods.ThePageFaultHandler = HandlePageFault;

            ActiveQueue.Name   = "Active Queue";
            InactiveQueue.Name = "Inactive Queue";

            //Load first process and first thread
#if SCHEDULER_TRACE
            BasicConsole.WriteLine(" > Setting current process...");
#endif
            ProcessManager.CurrentProcess = (Process)ProcessManager.Processes[0];
#if SCHEDULER_TRACE
            BasicConsole.WriteLine(" > Setting current thread...");
#endif
            ProcessManager.CurrentThread = (Thread)ProcessManager.CurrentProcess.Threads[0];
#if SCHEDULER_TRACE
            BasicConsole.WriteLine(" > Setting current thread state...");
#endif
            ProcessManager.CurrentThread_State = ProcessManager.CurrentThread.State;

            //Init TSS
#if SCHEDULER_TRACE
            BasicConsole.WriteLine(" > Getting TSS pointer...");
#endif
            TSS *tss = GetTSSPointer();
#if SCHEDULER_TRACE
            BasicConsole.WriteLine(" > Setting esp0...");
#endif
            tss->esp0 = (uint)ProcessManager.CurrentThread_State->KernelStackTop;
#if SCHEDULER_TRACE
            BasicConsole.WriteLine(" > Setting ss0...");
#endif
            //Note: KM CS is loaded from IDT entry on ring 3 -> 0 switch
            tss->ss0 = 0x10; //Kernel mode stack segment = KM Data segment (same for all processes)

#if SCHEDULER_TRACE
            BasicConsole.WriteLine(" > Setting cr3...");
#endif
            tss->cr3 = VirtMem.x86.GetCR3();

            //Load Task Register
#if SCHEDULER_TRACE
            BasicConsole.WriteLine(" > Loading TR...");
#endif
            LoadTR();

            //Enable timer
#if SCHEDULER_TRACE
            BasicConsole.WriteLine(" > Adding timer handler...");
#endif
            /*Multiply by 1000000 to get from ms to ns*/
            Hardware.Devices.Timer.Default.RegisterHandler(OnTimerInterrupt, /* MSFreq * 1000000 */ 5000000, true, null);

#if SCHEDULER_TRACE
            BasicConsole.WriteLine(" > Enabling process switching...");
#endif
            Interrupts.Interrupts.EnableProcessSwitching = true;

//#if SCHEDULER_TRACE
            BasicConsole.WriteLine(" > Enabling scheduler...");
//#endif
            UpdateCountdown = UpdatePeriod;

            Initialised = true;
            Enable();
        }