asm { /* See $LK-A,"::/TempleOS/Doc/Boot.TXT"$ for how booting works. This file calls some BIOS routines before switching to 32 bit, and then, 64 bit modes. It continues here: $LK,"Kernel","FF:::/TempleOS/Kernel/KEnd.CPP,U0 Kernel"$. The boot loader jumps here, in real-mode (16-bit). It actually jumps to the $LK,"CBinFile","MN:CBinFile"$ which is placed just before this $LK,"generated by the compiler","FF:::/TempleOS/Compiler/CmpMain.CPP,TEMPLEOS_XSUM"$. The header begins with a short jmp to the start of this file's code which begins with the following small jump past some data. This file is first in the Kernel image because it is #included first. $LK,"Kernel.PRJ","FF:::/TempleOS/Kernel/Kernel.PRJ,KStart:1"$ */ USE16 SYS_KERNEL_START1:: //This must match $LK,"CKernel","MN:CKernel"$. JMP U16 SYS_KERNEL_START2 // ************************************ // ASM Global vars required for 16-bit start-up ALIGN 4,OC_NOP SYS_BOOT_BASE:: DU32 0; //Fixed offset from start used by reboot SYS_BOOT_PATCH_TABLE_BASE:: DU32 0; #exe {StreamPrint("SYS_COMPILE_TIME:: DU64 0x%X;",GetDateTime);} //See $LK,"BootCdProbe","MN:BootCdProbe"$ #assert SYS_COMPILE_TIME+8+16bios_gr_mode);}; MOV U16 [SYS_BIOS_GR_MODE],BX MOV AX,0x4F02 #exe { if (!kernel_cfg->opts[CFG_TEXT_MODE]) StreamPrint("INT 0x10"); //Enable VGA }; CMP AX,0x004F JE @@10 MOV U16 [SYS_BIOS_GR_MODE],0 //failed @@10: /**** This doesn't help //Enable mouse MOV AX,0xC200 //Enable MOV BX,0x0100 INT 0x15 MOV AX,0xC201 //Rst INT 0x15 MOV AX,0xC200 //Enable MOV BX,0x0100 INT 0x15 MOV AX,0xC202 //Sample MOV BX,0x0500 //100 INT 0x15 MOV AX,0xC203 //Resolution MOV BX,0x0300 //8 per mm INT 0x15 MOV AX,0xC205 //pkt size MOV BX,0x0300 INT 0x15 MOV AX,0xC200 //Enable MOV BX,0x0100 INT 0x15 ****/ //Get mem maps MOV AX,0xE801 INT 0x15 MOV U16 [SYS_MEM_E801],CX MOV U16 [SYS_MEM_E801+2],DX MOV CX,NUM_MEM_E820_ENTRIES-1 //Leave one to terminate XOR EBX,EBX MOV AX,DS MOV ES,AX MOV DI,SYS_MEM_E820 @@15: PUSH CX MOV EAX,0xE820 MOV ECX,MEM_E820_ENTRY_SIZE MOV EDX,'PAMS' INT 0x15 JC @@20 CMP EAX,'PAMS' JNE @@20 TEST EBX,EBX JZ @@20 ADD DI,MEM_E820_ENTRY_SIZE POP CX LOOP @@15 JMP @@25 @@20: ADD SP,2 //Get PCI Bus Info @@25: MOV U16 [SYS_PCI_BUSSES],256 XOR DX,DX MOV AX,0xB101 INT 0x1A CMP DX,'PC' JNE @@30 MOV CH,0 INC CX MOV U16 [SYS_PCI_BUSSES],CX @@30: CLI //Enable A20 IN AL,0x92 OR AL,2 OUT 0x92,AL CLD //Start with known registers MOV AX,CS MOV DS,AX MOV ES,AX MOV FS,AX MOV GS,AX XOR EAX,EAX XOR EBX,EBX XOR ECX,ECX XOR EDX,EDX XOR ESI,ESI XOR EDI,EDI XOR EBP,EBP XOR EAX,EAX MOV AX,CS SHL EAX,4 MOV U32 [SYS_BOOT_BASE],EAX POP U32 [SYS_BOOT_CODE] MOV BX,CS DEC BX #assert sizeof(CBinFile)==16 MOV GS,BX MOV EBX,U32 GS:[CBinFile.loader_patch_table_offset] ADD EAX,EBX SUB EAX,16 MOV U32 [SYS_BOOT_PATCH_TABLE_BASE],EAX MOV U32 [GDT_BOOT_DS],0x0000FFFF MOV U32 [GDT_BOOT_DS+4],0x0CF9200 MOV U32 [GDT_BOOT_CS],0x0000FFFF MOV U32 [GDT_BOOT_CS+4],0x0CF9A00 MOV EAX,U32 [SYS_BOOT_BASE] ADD U32 [GDT_BOOT_DS+2],EAX ADD U32 [GDT_BOOT_CS+2],EAX // Set-up ptr to limit and base //of GDT. MOV U16 [SYS_TEMP_PTR],GDT_SIZE-1 MOV EAX,U32 [SYS_BOOT_BASE] ADD EAX,SYS_GDTTAB MOV U32 [SYS_TEMP_PTR+2],EAX MOV U16 [SYS_TEMP_PTR+6],0 LGDT U32 [SYS_TEMP_PTR] MOV EAX,SYS_START_CR0 MOV_CR0_EAX /* The assembler doesn't support far jumps so we hand code it. 16-bit code is not important enough for me to implement 16-bit mode in the assembler fully. To complete the switch to 32-bit mode, we have to load the code segment with a far jump. */ DU8 0x66,0xEA; //JMP GDT_CS_SEL:SYS_INIT_OS DU32 SYS_INIT_OS; DU16 GDT_BOOT_CS_SEL; #assert $$+16<=0xFFFF USE32 // ************************************ // ASM Global vars not required for 16-bit start-up ALIGN 8,OC_NOP SYS_HEAP_BASE:: DU64 0x100000+0x1000*(NUM_PML1+NUM_PML2+NUM_PML3+NUM_PML4); SYS_HEAP_LIMIT:: DU64 0; #exe { StreamPrint( "SYS_MEM_INIT_FLAG:: DU8 %d;" "SYS_MEM_INIT_VAL:: DU8 %d;" "SYS_HEAP_INIT_FLAG:: DU8 %d;" "SYS_HEAP_INIT_VAL:: DU8 %d;" "SYS_VAR_INIT_FLAG:: DU8 %d;" "SYS_VAR_INIT_VAL:: DU8 %d;", kernel_cfg->opts[CFG_MEM_INIT], kernel_cfg->mem_init_val, kernel_cfg->opts[CFG_HEAP_INIT],kernel_cfg->heap_init_val, kernel_cfg->opts[CFG_VAR_INIT], kernel_cfg->var_init_val); }; SYS_HEAP_DBG_FLAG:: DU8 _CFG_HEAP_DBG; ALIGN 8,0 SYS_CTRL_ALT_FLAGS:: DU64 0; SYS_EXTERN_TABLE:: DU64 0; SYS_BP_START:: SYS_BP_LOCKED_FLAGS:: DU64 0; SYS_BP_SIZE:: DU64 0; SYS_BP_ALLOCATED_U8S:: DU64 0; SYS_BP_MEM_FREE_LST:: DU64 0; SYS_BP_MEM_FREE_2MEG_LST:: DU64 0; SYS_BP_FREE_PAGE_HASH:: DU64 FREE_PAGE_HASH_SIZE DUP(0); SYS_BP_FREE_PAGE_HASH2:: DU64 64-PAGE_BITS DUP(0); #assert sizeof(CBlkPool)==$$-SYS_BP_START SYS_CODE_BP:: DU64 0; SYS_DATA_BP:: DU64 0; SYS_PROGRESSES:: SYS_PROGRESS1:: DU64 0; SYS_PROGRESS1_MAX:: DU64 0; SYS_PROGRESS1_DESC:: DU8 PROGRESS_DESC_LEN+1 DUP(0); SYS_PROGRESS2:: DU64 0; SYS_PROGRESS2_MAX:: DU64 0; SYS_PROGRESS2_DESC:: DU8 PROGRESS_DESC_LEN+1 DUP(0); SYS_PROGRESS3:: DU64 0; SYS_PROGRESS3_MAX:: DU64 0; SYS_PROGRESS3_DESC:: DU8 PROGRESS_DESC_LEN+1 DUP(0); SYS_PROGRESS4:: DU64 0; SYS_PROGRESS4_MAX:: DU64 0; SYS_PROGRESS4_DESC:: DU8 PROGRESS_DESC_LEN+1 DUP(0); #assert $$-SYS_PROGRESSES==sizeof(CProgress)*4 SYS_FOCUS_TASK:: DU64 0; SYS_TIMER:: DU64 0; SYS_JIFFIES:: DU64 1; SYS_CPU_STRUCTS:: DU64 0; SYS_MP_CNT:: DU64 1; SYS_MP_CNT_INITIAL:: DU64 1; SYS_MP_CNT_LOCK:: DU64 1; SYS_TEMP_CPU0_STRUCT:: DU8 sizeof(CCPU) DUP (0); ALIGN DFT_CACHE_LINE_WIDTH,OC_NOP SYS_CACHE_LINE_WIDTH:: DU64 DFT_CACHE_LINE_WIDTH; DU8 DFT_CACHE_LINE_WIDTH-sizeof(CBinFile)-8 DUP(0); SYS_SEMAS:: DU8 NUM_SYS_SEMAS*SEMA_STRUCT_SIZE DUP(0); ALIGN 16,OC_NOP SYS_INIT_FPU_MMX:: DU8 sizeof(CFPU) DUP(0); // ************************************ ALIGN 16,OC_NOP SYS_INIT_OS:: //Entry point for RAM reboots. PUSH U32 SYS_START_RFLAGS POPFD MOV EAX,SYS_START_CR0 MOV_CR0_EAX MOV AX,GDT_BOOT_DS_SEL //LOAD DS SELECTOR MOV DS,AX MOV ES,AX MOV EAX,U32 [SYS_RUN_LEVEL] AND EAX,RLF_16BIT OR EAX,RLF_32BIT MOV U32 [SYS_RUN_LEVEL],EAX //Patch abs addresses MOV ESI,U32 [SYS_BOOT_PATCH_TABLE_BASE] MOV EDI,U32 [SYS_BOOT_BASE] MOV AX,GDT_ZERO_DS_SEL MOV DS,AX MOV ES,AX MOV ECX,U32 CBinFilePatchTableWithoutOrg.abs_addres_cnt[ESI] LEA ESI,U32 CBinFilePatchTableWithoutOrg.abs_addres[ESI] @@05: LODSD ADD EAX,EDI ADD U32 [EAX],EDI LOOP @@05 MOV AX,GDT_ZERO_DS_SEL MOV DS,AX MOV ES,AX MOV FS,AX MOV GS,AX MOV SS,AX MOV ESP,BOOT_RAM_LIMIT //Temp Stk DU8 0xEA; //JMP GDT_CS_SEL:SYS_CONT_INIT_OS DU32 SYS_CONT_INIT_OS; DU16 GDT_CS_SEL; SYS_CONT_INIT_OS:: LOCK BTS U32 [SYS_RUN_LEVEL],RLf_PATCHED CALL SYS_FIND_BIOS32_SERVICE_DIR CALL SYS_FIND_PCI_SERVICES MOV U32 [SYS_HEAP_BASE],0x100000+0x1000*(NUM_PML1+NUM_PML2+NUM_PML3+NUM_PML4) CALL SYS_INIT_MEM PUSH U32 0 CALL INIT_EM64T USE64 LOCK BTS U32 [SYS_RUN_LEVEL],RLf_64BIT FNINIT FXSAVE U64 [SYS_INIT_FPU_MMX] //Init CPU0 Struct PUSH U32 SYS_TEMP_CPU0_STRUCT PUSH 0 CALL &CPUStructInit PUSH RAX CALL _SET_GS_BASE //Init Adam Task MOV EDI,U32 SYS_ADAM_TASK MOV RCX,sizeof(CTask) XOR RAX,RAX REP_STOSB //Init Adam heap ctrl MOV EDI,U32 SYS_ADAM_HC MOV RCX,sizeof(CHeapCtrl) XOR RAX,RAX REP_STOSB MOV EDI,U32 SYS_ADAM_HC MOV EAX,U32 SYS_BP_START MOV U64 CHeapCtrl.bp[RDI],RAX MOV U32 CHeapCtrl.hc_signature[RDI],HEAP_CTRL_SIGNATURE_VAL LEA RAX,U64 CHeapCtrl.next_um-CMemUsedAllocated.next[RDI] MOV U64 CHeapCtrl.next_um[RDI],RAX MOV U64 CHeapCtrl.last_um[RDI],RAX MOV EAX,U32 SYS_ADAM_TASK MOV U64 CHeapCtrl.mem_task[RDI],RAX MOV U64 CTask.code_heap[RAX],RDI MOV U64 CTask.data_heap[RAX],RDI MOV U32 CTask.task_signature[RAX],TASK_SIGNATURE_VAL MOV U32 CTask.task_in_que_signature[RAX],TASK_IN_QUE_SIGNATURE_VAL LOCK BTS U32 [SYS_RUN_LEVEL],RLf_BOOT_HEAP PUSH ADAM_STK PUSH U32 SYS_ADAM_TASK CALL &TaskInit CALL SET_FS_BASE MOV RSP,U64 CTask.rsp[RAX] JMP I32 &KernelMain // ************************************ USE32 INIT_EM64T: MOV_EAX_CR4 OR EAX,0xB0 MOV_CR4_EAX MOV EAX,PAGE_TABLE_BASE+0x1000*(NUM_PML1+NUM_PML2+NUM_PML3) MOV_CR3_EAX MOV ECX,IA32_EFER XOR EDX,EDX MOV EAX,IA32F_LME WRMSR MOV_EAX_CR0 BTS EAX,31 //enable paging (required for 64-bit mode) MOV_CR0_EAX DU8 0xEA; //JMP GDT_CS64_SEL:EM64T_PART3 DU32 EM64T_PART3; DU16 GDT_CS64_SEL; USE64 EM64T_PART3: RET // ************************************ SYS_RESTART_KERNEL:: XOR RDI,RDI MOV EDI,U32 SYS_BOOT_BASE MOV EDI,U32 [RDI] XOR RSI,RSI MOV ESI,U32 SYS_OS_32START MOV ESI,U32 [RSI] ADD ESI,EDI PUSH U32 GDT_ZERO_DS_SEL //stk seg PUSH U32 BOOT_RAM_LIMIT //stk PUSH U32 0 //flags PUSH U32 GDT_CS_SEL LEA RAX,[@@10] PUSH RAX IRET USE32 @@10: WBINVD //disable paging MOV_EAX_CR0 BTR EAX,31 MOV_CR0_EAX MOV ECX,IA32_EFER XOR EDX,EDX XOR EAX,EAX WRMSR MOV EBX,BOOT_CODE_RAM JMP ESI USE64 SYS_RESTART_KERNEL_END:: }