unreal.asm 1.41 KB
Newer Older
Jeremy Soller's avatar
Jeremy Soller committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
SECTION .text
USE16

; switch to unreal mode; ds and es can address up to 4GiB
unreal:
    cli

    lgdt [unreal_gdtr]

    push es
    push ds

    mov  eax, cr0          ; switch to pmode by
    or al,1                ; set pmode bit
    mov  cr0, eax

    jmp $+2

; http://wiki.osdev.org/Babystep7
; When this register given a "selector", a "segment descriptor cache register"
; is filled with the descriptor values, including the size (or limit). After
; the switch back to real mode, these values are not modified, regardless of
; what value is in the 16-bit segment register. So the 64k limit is no longer
; valid and 32-bit offsets can be used with the real-mode addressing rules
    mov bx, unreal_gdt.data
    mov es, bx
    mov ds, bx

    and al,0xFE            ; back to realmode
    mov  cr0, eax          ; by toggling bit again

    pop ds
    pop es
    sti
    ret


unreal_gdtr:
    dw unreal_gdt.end + 1  ; size
    dd unreal_gdt          ; offset

unreal_gdt:
.null equ $ - unreal_gdt
    dq 0
.data equ $ - unreal_gdt
    istruc GDTEntry
        at GDTEntry.limitl,        dw 0xFFFF
        at GDTEntry.basel,         dw 0x0
        at GDTEntry.basem,         db 0x0
        at GDTEntry.attribute,        db attrib.present | attrib.user | attrib.writable
        at GDTEntry.flags__limith, db 0xFF | flags.granularity | flags.default_operand_size
        at GDTEntry.baseh,         db 0x0
    iend
.end equ $ - unreal_gdt