Skip to content

Latest commit

 

History

History
147 lines (121 loc) · 4.46 KB

File metadata and controls

147 lines (121 loc) · 4.46 KB

Code: part of EntryPoint.s that shows descriptors for long mode

;; look at added segments descriptors for long mode

GDT:
    ; first descriptor must be null descriptor
    NULLDescriptor:
        dw 0x0000
        dw 0x0000
        db 0x0000
        db 0x00
        db 0x00
        db 0x00

    ; IA-32e mode code descriptor for kernel
    IA_32eCODEDESCRIPTOR:
        ; BASE: 0x00000000
        ; LIMIT: 0xFFFFF
        ; P=1, DPL=0, Code Segment, Execute/Read
        ; G=1, D=0, L=1
        dw 0xFFFF ; Limit (16:0]
        dw 0x0000 ; Base (32:16)
        db 0x00   ; Base (40:32]
        db 0x9A   ; P/DPL/S/Type (48:40]
        db 0xAF   ; G/D/L/LIMIT (56:48]
        db 0x00   ; BASE (64:56]

    ; IA-32e mode data and stack descriptor for kernel
    IA_32eDATADESCRIPTOR:
        ; BASE: 0x00000000
        ; LIMIT: 0xFFFFF
        ; P=1, DPL=0, Data Segment, Read/Write
        ; G=1, B=0, L=1
        dw 0xFFFF ; Limit (16:0]
        dw 0x0000 ; Base (32:16)
        db 0x00   ; Base (40:32]
        db 0x92   ; P/DPL/S/Type (48:40]
        db 0xAF   ; G/D/L/LIMIT (56:48]
        db 0x00   ; BASE (64:56]

    ; protected mode's code descriptor (CS)
    CODEDESCRIPTOR:
        ; BASE: 0x00000000
        ; LIMIT: 0xFFFFF
        ; P=1, DPL=0, Code Segment, Execute/Read
        ; G=1, D=1, L=0
        dw 0xFFFF ; Limit (16:0]
        dw 0x0000 ; Base (32:16)
        db 0x00   ; Base (40:32]
        db 0x9A   ; P/DPL/S/Type (48:40]
        db 0xCF   ; G/D/L/LIMIT (56:48]
        db 0x00   ; BASE (64:56]
;; Because of added descriptors, far jmp instruction should be changed
;; change jmp dword 0x08:0x10200 to jmp dword 0x18:0x10200 and
;; change jmp dword 0x08: (PROTECTEDMODE - $$ + 0x10000) to
;; jmp dword 0x18: (PROTECTEDMODE - $$ + 0x10000)

START:
    mov ax, 0x1000
    mov ds, ax
    mov es, ax

    ;; A20 Gate activation
    ; activate A20 by using BIOS service, if it fails
    ; try activating by using system control port
    mov ax, 0x2401 ; 0x2401: activate
    int 0x15       ; 0x15: miscellaneous system services

    jc .A20GATEERROR ; if cflag is set, it fails
    jmp .A20GATESUCCESS

    .A20GATEERROR:
        in al, 0x92  ; 0x92: system control port
        or al, 0x02  ; set A20 Gate bit (set bit 1)
        and al, 0xFE ; prevent reset (clear bit 0)
        out 0x92, al

    .A20GATESUCCESS:
        cli ; ignore interrupt until interrupt handler is set

        lgdt [GDTR]
        
            ; PG=0, CD=1, NW=0, AM=0, WP=0, NE=0, ET=1, EM=0, MP=1, PE=1
            ; CD means cache disable
            ; PE is protection enable    
            ; EM, ET, MP, PE are FPU-related fields and they are set
            ; although their feature is not used in IA-32 mode. they will
            ; be explained in detail later. Don't worry about the fields now
            mov eax, 0x4000003B
            mov cr0, eax

            ; 0x18 is offset to the protected mode's code segment descriptor
            ; from GDT PROTECTEDMODE - $$ + 0x10000 is offset to the code from
            ; segment
            jmp dword 0x18: (PROTECTEDMODE - $$ + 0x10000)

[BITS 32]
PROTECTEDMODE:
    ; set code and data segment
    mov ax, 0x20 ; 0x20 = offset to IA-32 mode's data segment descriptor
    mov ds, ax
    mov es, ax ; it is not required to set es, fs, and gs
    mov fs, ax
    mov gs, ax

    ; set stack segment
    ; because bootloader is not used anymore stack is from 0x0C700 ~ 0xFFFE0
    mov ss, ax ; data segment is also used as stack segment
    mov esp, 0xFFFE
    mov ebp, 0xFFFE

    ;; print message
    
    ; printMessage(success_message, 2, 0)
    push (SWITCHSUCCESSMESSAGE - $$ + 0x10000)
    push 2
    push 0
    call PRINTMESSAGE
    add esp, 12 ; 4 bytes (Protected Mode) * 3

    ; 0x18 is offset to IA-32's code descriptor
    jmp dword 0x18:0x10200

Explanation

Segment Descriptor for long mode

  1. Because IA-32e mode supports compatibility mode, the structure of descriptor for long mode is the same as that for protected mode

  2. Difference between long mode descriptor and protected mode descriptor comes from L bit and D/B bit

    • In protected mode, L bit must be clear
    • In long mode, L bit must be set and D/B bit must be clear
  3. Long mode ignores base address and limit in descriptor

    • In long mode, base address is 0x00 and limit is maximum of current mode
    • Basically, you cannot utilize segmentation feature in long mode. It is like vestigial organ. Segmentation feature exists, but does not work as intended.