Example #1
0
 public static void Break()
 {
     KernelMessage.Write("<BREAK>");
     while (true)
     {
         Native.Nop();
     }
 }
Example #2
0
        public static void Setup()
        {
            KernelMessage.WriteLine("Setup IDT");

            IDTAddr = PageFrameManager.AllocatePage(PageFrameRequestFlags.Default)->PhysicalAddress;
            KernelMessage.WriteLine("Address of IDT: {0:X8}", IDTAddr);

            // Setup IDT table
            Mosa.Runtime.Internal.MemoryClear(new IntPtr((uint)IDTAddr), 6);
            Intrinsic.Store16(new IntPtr((uint)IDTAddr), (Offset.TotalSize * 256) - 1);
            Intrinsic.Store32(new IntPtr((uint)IDTAddr), 2, IDTAddr + 6);

            KernelMessage.Write("Set IDT table entries...");
            SetTableEntries();
            KernelMessage.WriteLine("done");

            handlers = new InterruptInfo[256];
            for (var i = 0; i <= 255; i++)
            {
                var info = new InterruptInfo
                {
                    Interrupt      = i,
                    CountStatistcs = true,
                    Trace          = true,
                    Handler        = UndefinedHandler
                };
                if (i == (int)KnownInterrupt.ClockTimer)
                {
                    info.Trace          = false;
                    info.CountStatistcs = false;
                }
                handlers[i] = info;
            }

            SetInterruptHandler(KnownInterrupt.DivideError, InterruptsHandlers.DivideError);
            SetInterruptHandler(KnownInterrupt.ArithmeticOverflowException, InterruptsHandlers.ArithmeticOverflowException);
            SetInterruptHandler(KnownInterrupt.BoundCheckError, InterruptsHandlers.BoundCheckError);
            SetInterruptHandler(KnownInterrupt.InvalidOpcode, InterruptsHandlers.InvalidOpcode);
            SetInterruptHandler(KnownInterrupt.CoProcessorNotAvailable, InterruptsHandlers.CoProcessorNotAvailable);
            SetInterruptHandler(KnownInterrupt.DoubleFault, InterruptsHandlers.DoubleFault);
            SetInterruptHandler(KnownInterrupt.CoProcessorSegmentOverrun, InterruptsHandlers.CoProcessorSegmentOverrun);
            SetInterruptHandler(KnownInterrupt.InvalidTSS, InterruptsHandlers.InvalidTSS);
            SetInterruptHandler(KnownInterrupt.SegmentNotPresent, InterruptsHandlers.SegmentNotPresent);
            SetInterruptHandler(KnownInterrupt.StackException, InterruptsHandlers.StackException);
            SetInterruptHandler(KnownInterrupt.GeneralProtectionException, InterruptsHandlers.GeneralProtectionException);
            SetInterruptHandler(KnownInterrupt.PageFault, InterruptsHandlers.PageFault);
            SetInterruptHandler(KnownInterrupt.CoProcessorError, InterruptsHandlers.CoProcessorError);
            SetInterruptHandler(KnownInterrupt.SIMDFloatinPointException, InterruptsHandlers.SIMDFloatinPointException);
            SetInterruptHandler(KnownInterrupt.ClockTimer, InterruptsHandlers.ClockTimer);

            KernelMessage.Write("Enabling interrupts...");
            var idtAddr = (uint)IDTAddr;

            Native.Lidt(idtAddr);
            Native.Sti();
            KernelMessage.WriteLine("done");
        }
Example #3
0
        /// <summary>
        /// Sets up the PageTable
        /// </summary>
        public static void Setup(Addr addrPageDirectory, Addr addrPageTable)
        {
            KernelMessage.WriteLine("Setup PageTable");

            AddrPageDirectory = addrPageDirectory;
            AddrPageTable     = addrPageTable;

            // Setup Page Directory
            PageDirectoryEntry *pde = (PageDirectoryEntry *)AddrPageDirectory;

            for (int index = 0; index < 1024; index++)
            {
                pde[index]                = new PageDirectoryEntry();
                pde[index].Present        = true;
                pde[index].Writable       = true;
                pde[index].User           = true;
                pde[index].PageTableEntry = (PageTableEntry *)(uint)(AddrPageTable + (index * 4096));
            }

            // Map the first 128MB of memory (32786 4K pages) (why 128MB?)
            for (int index = 0; index < 1024 * 32; index++)
            {
                PageTableEntry *pte = (PageTableEntry *)AddrPageTable;
                pte[index]                 = new PageTableEntry();
                pte[index].Present         = true;
                pte[index].Writable        = true;
                pte[index].User            = true;
                pte[index].PhysicalAddress = (uint)(index * 4096);
            }

            // Unmap the first page for null pointer exceptions
            MapVirtualAddressToPhysical(0x0, 0x0, false);

            // Set CR3 register on processor - sets page directory
            KernelMessage.WriteLine("Set CR3 to {0:X8}", PageTable.AddrPageDirectory);
            Native.SetCR3(AddrPageDirectory);

            KernelMessage.Write("Enable Paging... ");

            // Set CR0.WP
            Native.SetCR0(Native.GetCR0() | 0x10000);

            // Set CR0 register on processor - turns on virtual memory
            Native.SetCR0(Native.GetCR0() | 0x80000000);

            KernelMessage.WriteLine("Done");
        }
