org 0x2000
[BITS 16]
cli
lgdt [gdtr]
in al, 0x92
cmp al, 0xff
je nofastA20
or al, 2
and al, ~1
out 0x92, al
jmp A20done
nofastA20:
call empty8042
mov al, 0xd1
out 0x64, al
call empty8042
mov al, 0xdf
out 0x60, al
call empty8042
A20done:
mov eax, cr0
or eax, 1
mov cr0, eax
jmp 0x2:ProtectedMode
empty8042:
call waitloop
in al, 0x64
cmp al, 0xff
je done
test al, 1
jz nooutput
call waitloop
in al, 0x60
jmp empty8042
nooutput:
test al, 2
jnz empty8042
done:
ret
[Bits 32]
ProtectedMode:
mov ax, 0x10
mov ds, ax
mov ss, ax
mov es, ax
xor eax, eax
mov fs, ax
mov gs, ax
mov esp, 0x200000 ;
mov ah, 0x01
mov esi, msgprotectedmode
call putstr32
pmloopend: jmp pmloopend
waitloop:
mov ebx,0x9ffff
loopstart:
dec ebx
jnz loopstart
ret
putstr32:
mov edi, [videobuffer]
nextchar:
lodsb
test al, al
jz end
stosw
jmp nextchar
end:
mov [videobuffer], edi
ret
videobuffer dd 0xb8000
msgprotectedmode db "Wir sind jetzt im Protected Mode, das A20 und das A21 Gate muessen sie kennen, das setzt die Prozedur vor dem Einschalten des Protected Modes vorraus, die uebrigen Sektoren ausser dem Bootsektor muessen vorher in den RAM und was eine Segment Deskriptor Tabelle ist, muss man auch lernen, bei IA32 und ebenso dass man jetzt keine Interrupts hat, sondern in den Videopuffer schreiben muss,", 0
nulldescriptor:
dd 0
dd 0
codesegmentdescriptor:
dw 0xFFFF
dw 0
db 0
db 10011010b
db 11001111b
db 0
datasegmentdescriptor:
dw 0xFFFF
dw 0
db 0
db 10010010b
db 11001111b
db 0
gdtr:
Limit dw 24
Base dd nulldescriptor
times 2048-($-$$) hlt