; TODO finish converting this to a text file that looks like the PDF... ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ASSUMPTIONS: ; ; 1. The bottom 64K of memory is ram, and can be used for ; scratch space by this module. ; ; 2. The system has sufficient free usable ram to copy the ; initial GDT, IDT, and TSS ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; configuration data - must match with build definition CS_BASE EQU 0FFFF0000H ; CS_BASE is the linear address of the segment STARTUP_CODE ; - this is specified in the build language file RAM_START EQU 400H ; RAM_START is the start of free, usable ram in the linear ; memory space. The GDT, IDT, and initial TSS will be ; copied above this space, and a small data segment will be ; discarded at this linear address. The 32-bit word at ; RAM_START will contain the linear address of the first ; free byte above the copied tables - this may be useful if ; a memory manager is used. TSS_INDEX EQU 10 ; TSS_INDEX is the index of the TSS of the first task to ; run after startup ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ------------------------- STRUCTURES and EQU --------------- ; structures for system data ; TSS structure TASK_STATE STRUC link DW ? link_h DW ? ESP0 DD ? SS0 DW ? SS0_h DW ? ESP1 DD ? SS1 DW ? SS1_h DW ? ESP2 DD ? SS2 DW ? SS2_h DW ? CR3_reg DD ? EIP_reg DD ? EFLAGS_regDD ? EAX_reg DD ? ECX_reg DD ? EDX_reg DD ? EBX_reg DD ? ESP_reg DD ? EBP_reg DD ? ESI_reg DD ? EDI_reg DD ? ES_reg DW ? ES_h DW ? CS_reg DW ? CS_h DW ? SS_reg DW ? SS_h DW ? DS_reg DW ? DS_h DW ? FS_reg DW ? FS_h DW ? GS_reg DW ? GS_h DW ? LDT_reg DW ? LDT_h DW ? TRAP_reg DW ? IO_map_baseDW ? TASK_STATE ENDS ; basic structure of a descriptor DESC STRUC lim_0_15 DW ? bas_0_15 DW ? bas_16_23 DB ? access DB ? gran DB ? bas_24_31 DB ? DESC ENDS ; structure for use with LGDT and LIDT instructions TABLE_REG STRUC table_lim DW ? table_linearDD ? TABLE_REG ENDS ; offset of GDT and IDT descriptors in builder generated GDT GDT_DESC_OFF EQU 1*SIZE(DESC) IDT_DESC_OFF EQU 2*SIZE(DESC) ; equates for building temporary GDT in RAM LINEAR_SEL EQU 1*SIZE (DESC) LINEAR_PROTO_LO EQU 00000FFFFH ; LINEAR_ALIAS LINEAR_PROTO_HI EQU 000CF9200H ; Protection Enable Bit in CR0 PE_BIT EQU 1B ; ------------------------------------------------------------ ; ------------------------- DATA SEGMENT---------------------- ; Initially, this data segment starts at linear 0, according ; to the processor’s power-up state. STARTUP_DATA SEGMENT RW free_mem_linear_base LABEL DWORD TEMP_GDT LABEL BYTE ; must be first in segment TEMP_GDT_NULL_DESC DESC <> TEMP_GDT_LINEAR_DESC DESC <> ; scratch areas for LGDT and LIDT instructions TEMP_GDT_SCRATCH TABLE_REG <> APP_GDT_RAM TABLE_REG <> APP_IDT_RAM TABLE_REG <> ; align end_data fill DW ? ; last thing in this segment - should be on a dword boundary end_data LABEL BYTE STARTUP_DATA ENDS ; ------------------------------------------------------------ ; ------------------------- CODE SEGMENT---------------------- STARTUP_CODE SEGMENT ER PUBLIC USE16 ; filled in by builder PUBLIC GDT_EPROM GDT_EPROM TABLE_REG <> ; filled in by builder PUBLIC IDT_EPROM IDT_EPROM TABLE_REG <> ; entry point into startup code - the bootstrap will vector ; here with a near JMP generated by the builder. This ; label must be in the top 64K of linear memory. PUBLIC STARTUP STARTUP: ; DS,ES address the bottom 64K of flat linear memory ASSUME DS:STARTUP_DATA, ES:STARTUP_DATA ; See Figure 9-4 ; load GDTR with temporary GDT LEA EBX,TEMP_GDT ; build the TEMP_GDT in low ram, MOV DWORD PTR [EBX],0 ; where we can address MOV DWORD PTR [EBX]+4,0 MOV DWORD PTR [EBX]+8, LINEAR_PROTO_LO MOV DWORD PTR [EBX]+12, LINEAR_PROTO_HI MOV TEMP_GDT_scratch.table_linear,EBX MOV TEMP_GDT_scratch.table_lim,15 DB 66H; execute a 32 bit LGDT LGDT TEMP_GDT_scratch ; enter protected mode MOV EBX,CR0 OR EBX,PE_BIT MOV CR0,EBX ; clear prefetch queue JMP CLEAR_LABEL CLEAR_LABEL: ; make DS and ES address 4G of linear memory MOV CX,LINEAR_SEL MOV DS,CX MOV ES,CX ; do board specific initialization ; ; ; ...... ; ; See Figure 9-5 ; copy EPROM GDT to ram at: ; RAM_START + size (STARTUP_DATA) MOV EAX,RAM_START ADD EAX,OFFSET (end_data) MOV EBX,RAM_START MOV ECX, CS_BASE ADD ECX, OFFSET (GDT_EPROM) MOV ESI, [ECX].table_linear MOV EDI,EAX MOVZX ECX, [ECX].table_lim MOV APP_GDT_ram[EBX].table_lim,CX INC ECX MOV EDX,EAX MOV APP_GDT_ram[EBX].table_linear,EAX ADD EAX,ECX REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI] ; fixup GDT base in descriptor MOV ECX,EDX MOV [EDX].bas_0_15+GDT_DESC_OFF,CX ROR ECX,16 ; PAGE 4 TODO remove later. MOV [EDX].bas_16_23+GDT_DESC_OFF,CL [EDX].bas_24_31+GDT_DESC_OFF,CH ; copy EPROM IDT to ram at: ; RAM_START+size(STARTUP_DATA)+SIZE (EPROM GDT) MOV ECX, CS_BASE ADD ECX, OFFSET (IDT_EPROM) MOV ESI, [ECX].table_linear MOV EDI,EAX MOVZX ECX, [ECX].table_lim MOV APP_IDT_ram[EBX].table_lim,CX INC ECX MOV APP_IDT_ram[EBX].table_linear,EAX MOV EBX,EAX ADD EAX,ECX REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI] MOV ROR MOV MOV MOV LGDT LIDT REPMOV MOV MOV MOV MOV MOV ROL MOV MOV LSL INC MOV ADD MOVS MOV ROL MOV MOV ROL ;save start MOV ; fixup IDT pointer in GDT [EDX].bas_0_15+IDT_DESC_OFF,BX EBX,16 [EDX].bas_16_23+IDT_DESC_OFF,BL [EDX].bas_24_31+IDT_DESC_OFF,BH ; load GDTR and IDTR EBX,RAM_START DB 66H ; execute a 32 bit LGDT APP_GDT_ram[EBX] DB 66H ; execute a 32 bit LIDT APP_IDT_ram[EBX] ; move the TSS EDI,EAX EBX,TSS_INDEX*SIZE(DESC) ECX,GDT_DESC_OFF ;build linear address for TSS GS,CX DH,GS:[EBX].bas_24_31 DL,GS:[EBX].bas_16_23 EDX,16 DX,GS:[EBX].bas_0_15 ESI,EDX ECX,EBX ECX EDX,EAX EAX,ECX BYTE PTR ES:[EDI],BYTE PTR DS:[ESI] ; fixup TSS pointer GS:[EBX].bas_0_15,DX EDX,16 GS:[EBX].bas_24_31,DH GS:[EBX].bas_16_23,DL EDX,16 of free ram at linear location RAMSTART free_mem_linear_base+RAM_START,EAX ;assume no LDT used in the initial task - if necessary, ;code to move the LDT could be added, and should resemble ;that used to move the TSS ; load task register LTR BX ; No task switch, only descriptor loading ; See Figure 9-6 ; load minimal set of registers necessary to simulate task ; switch MOV AX,[EDX].SS_reg ; start loading registers MOV EDI,[EDX].ESP_reg MOV SS,AX MOV ESP,EDI ; stack now valid PUSH DWORD PTR [EDX].EFLAGS_reg PUSH DWORD PTR [EDX].CS_reg PUSH DWORD PTR [EDX].EIP_reg MOV AX,[EDX].DS_reg MOV BX,[EDX].ES_reg MOV DS,AX ; DS and ES no longer linear memory MOV ES,BX ; simulate far jump to initial task IRETD STARTUP_CODE ENDS END STARTUP, DS:STARTUP_DATA, SS:STARTUP_DATA