public static void Break() { KernelMessage.Write("<BREAK>"); while (true) { Native.Nop(); } }
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"); }
/// <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"); }
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); } }
/// <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"); }
/// <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); }
public static void DumpToConsoleLine(uint addr, uint length) { DumpToConsole(addr, length); KernelMessage.Write('\n'); }