start.asm
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· 汇编 代码 · 共 843 行 · 第 1/3 页
ASM
843 行
add ebx,01000h ; Source of EFI32
mov dword ptr [JUMP+2],ebx
add ebx,01000h
mov esi,ebx ; Source of EFILDR32
mov ax,0b800h
mov es,ax
mov byte ptr es:[162],'b'
mov ax,cs
mov es,ax
;
; Enable A20 Gate
;
mov ax,2401h ; Enable A20 Gate
int 15h
jnc A20GateEnabled ; Jump if it suceeded
;
; If INT 15 Function 2401 is not supported, then attempt to Enable A20 manually.
;
call Empty8042InputBuffer ; Empty the Input Buffer on the 8042 controller
jnz Timeout8042 ; Jump if the 8042 timed out
out DELAY_PORT,ax ; Delay 1 uS
mov al,WRITE_DATA_PORT_CMD ; 8042 cmd to write output port
out KBD_STATUS_PORT,al ; Send command to the 8042
call Empty8042InputBuffer ; Empty the Input Buffer on the 8042 controller
jnz Timeout8042 ; Jump if the 8042 timed out
mov al,ENABLE_A20_CMD ; gate address bit 20 on
out KBD_CONTROL_PORT,al ; Send command to thre 8042
call Empty8042InputBuffer ; Empty the Input Buffer on the 8042 controller
mov cx,25 ; Delay 25 uS for the command to complete on the 8042
Delay25uS:
out DELAY_PORT,ax ; Delay 1 uS
loop Delay25uS
Timeout8042:
A20GateEnabled:
;
; DISABLE INTERRUPTS - Entering Protected Mode
;
cli
mov ax,0b800h
mov es,ax
mov byte ptr es:[164],'c'
mov ax,cs
mov es,ax
db 66h
lgdt fword ptr [gdtr]
db 66h
lidt fword ptr [idtr]
mov eax,cr0
or al,1
mov cr0,eax
mov eax,0008h ; Flat data descriptor
mov ebp,000400000h ; Destination of EFILDR32
mov ebx,000070000h ; Length of copy
JUMP:
; jmp far 0010:00020000
db 066h
db 0eah
dd 000020000h
dw 00010h
Empty8042InputBuffer:
mov cx,0
Empty8042Loop:
out DELAY_PORT,ax ; Delay 1us
in al,KBD_STATUS_PORT ; Read the 8042 Status Port
and al,02h ; Check the Input Buffer Full Flag
loopnz Empty8042Loop ; Loop until the input buffer is empty or a timout of 65536 uS
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; data
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
align 02h
gdtr dw GDT_END - GDT_BASE - 1 ; GDT limit
dd 0 ; (GDT base gets set above)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; global descriptor table (GDT)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
align 02h
public GDT_BASE
GDT_BASE:
; null descriptor
NULL_SEL equ $-GDT_BASE
dw 0 ; limit 15:0
dw 0 ; base 15:0
db 0 ; base 23:16
db 0 ; type
db 0 ; limit 19:16, flags
db 0 ; base 31:24
; linear data segment descriptor
LINEAR_SEL equ $-GDT_BASE
dw 0FFFFh ; limit 0xFFFFF
dw 0 ; base 0
db 0
db 092h ; present, ring 0, data, expand-up, writable
db 0CFh ; page-granular, 32-bit
db 0
; linear code segment descriptor
LINEAR_CODE_SEL equ $-GDT_BASE
dw 0FFFFh ; limit 0xFFFFF
dw 0 ; base 0
db 0
db 09Ah ; present, ring 0, data, expand-up, writable
db 0CFh ; page-granular, 32-bit
db 0
; system data segment descriptor
SYS_DATA_SEL equ $-GDT_BASE
dw 0FFFFh ; limit 0xFFFFF
dw 0 ; base 0
db 0
db 092h ; present, ring 0, data, expand-up, writable
db 0CFh ; page-granular, 32-bit
db 0
; system code segment descriptor
SYS_CODE_SEL equ $-GDT_BASE
dw 0FFFFh ; limit 0xFFFFF
dw 0 ; base 0
db 0
db 09Ah ; present, ring 0, data, expand-up, writable
db 0CFh ; page-granular, 32-bit
db 0
; spare segment descriptor
SPARE3_SEL equ $-GDT_BASE
dw 0 ; limit 0xFFFFF
dw 0 ; base 0
db 0
db 0 ; present, ring 0, data, expand-up, writable
db 0 ; page-granular, 32-bit
db 0
; spare segment descriptor
SPARE4_SEL equ $-GDT_BASE
dw 0 ; limit 0xFFFFF
dw 0 ; base 0
db 0
db 0 ; present, ring 0, data, expand-up, writable
db 0 ; page-granular, 32-bit
db 0
; spare segment descriptor
SPARE5_SEL equ $-GDT_BASE
dw 0 ; limit 0xFFFFF
dw 0 ; base 0
db 0
db 0 ; present, ring 0, data, expand-up, writable
db 0 ; page-granular, 32-bit
db 0
GDT_END:
align 02h
idtr dw IDT_END - IDT_BASE - 1 ; IDT limit
dd 0 ; (IDT base gets set above)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; interrupt descriptor table (IDT)
;
; Note: The hardware IRQ's specified in this table are the normal PC/AT IRQ
; mappings. This implementation only uses the system timer and all other
; IRQs will remain masked. The descriptors for vectors 33+ are provided
; for convenience.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;idt_tag db "IDT",0
align 02h
public IDT_BASE
IDT_BASE:
; divide by zero (INT 0)
DIV_ZERO_SEL equ $-IDT_BASE
dw 0 ; offset 15:0
dw SYS_CODE_SEL ; selector 15:0
db 0 ; 0 for interrupt gate
db 0eh OR 80h ; type = 386 interrupt gate, present
dw 0 ; offset 31:16
; debug exception (INT 1)
DEBUG_EXCEPT_SEL equ $-IDT_BASE
dw 0 ; offset 15:0
dw SYS_CODE_SEL ; selector 15:0
db 0 ; 0 for interrupt gate
db 0eh OR 80h ; type = 386 interrupt gate, present
dw 0 ; offset 31:16
; NMI (INT 2)
NMI_SEL equ $-IDT_BASE
dw 0 ; offset 15:0
dw SYS_CODE_SEL ; selector 15:0
db 0 ; 0 for interrupt gate
db 0eh OR 80h ; type = 386 interrupt gate, present
dw 0 ; offset 31:16
; soft breakpoint (INT 3)
BREAKPOINT_SEL equ $-IDT_BASE
dw 0 ; offset 15:0
dw SYS_CODE_SEL ; selector 15:0
db 0 ; 0 for interrupt gate
db 0eh OR 80h ; type = 386 interrupt gate, present
dw 0 ; offset 31:16
; overflow (INT 4)
OVERFLOW_SEL equ $-IDT_BASE
dw 0 ; offset 15:0
dw SYS_CODE_SEL ; selector 15:0
db 0 ; 0 for interrupt gate
db 0eh OR 80h ; type = 386 interrupt gate, present
dw 0 ; offset 31:16
; bounds check (INT 5)
BOUNDS_CHECK_SEL equ $-IDT_BASE
dw 0 ; offset 15:0
dw SYS_CODE_SEL ; selector 15:0
db 0 ; 0 for interrupt gate
db 0eh OR 80h ; type = 386 interrupt gate, present
dw 0 ; offset 31:16
; invalid opcode (INT 6)
INVALID_OPCODE_SEL equ $-IDT_BASE
dw 0 ; offset 15:0
dw SYS_CODE_SEL ; selector 15:0
db 0 ; 0 for interrupt gate
db 0eh OR 80h ; type = 386 interrupt gate, present
dw 0 ; offset 31:16
; device not available (INT 7)
DEV_NOT_AVAIL_SEL equ $-IDT_BASE
dw 0 ; offset 15:0
dw SYS_CODE_SEL ; selector 15:0
db 0 ; 0 for interrupt gate
db 0eh OR 80h ; type = 386 interrupt gate, present
dw 0 ; offset 31:16
; double fault (INT 8)
DOUBLE_FAULT_SEL equ $-IDT_BASE
dw 0 ; offset 15:0
dw SYS_CODE_SEL ; selector 15:0
db 0 ; 0 for interrupt gate
db 0eh OR 80h ; type = 386 interrupt gate, present
dw 0 ; offset 31:16
; Coprocessor segment overrun - reserved (INT 9)
RSVD_INTR_SEL1 equ $-IDT_BASE
dw 0 ; offset 15:0
dw SYS_CODE_SEL ; selector 15:0
db 0 ; 0 for interrupt gate
db 0eh OR 80h ; type = 386 interrupt gate, present
dw 0 ; offset 31:16
; invalid TSS (INT 0ah)
INVALID_TSS_SEL equ $-IDT_BASE
dw 0 ; offset 15:0
dw SYS_CODE_SEL ; selector 15:0
db 0 ; 0 for interrupt gate
db 0eh OR 80h ; type = 386 interrupt gate, present
dw 0 ; offset 31:16
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?