Пример #1
0
        private static void SetupMemoryMap()
        {
            var mbMapCount = Multiboot.MemoryMapCount;

            BootInfo->MemoryMapArray = (BootInfoMemory *)MallocBootInfoData((USize)(sizeof(MultiBootMemoryMap) * MemoryMapReserve));

            for (uint i = 0; i < mbMapCount; i++)
            {
                BootInfo->MemoryMapArray[i].Start = Multiboot.GetMemoryMapBase(i);
                BootInfo->MemoryMapArray[i].Size  = Multiboot.GetMemoryMapLength(i);
                var memType          = BootInfoMemoryType.Reserved;
                var type             = (BIOSMemoryMapType)Multiboot.GetMemoryMapType(i);
                var addressSpaceKind = AddressSpaceKind.Physical;
                var preMap           = false;

                switch (type)
                {
                case BIOSMemoryMapType.Usable:
                    memType = BootInfoMemoryType.SystemUsable;
                    break;

                case BIOSMemoryMapType.Reserved:
                    memType = BootInfoMemoryType.Reserved;
                    break;

                case BIOSMemoryMapType.ACPI_Relaimable:
                    memType = BootInfoMemoryType.ACPI_Relaimable;
                    break;

                case BIOSMemoryMapType.ACPI_NVS_Memory:
                    memType = BootInfoMemoryType.ACPI_NVS_Memory;
                    break;

                case BIOSMemoryMapType.BadMemory:
                    memType = BootInfoMemoryType.BadMemory;
                    break;

                default:
                    memType = BootInfoMemoryType.Unknown;
                    break;
                }
                BootInfo->MemoryMapArray[i].Type             = memType;
                BootInfo->MemoryMapArray[i].AddressSpaceKind = addressSpaceKind;
                BootInfo->MemoryMapArray[i].PreMap           = preMap;
            }

            // It's possible, that the BIOS-Area (@640K) is not correctly setup by Multiboot. So add it here manually to be sure
            var idx = mbMapCount + 0;

            BootInfo->MemoryMapArray[idx].Start            = 640 * 1024;
            BootInfo->MemoryMapArray[idx].Size             = (1024 - 640) * 1024;
            BootInfo->MemoryMapArray[idx].Type             = BootInfoMemoryType.CustomReserved;
            BootInfo->MemoryMapArray[idx].AddressSpaceKind = AddressSpaceKind.Both; //TODO: Physical
            BootInfo->MemoryMapArray[idx].PreMap           = true;

            idx++;
            BootInfo->MemoryMapArray[idx].Start            = Address.KernelElfSectionPhys;
            BootInfo->MemoryMapArray[idx].Size             = KMath.AlignValueCeil(LoaderStart.OriginalKernelElf.TotalFileSize, 0x1000);
            BootInfo->MemoryMapArray[idx].Type             = BootInfoMemoryType.KernelElf;
            BootInfo->MemoryMapArray[idx].AddressSpaceKind = AddressSpaceKind.Physical;
            BootInfo->MemoryMapArray[idx].PreMap           = true;

            idx++;
            BootInfo->MemoryMapArray[idx].Start            = Address.KernelBootInfo;
            BootInfo->MemoryMapArray[idx].Size             = 0x1000;
            BootInfo->MemoryMapArray[idx].Type             = BootInfoMemoryType.BootInfoHeader;
            BootInfo->MemoryMapArray[idx].AddressSpaceKind = AddressSpaceKind.Both;
            BootInfo->MemoryMapArray[idx].PreMap           = true;

            idx++;
            BootInfo->MemoryMapArray[idx].Start            = BootInfo->HeapStart;
            BootInfo->MemoryMapArray[idx].Size             = 0x1000; //TODO: Recalculate after Setup all Infos
            BootInfo->MemoryMapArray[idx].Type             = BootInfoMemoryType.BootInfoHeap;
            BootInfo->MemoryMapArray[idx].AddressSpaceKind = AddressSpaceKind.Both;
            BootInfo->MemoryMapArray[idx].PreMap           = true;

            idx++;
            uint stackSize = 0x100000; // 1MB

            BootInfo->MemoryMapArray[idx].Start            = Address.InitialStack - stackSize;
            BootInfo->MemoryMapArray[idx].Size             = stackSize;
            BootInfo->MemoryMapArray[idx].Type             = BootInfoMemoryType.InitialStack;
            BootInfo->MemoryMapArray[idx].AddressSpaceKind = AddressSpaceKind.Both;
            BootInfo->MemoryMapArray[idx].PreMap           = true;

            idx++;
            BootInfo->MemoryMapArray[idx].Start            = Address.GCInitialMemory;
            BootInfo->MemoryMapArray[idx].Size             = Address.GCInitialMemorySize;
            BootInfo->MemoryMapArray[idx].Type             = BootInfoMemoryType.InitialGCMemory;
            BootInfo->MemoryMapArray[idx].AddressSpaceKind = AddressSpaceKind.Both;
            BootInfo->MemoryMapArray[idx].PreMap           = true;

            idx++;
            BootInfo->MemoryMapArray[idx].Start            = LoaderStart.OriginalKernelElf.GetSectionHeader(".bss")->Addr;
            BootInfo->MemoryMapArray[idx].Size             = LoaderStart.OriginalKernelElf.GetSectionHeader(".bss")->Size;
            BootInfo->MemoryMapArray[idx].Type             = BootInfoMemoryType.KernelBssSegment;
            BootInfo->MemoryMapArray[idx].AddressSpaceKind = AddressSpaceKind.Virtual;
            BootInfo->MemoryMapArray[idx].PreMap           = false;

            idx++;
            BootInfo->MemoryMapArray[idx].Start            = LoaderStart.OriginalKernelElf.GetSectionHeader(".text")->Addr;
            BootInfo->MemoryMapArray[idx].Size             = LoaderStart.OriginalKernelElf.GetSectionHeader(".text")->Size;
            BootInfo->MemoryMapArray[idx].Type             = BootInfoMemoryType.KernelTextSegment;
            BootInfo->MemoryMapArray[idx].AddressSpaceKind = AddressSpaceKind.Virtual;
            BootInfo->MemoryMapArray[idx].PreMap           = false;

            idx++;
            BootInfo->MemoryMapArray[idx].Start            = LoaderStart.OriginalKernelElf.GetSectionHeader(".rodata")->Addr;
            BootInfo->MemoryMapArray[idx].Size             = LoaderStart.OriginalKernelElf.GetSectionHeader(".rodata")->Size;
            BootInfo->MemoryMapArray[idx].Type             = BootInfoMemoryType.KernelROdataSegment;
            BootInfo->MemoryMapArray[idx].AddressSpaceKind = AddressSpaceKind.Virtual;
            BootInfo->MemoryMapArray[idx].PreMap           = false;

            idx++;
            BootInfo->MemoryMapArray[idx].Start            = LoaderStart.OriginalKernelElf.GetSectionHeader(".data")->Addr;
            BootInfo->MemoryMapArray[idx].Size             = LoaderStart.OriginalKernelElf.GetSectionHeader(".data")->Size;
            BootInfo->MemoryMapArray[idx].Type             = BootInfoMemoryType.KernelDataSegment;
            BootInfo->MemoryMapArray[idx].AddressSpaceKind = AddressSpaceKind.Virtual;
            BootInfo->MemoryMapArray[idx].PreMap           = false;

            // Avoiding the use of the first megabyte of RAM
            idx++;
            BootInfo->MemoryMapArray[idx].Start            = 0x0;
            BootInfo->MemoryMapArray[idx].Size             = Address.ReserveMemory;
            BootInfo->MemoryMapArray[idx].Type             = BootInfoMemoryType.KernelReserved;
            BootInfo->MemoryMapArray[idx].AddressSpaceKind = AddressSpaceKind.Both;
            BootInfo->MemoryMapArray[idx].PreMap           = false;

            BootInfo->MemoryMapLength = idx + 1;
        }
Пример #2
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>");
            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();
        }