hschumann2/TempleOS-Source-Code
0838
1 2asm {/* See ::/Doc/Boot.DD.3TempleOS starts in real, calls some BIOS4routines, switches to 32 bit, and 64 bit mode5and continues in HolyC at KMain().6 7The boot loader jumps here in real-mode (16-bit).8It actually jumps to the CBinFile header which is9placed just before this by the compiler.10The header begins with a short jmp to11the start of this file's code which begins12with the following small jump past some data.13 14This file is first in the Kernel image15because it is #included first. Kernel.PRJ16*/17USE1618SYS_KERNEL:: //This must match CKernel.19 JMP I16 CORE0_16BIT_INIT20 21//************************************22// ASM Global vars required for 16-bit start-up23 ALIGN 4,OC_NOP24SYS_BOOT_SRC:: DU32 BOOT_SRC_NULL;25SYS_BOOT_BLK:: DU32 0;26SYS_BOOT_PATCH_TABLE_BASE:: DU32 0;27SYS_RUN_LEVEL:: DU32 0;28#exe {StreamPrint("SYS_COMPILE_TIME:: DU64 0x%X;",Now);} //See BootDVDProbe29#assert SYS_COMPILE_TIME+sizeof(CDate)+sizeof(CBinFile)<DVD_BLK_SIZE30 31MEM_BOOT_BASE:: DU32 0; //Offset from start used by reboot32MEM_E801:: DU16 0,0;33MEM_E820:: DU8 MEM_E820_ENTRIES_NUM*sizeof(CMemE820) DUP (0);34MEM_PHYSICAL_SPACE:: DU64 0;35SYS_GDT_PTR:: DU16 sizeof(CGDT)-1;36 DU64 0;37SYS_PCI_BUSES:: DU16 0;38 39 ALIGN 16,OC_NOP40SYS_GDT:: //See CGDT41GDT_NULL: DU64 0,0;42GDT_BOOT_DS: DU64 0x00CF92000000FFFF,0; //Gets patched.43GDT_BOOT_CS: DU64 0x00CF9A000000FFFF,0; //Gets patched.44GDT_CS32: DU64 0x00CF9A000000FFFF,0;45GDT_CS64: DU64 0x00209A0000000000,0; //The Charter says just ring0.46GDT_CS64_RING3: DU64 0x0020FA0000000000,0; //Ring3, so you can play with.47GDT_DS: DU64 0x00CF92000000FFFF,0;48GDT_DS_RING3: DU64 0x00CFF2000000FFFF,0;49GDT_TR: DU8 MP_PROCESSORS_NUM*16 DUP(0);50GDT_TR_RING3: DU8 MP_PROCESSORS_NUM*16 DUP(0);51#assert $-SYS_GDT==sizeof(CGDT)52 53#assert $-SYS_KERNEL==sizeof(CKernel)-sizeof(CBinFile)54 55//************************************56CORE0_16BIT_INIT::57//EAX is SYS_BOOT_SRC. (Val passed from boot blk, BootHD, BootDVD, & BootRAM.)58 MOV ECX,EAX59 MOV AX,(BOOT_RAM_LIMIT-BOOT_STK_SIZE)/1660 MOV SS,AX61 MOV SP,BOOT_STK_SIZE62 PUSH ECX //Will be SYS_BOOT_SRC. See BootHD, BootDVD & BootRAM.63 PUSH EBX64 65 CALL U16 GET_RIP66GET_RIP: POP BX67 SUB BX,GET_RIP68 SHR BX,469 MOV AX,CS70 ADD AX,BX71 PUSH AX72 PUSH U16 @@0573 RETF74 75@@05: STI76 MOV AX,CS77 MOV DS,AX78 79 MOV U32 [SYS_RUN_LEVEL],RLF_16BIT80 81 MOV AX,0x4F0282 MOV BX,0x12 //640x480 16 color83#exe {84 if (!kernel_cfg->opts[CFG_TEXT_MODE])85 StreamPrint("INT 0x10"); //Enable VGA86};87 CMP AX,0x004F88 JNE @@10 //Jmp if fail89 BTS U32 [SYS_RUN_LEVEL],RLf_VGA90@@10:91 92//Get mem maps.93 MOV AX,0xE80194 INT 0x1595 MOV U16 [MEM_E801],CX96 MOV U16 [MEM_E801+2],DX97 98 MOV CX,MEM_E820_ENTRIES_NUM-1 //Leave one to terminate99 XOR EBX,EBX100 MOV AX,DS101 MOV ES,AX102 MOV DI,MEM_E820103@@15: PUSH CX104 MOV EAX,0xE820105 MOV ECX,sizeof(CMemE820)106 MOV EDX,'PAMS'107 INT 0x15108 JC @@20109 CMP EAX,'PAMS'110 JNE @@20111 TEST EBX,EBX112 JZ @@20113 ADD DI,sizeof(CMemE820)114 POP CX115 LOOP @@15116 SUB SP,2117@@20: ADD SP,2118 119//Find how much space to map, start with E801 limit.120 XOR EAX,EAX121 MOV AX,[MEM_E801+2]122 SHL EAX,16123 ADD EAX,SYS_16MEG_AREA_LIMIT124 XOR EDX,EDX125 126//Find max of E820 to set mapped space.127 MOV SI,MEM_E820128@@25: MOV CL,CMemE820.type[SI]129 TEST CL,CL130 JZ @@35131 MOV EBX,CMemE820.base[SI]132 MOV ECX,CMemE820.base+4[SI]133 ADD EBX,CMemE820.len[SI]134 ADC ECX,CMemE820.len+4[SI]135 SUB EBX,EAX136 SBB ECX,EDX137 JC @@30138 MOV EAX,CMemE820.base[SI]139 MOV EDX,CMemE820.base+4[SI]140 ADD EAX,CMemE820.len[SI]141 ADC EDX,CMemE820.len+4[SI]142@@30: ADD SI,sizeof(CMemE820)143 JMP @@25144 145@@35: MOV [MEM_PHYSICAL_SPACE],EAX146 MOV [MEM_PHYSICAL_SPACE+4],EDX147 148//Get PCI Bus Info149 MOV U16 [SYS_PCI_BUSES],256150 XOR DX,DX151 MOV AX,0xB101152 INT 0x1A153 CMP DX,'PC'154 JNE @@40155 MOV CH,0156 INC CX157 MOV U16 [SYS_PCI_BUSES],CX158@@40:159 CLI160//Enable A20161 IN AL,0x92162 OR AL,2163 OUT 0x92,AL164 165 POP U32 [SYS_BOOT_BLK]166 POP U32 [SYS_BOOT_SRC] //See BootHD, BootDVD, & BootRAM.167 168 CLD169 XOR EAX,EAX170 MOV AX,CS171 MOV DS,AX172 MOV ES,AX173 SHL EAX,4174 175 MOV U32 [MEM_BOOT_BASE],EAX176 177 MOV DX,CS178 SUB DX,sizeof(CBinFile)/16179#assert !(sizeof(CBinFile)&15)180 MOV GS,DX181 182 MOV EDX,EAX183 ADD EDX,U32 GS:[CBinFile.patch_table_offset]184 SUB EDX,sizeof(CBinFile)185 MOV U32 [SYS_BOOT_PATCH_TABLE_BASE],EDX186 187 ADD U32 [GDT_BOOT_DS+2],EAX188 ADD U32 [GDT_BOOT_CS+2],EAX189 ADD EAX,I32 SYS_GDT190 MOV U32 [SYS_GDT_PTR+CSysLimitBase.base],EAX191 LGDT U32 [SYS_GDT_PTR]192 193 MOV EAX,SYS_START_CR0194 MOV_CR0_EAX195 196/* The assembler doesn't support far jumps so197we hand code it. 16-bit code is not important198enough to fully implement in the assembler.199 200To complete the switch to 32-bit mode, we have to load201the code segment with a far jump.202*/203 DU8 0x66,0xEA; //JMP CGDT.boot_cs:CORE0_32BIT_INIT204 DU32 CORE0_32BIT_INIT;205 DU16 CGDT.boot_cs;206#assert $+16<=0xFFFF207}208 