예제 #1
0
        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);
        }
예제 #3
0
        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);
        }
예제 #4
0
        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();
        }