⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 st32_64.asm

📁 EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是EFI BIOS源代码中的与平台无关部分的代码
💻 ASM
📖 第 1 页 / 共 3 页
字号:
        cli                             

        mov ax,0b800h
        mov es,ax
        mov byte ptr es:[164],'c'
        mov ax,cs
        mov es,ax

    lea eax, OffsetIn32BitProtectedMode
    add eax, 20000h + 6h
    mov dword ptr[OffsetIn32BitProtectedMode], eax

    lea eax, OffsetInLongMode
    add eax, 20000h + 6h
    mov dword ptr[OffsetInLongMode], eax

    ;
    ; load GDT
    ;
    db      66h     
    lgdt    fword ptr [gdtr]

    ;
    ; Enable Protect Mode (set CR0.PE=1)
    ;
    mov   eax, cr0        ; Read CR0.
    or    eax, 1h         ; Set PE=1
    mov   cr0, eax        ; Write CR0.
    db    066h
    db    0eah                        ; jmp far 16:32
OffsetIn32BitProtectedMode:
    dd    00000000h                   ; offset $+8   (In32BitProtectedMode)
    dw    10h                         ; selector  (flat CS)
In32BitProtectedMode:

;
; Entering Long Mode
;
    db   66h
    mov  ax, 8
    mov  ds, ax
    mov  es, ax
    mov  ss, ax

    ;
    ; Enable the 64-bit page-translation-table entries by
    ; setting CR4.PAE=1 (this is _required_ before activating
    ; long mode). Paging is not enabled until after long mode
    ; is enabled.
    ;
    db 0fh
    db 20h
    db 0e0h
;    mov eax, cr4
    bts eax, 5
    db 0fh
    db 22h
    db 0e0h
;    mov cr4, eax

    ;
    ; This is the Trapolean Page Tables that are guarenteed
    ;  under 4GB.
    ;
    ; Address Map:
    ;    10000 ~    12000 - efildr (loaded)
    ;    20000 ~    21000 - start64.com
    ;    21000 ~    22000 - efi64.com
    ;    22000 ~    90000 - efildr
    ;    90000 ~    96000 - 4G pagetable (will be reload later)
    ;
    db  0b8h
    dd  90000h
;    mov eax, 90000h
    mov cr3, eax

    ;
    ; Enable long mode (set EFER.LME=1).
    ;
    db  0b9h
    dd  0c0000080h
;    mov   ecx, 0c0000080h ; EFER MSR number.
    db 0fh
    db 32h
;    rdmsr                 ; Read EFER.
    db    0fh
    db    0bah
    db    0e8h
    db    08h
;    bts   eax, 8          ; Set LME=1.
    db 0fh
    db 30h
;    wrmsr                 ; Write EFER.

    ;
    ; Enable paging to activate long mode (set CR0.PG=1)
    ;
    mov   eax, cr0        ; Read CR0.
    db    0fh
    db    0bah
    db    0e8h
    db    01fh
;    bts   eax, 31         ; Set PG=1.
    mov   cr0, eax        ; Write CR0.
    jmp   GoToLongMode
GoToLongMode:

    db      067h
    db      0eah                ; Far Jump $+9:Selector to reload CS
OffsetInLongMode:
    dd      00000000            ;   $+9 Offset is ensuing instruction boundary
    dw      038h                ;   Selector is our code selector, 38h

InLongMode:
    db   66h
    mov     ax, 30h
    mov     ds, ax

    db   66h
    mov     ax, 18h
    mov     es, ax
    mov     ss, ax
    mov     ds, ax

    db 0bdh
    dd 400000h
;    mov ebp,000400000h                  ; Destination of EFILDR32
    db 0bbh
    dd 70000h
;    mov ebx,000070000h                  ; Length of copy

    ;
    ; load idt later
    ;
    db 48h
    db 33h
    db 0c0h
;    xor rax, rax
    db 66h
    mov ax, offset idtr
    db 48h
    db 05h
    dd 20000h
;    add rax, 20000h

    db 0fh
    db 01h
    db 18h
;    lidt    fword ptr [rax]

    db 48h
    db 0c7h
    db 0c0h
    dd 21000h
;   mov rax, 21000h
    db 50h
;   push rax

