55 lines
1.4 KiB
NASM
55 lines
1.4 KiB
NASM
![]() |
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
|