private static void MapKernelImage() { var phys = Address.KernelElfSectionPhys; 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.KernelTable.MapVirtualAddressToPhysical(addr + diff, addr); addr += 0x1000; } PageTable.KernelTable.Flush(); var map = new BootInfoMemory { Start = phys + diff, Size = OriginalKernelElf.TotalFileSize, Type = BootInfoMemoryType.KernelElfVirt, AddressSpaceKind = AddressSpaceKind.Virtual, }; BootInfo_.AddMap(map); }
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>"); Assert.Setup(AssertError); PerformanceCounter.Setup(); // 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, AddressSpaceKind.Both); 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. PageTable.ConfigureType(BootInfo_.BootInfo->PageTableType); map = BootMemory.AllocateMemoryMap(PageTable.KernelTable.InitalMemoryAllocationSize, BootInfoMemoryType.PageTable, AddressSpaceKind.Both); BootInfo_.AddMap(map); PageTable.KernelTable.Setup(map.Start); MapMemory(); PageTable.KernelTable.EnablePaging(); // 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(); }