; ret
    db 0c3h

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          ; Selector [0x0]
        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          ; Selector [0x8]
        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          ; Selector [0x10]
        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          ; Selector [0x18]
        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          ; Selector [0x20]
        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          ; Selector [0x28]
        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

;
; system data segment descriptor
;
SYS_DATA64_SEL    equ $-GDT_BASE          ; Selector [0x30]
        dw 0FFFFh       ; limit 0xFFFFF
        dw 0            ; base 0
        db 0
        db 092h         ; P | DPL [1..2] | 1   | 1   | C | R | A
        db 0CFh         ; G | D   | L    | AVL | Segment [19..16]
        db 0

;
; system code segment descriptor
;
SYS_CODE64_SEL    equ $-GDT_BASE          ; Selector [0x38]
        dw 0FFFFh       ; limit 0xFFFFF
        dw 0            ; base 0
        db 0
        db 09Ah         ; P | DPL [1..2] | 1   | 1   | C | R | A
        db 0AFh         ; G | D   | L    | AVL | Segment [19..16]
        db 0

; spare segment descriptor
SPARE4_SEL  equ $-GDT_BASE            ; Selector [0x40]
        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
        dq 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_CODE64_SEL ; selector 15:0
        db 0            ; 0 for interrupt gate
        db 0eh OR 80h   ; type = 386 interrupt gate, present
        dw 0            ; offset 31:16
        dd 0            ; offset 63:32
        dd 0            ; 0 for reserved

; debug exception (INT 1)
DEBUG_EXCEPT_SEL    equ $-IDT_BASE
        dw 0            ; offset 15:0
        dw SYS_CODE64_SEL ; selector 15:0
        db 0            ; 0 for interrupt gate
        db 0eh OR 80h   ; type = 386 interrupt gate, present
        dw 0            ; offset 31:16
        dd 0            ; offset 63:32
        dd 0            ; 0 for reserved

; NMI (INT 2)
NMI_SEL             equ $-IDT_BASE
        dw 0            ; offset 15:0
        dw SYS_CODE64_SEL ; selector 15:0
        db 0            ; 0 for interrupt gate
        db 0eh OR 80h   ; type = 386 interrupt gate, present
        dw 0            ; offset 31:16
        dd 0            ; offset 63:32
        dd 0            ; 0 for reserved

; soft breakpoint (INT 3)
BREAKPOINT_SEL      equ $-IDT_BASE
        dw 0            ; offset 15:0
        dw SYS_CODE64_SEL ; selector 15:0
        db 0            ; 0 for interrupt gate
        db 0eh OR 80h   ; type = 386 interrupt gate, present
        dw 0            ; offset 31:16
        dd 0            ; offset 63:32
        dd 0            ; 0 for reserved

; overflow (INT 4)
OVERFLOW_SEL        equ $-IDT_BASE
        dw 0            ; offset 15:0
        dw SYS_CODE64_SEL ; selector 15:0
        db 0            ; 0 for interrupt gate
        db 0eh OR 80h   ; type = 386 interrupt gate, present
        dw 0            ; offset 31:16
        dd 0            ; offset 63:32
        dd 0            ; 0 for reserved

; bounds check (INT 5)
BOUNDS_CHECK_SEL    equ $-IDT_BASE
        dw 0            ; offset 15:0
        dw SYS_CODE64_SEL ; selector 15:0
        db 0            ; 0 for interrupt gate
        db 0eh OR 80h   ; type = 386 interrupt gate, present
        dw 0            ; offset 31:16
        dd 0            ; offset 63:32
        dd 0            ; 0 for reserved

; invalid opcode (INT 6)
INVALID_OPCODE_SEL  equ $-IDT_BASE
        dw 0            ; offset 15:0
        dw SYS_CODE64_SEL ; selector 15:0
        db 0            ; 0 for interrupt gate
        db 0eh OR 80h   ; type = 386 interrupt gate, present
        dw 0            ; offset 31:16
        dd 0            ; offset 63:32
        dd 0            ; 0 for reserved

; device not available (INT 7)
DEV_NOT_AVAIL_SEL   equ $-IDT_BASE
        dw 0            ; offset 15:0
        dw SYS_CODE64_SEL ; selector 15:0

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -