static void MapKernelImage() { var phys = Address.KernelElfSection; var diff = Address.KernelBaseVirt - Address.KernelBasePhys; var endPhys = phys + OriginalKernelElf.TotalFileSize; var addr = phys; KernelMessage.WriteLine("Mapping Kernel Image from physical {0:X8} to virtual {1:X8}", phys, phys + diff); while (addr < endPhys) { PageTable.MapVirtualAddressToPhysical(addr + diff, addr); addr += 0x1000; } }
/// <summary> /// Returns raw, unmanaged Memory. /// Consumer: Kernel, Memory allocators /// Shoud be used for larger Chunks. /// </summary> internal unsafe static Addr RequestRawVirtalMemoryPages(uint pages) { Addr virt = _nextVirtAddr; var head = PageFrameManager.AllocatePages(PageFrameRequestFlags.Default, pages); if (head == null) { return(Addr.Zero); } var p = head; for (var i = 0; i < pages; i++) { PageTable.MapVirtualAddressToPhysical(_nextVirtAddr, p->PhysicalAddress); _nextVirtAddr += 4096; p = p->Next; } return(virt); }
public unsafe static void InitialKernelProtect_MakeWritable_BySize(uint virtAddr, uint size) { if (!UseKernelWriteProtection) { return; } //KernelMessage.WriteLine("Unprotect Memory: Start={0:X}, End={1:X}", virtAddr, virtAddr + size); var pages = KMath.DivCeil(size, 4096); for (var i = 0; i < pages; i++) { var entry = PageTable.GetTableEntry(virtAddr); entry->Writable = true; virtAddr += 4096; } Native.SetCR3(PageTable.AddrPageDirectory); }
public static void Main() { //Screen.BackgroundColor = ScreenColor.Green; //Screen.Color = ScreenColor.Red; //Screen.Clear(); //Screen.Goto(0, 0); //Screen.Write('A'); //Serial.SetupPort(Serial.COM1); //Serial.Write(Serial.COM1, "Hello"); BootMemory.Setup(); // Setup Kernel Log var kmsgHandler = new KernelMessageWriter(); KernelMessage.SetHandler(kmsgHandler); KernelMessage.WriteLine("<LOADER:CONSOLE:BEGIN>"); // Parse Boot Informations Multiboot.Setup(); // Parse Kernel ELF section SetupOriginalKernelElf(); // Print all section of Kernel ELF (for information only) DumpElfInfo(); // Copy Section to a final destination SetupKernelSection(); // Collection informations we need to pass to the kernel BootInfo_.Setup(); // Setup Global Descriptor Table var map = BootMemory.AllocateMemoryMap(0x1000, BootInfoMemoryType.GDT); BootInfo_.AddMap(map); GDT.Setup(map.Start); // Now we enable Paging. It's important that we do not cause a Page Fault Exception, // Because IDT is not setup yet, that could handle this kind of exception. map = BootMemory.AllocateMemoryMap(PageTable.InitalPageDirectorySize, BootInfoMemoryType.PageDirectory); BootInfo_.AddMap(map); var map2 = BootMemory.AllocateMemoryMap(PageTable.InitalPageTableSize, BootInfoMemoryType.PageTable); BootInfo_.AddMap(map2); PageTable.Setup(map.Start, map2.Start); // Because Kernel is compiled in virtual address space, we need to remap the pages MapKernelImage(); // Get Entry Point of Kernel uint kernelEntry = GetKernelStartAddr(); if (kernelEntry == 0) { KernelMessage.WriteLine("No kernel entry point found {0:X8}"); KernelMessage.WriteLine("Is the name of entry point correct?"); KernelMessage.WriteLine("Are symbols emitted?"); KernelMessage.WriteLine("System halt!"); while (true) { Native.Nop(); } } KernelMessage.WriteLine("Call Kernel Start at {0:X8}", kernelEntry); // Start Kernel. CallAddress(kernelEntry); // If we hit this code location, the Kernel Main method returned. // This would be a general fault. Normally, this code section will overwritten // by the kernel, so normally, it can never reach this code position. KernelMessage.WriteLine("Unexpected return from Kernel Start"); Debug.Break(); }