// Bootstrap is a class designed only to get the essentials done. // ie the stuff needed to "pre boot". Do only the very minimal here. // IDT, PIC, and Float // Note: This is changing a bit GDT (already) and IDT are moving to a real preboot area. public static void Init() { // Drag this stuff in to the compiler manually until we add the always include attrib INTs.Dummy(); PIC = new PIC(); CPU.UpdateIDT(true); /* TODO check using CPUID that SSE2 is supported */ CPU.InitSSE(); /* * We liked to use SSE for all floating point operation and end to mix SSE / x87 in Cosmos code * but sadly in x86 this resulte impossible as Intel not implemented some needed instruction (for example conversion * for long to double) so - in some rare cases - x87 continue to be used. I hope passing to the x32 or x64 IA will solve * definively this problem. */ CPU.InitFloat(); header = (Multiboot.Header *)Multiboot.GetMBIAddress(); modeinfo = (Core.VBE.ModeInfo *)header->vbeModeInfo; controllerinfo = (Core.VBE.ControllerInfo *)header->vbeControlInfo; // Managed_Memory_System.ManagedMemory.Initialize(); // Managed_Memory_System.ManagedMemory.SetUpMemoryArea(); }
/// <summary> /// Processes the multiboot header /// </summary> /// <param name="header">The header</param> /// <param name="magic">The magic multiboot number</param> private static unsafe void processMultiboot(Multiboot.Header *header, uint magic) { // We require to be booted by a multiboot compliant bootloader if (magic != Multiboot.Magic) { Panic.DoPanic("Not booted by a multiboot bootloader"); } // Bring the header to a safe location fixed(Multiboot.Header *destination = &m_mbootHeader) { Memory.Memcpy(destination, header, sizeof(Multiboot.Header)); } // Memory size m_memSize = m_mbootHeader.MemHi; // Check if any modules are loaded if ((m_mbootHeader.Flags & Multiboot.FlagMods) > 0) { uint modsCount = m_mbootHeader.ModsCount; Console.Write("[Multiboot] Modules: "); Console.WriteNum((int)modsCount); Console.Write('\n'); Multiboot.Module **mods = (Multiboot.Module * *)m_mbootHeader.ModsAddr; for (int i = 0; i < modsCount; i++) { Multiboot.Module *module = mods[i]; // Move the heap end if ((uint)module->End > (uint)heapStart) { heapStart = module->End; } } } else { Console.WriteLine("[Multiboot] No modules"); } }
/// <summary> /// Kernel entrypoint /// </summary> /// <param name="header">The multiboot header</param> /// <param name="magic">The magic</param> /// <param name="end">The end address of the kernel</param> public static unsafe void KernelMain(Multiboot.Header *header, uint magic, void *end) { heapStart = end; Console.Clear(); X86Arch.EarlyInit(); processMultiboot(header, magic); Heap.InitTempHeap(heapStart); X86Arch.Init(); Random.Init(); VFS.Init(); initPCIDevices(); Keyboard.Init(); Tasking.Init(); BootParams.Init(Util.CharPtrToString((char *)header->CMDLine)); initUSB(); initStorage(); mountBootPartition(); //initNetworking(); initSound(); runUserspace(); // Idle loop while (true) { CPU.HLT(); } }