Example #4
0
        public static void DumpToConsole(uint addr, uint length)
        {
            var sb = new StringBuffer();

            sb.Append("{0:X}+{1:D} ", addr, length);
            KernelMessage.Write(sb);
            sb.Clear();

            for (uint a = addr; a < addr + length; a++)
            {
                sb.Clear();

                if (a != addr)
                {
                    sb.Append(" ");
                }
                var m = Native.Get8(a);
                sb.Append(m, 16, 2);
                KernelMessage.Write(sb);
            }
        }
Example #5
0
        /// <summary>
        /// Sets up the GDT table and entries
        /// </summary>
        public static void Setup(Addr addr)
        {
            KernelMessage.Write("Setup GDT...");

            gdtTableAddress = addr;

            table = (DescriptorTable *)gdtTableAddress;
            table->Clear();
            table->AdressOfEntries = gdtTableAddress + DescriptorTable.StructSize;

            //Null segment
            var nullEntry = DescriptorTableEntry.CreateNullDescriptor();

            table->AddEntry(nullEntry);

            //code segment
            var codeEntry = DescriptorTableEntry.CreateCode(0, 0xFFFFFFFF);

            codeEntry.CodeSegment_Readable = true;
            codeEntry.PriviligeRing        = 0;
            codeEntry.Present     = true;
            codeEntry.AddressMode = DescriptorTableEntry.EAddressMode.Bits32;
            codeEntry.Granularity = true;
            table->AddEntry(codeEntry);

            //data segment
            var dataEntry = DescriptorTableEntry.CreateData(0, 0xFFFFFFFF);

            dataEntry.DataSegment_Writable = true;
            dataEntry.PriviligeRing        = 0;
            dataEntry.Present     = true;
            dataEntry.AddressMode = DescriptorTableEntry.EAddressMode.Bits32;
            dataEntry.Granularity = true;
            table->AddEntry(dataEntry);

            Flush();

            KernelMessage.WriteLine("Done");
        }
Example #6
0
        /// <summary>
        /// Allocate a physical page from the free list
        /// </summary>
        /// <returns>The page</returns>
        Page *Allocate(uint num)
        {
            KernelMessage.Write("Request {0} pages...", num);

            var cnt = 0;

            if (lastAllocatedPage == null)
            {
                lastAllocatedPage = PageArray;
            }

            Page *p = lastAllocatedPage->Next;

            while (true)
            {
                if (p == null)
                {
                    p = PageArray;
                }

                if (p->Status == PageStatus.Free)
                {
                    var head = p;

                    // Found free Page. Check now free range.
                    for (var i = 0; i < num; i++)
                    {
                        if (p == null)
                        {
                            break;                        // Reached end. SorRange is incomplete
                        }
                        if (p->Status != PageStatus.Free) // Used -> so we can abort the searach
                        {
                            break;
                        }

                        if (i == num - 1)
                        { // all loops successful. So we found our range.
                            head->Tail      = p;
                            head->PagesUsed = num;
                            p = head;
                            for (var n = 0; n < num; n++)
                            {
                                p->Status = PageStatus.Used;
                                p->Head   = head;
                                p->Tail   = head->Tail;
                                p         = p->Next;
                                PagesUsed++;
                            }
                            lastAllocatedPage = p;

                            KernelMessage.WriteLine("Allocated from {0:X8} to {1:X8}", (uint)head->PhysicalAddress, (uint)head->Tail->PhysicalAddress);

                            return(head);
                        }

                        p = p->Next;
                    }
                }

                if (p->Tail != null)
                {
                    p = p->Tail;
                }

                p = p->Next;
                if (++cnt > PageCount)
                {
                    break;
                }
            }

            Panic.Error("PageFrameAllocator: No free Page found");
            return(null);
        }
Example #7
0
 public static void DumpToConsoleLine(uint addr, uint length)
 {
     DumpToConsole(addr, length);
     KernelMessage.Write('\n');
 }