public static void main() { const uint MultibootMagic = 0x1BADB002; const uint MultibootFlags = 0x10007; const uint InitalStackSize = 0x50000; /* Multiboot Config */ AssemblyHelper.AssemblerCode.Add(new Literal("MultibootSignature dd {0}", MultibootMagic)); AssemblyHelper.AssemblerCode.Add(new Literal("MultibootFlags dd {0}", 65543)); AssemblyHelper.AssemblerCode.Add(new Literal("MultibootChecksum dd {0}", -(MultibootMagic + MultibootFlags))); AssemblyHelper.AssemblerCode.Add(new Literal("MultibootHeaderAddr dd {0}", 0)); AssemblyHelper.AssemblerCode.Add(new Literal("MultibootLoadAddr dd {0}", 0)); AssemblyHelper.AssemblerCode.Add(new Literal("MultibootLoadEndAddr dd {0}", 0)); AssemblyHelper.AssemblerCode.Add(new Literal("MultibootBSSEndAddr dd {0}", 0)); AssemblyHelper.AssemblerCode.Add(new Literal("MultibootEntryAddr dd {0}", 0)); AssemblyHelper.InsertData(new AsmData("InitialStack", InitalStackSize)); AssemblyHelper.AssemblerCode.Add(new Label("_Kernel_Main")); /* Here is Entrypoint Method */ AssemblyHelper.AssemblerCode.Add(new Cli()); //Clear interrupts first !! //Setup Stack pointer, We do rest things later (i.e. Another method) because they are managed :) AssemblyHelper.AssemblerCode.Add(new Mov { DestinationReg = Registers.ESP, SourceRef = "InitialStack" }); AssemblyHelper.AssemblerCode.Add(new Add { DestinationReg = Registers.ESP, SourceRef = InitalStackSize.ToString() }); AssemblyHelper.AssemblerCode.Add(new Push { DestinationReg = Registers.EAX }); AssemblyHelper.AssemblerCode.Add(new Push { DestinationReg = Registers.EBX }); //Push Multiboot Header Info Address AssemblyHelper.AssemblerCode.Add(new Call("Kernel_Start")); }
public static void main() { const uint MultibootMagic = 0x1BADB002; const uint MultibootFlags = 0x10007; const uint InitalStackSize = 0x50000; const uint InitalHeapSize = 0x100000; /* Multiboot Config */ new Literal("MultibootSignature dd {0}", MultibootMagic); new Literal("MultibootFlags dd {0}", MultibootFlags); new Literal("MultibootChecksum dd {0}", -(MultibootMagic + MultibootFlags)); new Literal("MultibootHeaderAddr dd {0}", 0); new Literal("MultibootLoadAddr dd {0}", 0); new Literal("MultibootLoadEndAddr dd {0}", 0); new Literal("MultibootBSSEndAddr dd {0}", 0); new Literal("MultibootEntryAddr dd {0}", 0); new Literal("MultibootVesaMode dd {0}", 0); new Literal("MultibootVesaWidth dd {0}", 1024); new Literal("MultibootVesaHeight dd {0}", 768); new Literal("MultibootVesaDepth dd {0}", 32); Helper.InsertData("InitialStack", InitalStackSize); Helper.InsertData("InitialHeap", InitalHeapSize); new Label("_Kernel_Main"); #region KernelPageDirectory Helper.InsertData(new AsmData("align 0x1000")); Helper.InsertData(new AsmData("KernelPageDirectory:")); Helper.InsertData(new AsmData("dd (KernelPageTable - 0xC0000000 + 0x3)")); Helper.InsertData(new AsmData("times (0x300 - 1) dd 0")); Helper.InsertData(new AsmData("dd (KernelPageTable - 0xC0000000 + 0x3)")); Helper.InsertData(new AsmData("times (1024 - 0x300 - 1) dd 0")); var xPageTable = new uint[1024]; for (int i = 0; i < 1024; i++) { xPageTable[i] = (uint)((i * 0x1000) | 0x3); } Helper.InsertData(new AsmData("KernelPageTable", xPageTable)); #endregion /* Load Page Directory Base Register. */ new Mov { DestinationReg = Register.ECX, SourceRef = "(KernelPageDirectory - 0xC0000000)" }; new Mov { DestinationReg = Register.CR3, SourceReg = Register.ECX }; /* Set PG bit in CR0 to enable paging. */ new Mov { DestinationReg = Register.ECX, SourceReg = Register.CR0 }; new Or { DestinationReg = Register.ECX, SourceRef = "0x80000000" }; new Mov { DestinationReg = Register.CR0, SourceReg = Register.ECX }; /* Prepare for our quantum jump to Higher address */ new Lea { DestinationReg = Register.ECX, SourceRef = "Higher_Half_Kernel", SourceIndirect = true }; new Jmp { DestinationRef = "ECX" }; new Label("Higher_Half_Kernel"); new Mov { DestinationRef = "KernelPageDirectory", DestinationIndirect = true, SourceRef = "0x0" }; new Literal("invlpg [0]"); /* Setup Kernel stack */ new Mov { DestinationReg = Register.ESP, SourceRef = "InitialStack" }; new Add { DestinationReg = Register.ESP, SourceRef = InitalStackSize.ToString() }; /* Push relevent data to the stack */ new Push { DestinationReg = Register.EAX }; //Push Magic Number new Push { DestinationReg = Register.EBX }; //Push Multiboot Address new Push { DestinationRef = "KernelPageDirectory" }; new Push { DestinationRef = "InitialHeap" }; /* Enable Floating Point Unit */ new Mov { DestinationReg = Register.EAX, SourceReg = Register.CR0 }; new And { DestinationReg = Register.AX, SourceRef = "0xFFFD", Size = 16 }; new Or { DestinationReg = Register.AX, SourceRef = "0x10", Size = 16 }; new Mov { DestinationReg = Register.CR0, SourceReg = Register.EAX }; new Literal("fninit"); /* Enable SSE */ new Mov { DestinationReg = Register.EAX, SourceReg = Register.CR0 }; new And { DestinationReg = Register.AX, SourceRef = "0xFFFB", Size = 16 }; new Or { DestinationReg = Register.AX, SourceRef = "0x2", Size = 16 }; new Mov { DestinationReg = Register.CR0, SourceReg = Register.EAX }; new Mov { DestinationReg = Register.EAX, SourceReg = Register.CR4 }; new Or { DestinationReg = Register.AX, SourceRef = "0x600", Size = 16 }; new Mov { DestinationReg = Register.CR4, SourceReg = Register.EAX }; /* Call Kernel Start */ new Cli(); new Call { DestinationRef = "Kernel_Start", IsLabel = true }; }