Created
April 17, 2019 17:57
-
-
Save lighth7015/1f1359f45cc4a3ab297f9de40e982662 to your computer and use it in GitHub Desktop.
Protected Mode
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;--- | |
; Giza system bootstrap | |
; - check for a supported CPU, exit with error message if unsupported | |
; - Enter Protected Mode | |
; - Call system bootstrap | |
; - Leave Protected Mode | |
; - exit (status = byte obtatained) | |
; | |
Unsupported db "CPU: Not an 80386-class CPU; unable to start",0Dh,0Ah,'$' | |
AlreadyInPM db "Already in Protected Mode!",0Dh,0Ah,'$' | |
A20LineFail db "A20: Unable to enter protected mode",0Dh,0Ah,'$' | |
start: call GzIsSupportedCPU ; make sure having proper CPU and mode | |
add al, al | |
jz successful ; OK. | |
lea dx, A20LineFail | |
jc GzPrintErr | |
lea dx, Unsupported | |
js GzPrintErr | |
lea dx, AlreadyInPM | |
GzPrintErr: push cs ; Print error message and exit | |
pop ds | |
mov ah, 9 | |
int 21h | |
mov ax, 4cffh ; exit, status=-1 | |
int 21h | |
successful: call GzSysInitStartup | |
mov ah, 4ch ; exit | |
mov al, cl ; status = the byte | |
int 21h | |
codeseg ends | |
end start |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; | |
; +---------------------------------------------------------------------------+ | |
; | GzSysInitStartup - Enters protected mode, entering the Protected | | |
; | Mode section of the bootstrap executable. | | |
; +---------------------------------------------------------------------------+ | |
; | |
GzStartBaseSystem proc ; ===================================================== | |
; === Enter PM and start up =========================== | |
pushf ; ===================================================== | |
push ds ; === Set the processor into Protected Mode and FAR === | |
; === JMP to the startup code in the system loader. === | |
; === From there, we load both the ELF kernel and === | |
; === system libraries. This allows us to both load === | |
; === and start Human Experience which will present === | |
; === the user with a welcome prompt and allow them === | |
; === to sign in. === | |
; ===================================================== | |
mov ax, cs ; | |
movzx eax, ax ; === | |
shl eax, 4 ; eax = base (code segment) | |
mov dword ptr codeseg[2], eax ; | |
mov byte ptr codeseg[5], 9Ah ; set segment attribute | |
mov dx, offset nulldes ; | |
movzx edx, dx ; | |
add eax, edx ; eax = GDT base | |
push eax ; | |
push 20h ; | |
movzx eax, sp ; | |
cli ; make sure no ISR will interfere now | |
lgdt fword ptr ss:[eax] ; LGDT is necessary before switch to PM | |
add sp, 6 ; | |
mov eax, cr0 ; | |
or al, 1 ; | |
mov cr0, eax ; sets Protected Mode | |
db 0eah ; far jump to set CS & clear prefetch queue | |
dw GzStartupMain ; | |
dw 8 ; | |
; === Returns us back to RM ===================== | |
mov cr0, eax ; | |
db 0eah ; far jump to restore CS & clear prefetch queue | |
dd LeaveProtectedMode ; it MUST be a far jump - return crashes! | |
LeaveProtectedMode: pop ds | |
popf | |
ret | |
GzSysInitStartup endp |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;--- | |
; GzIsSupportedCPU - make sure have proper CPU, in Real Mode, and A20 enabled | |
; | |
; changes AX,DX | |
; returns AL=error code if anything wrong | |
; error codes: 040h - not 32-bit CPU (PM,A20 not tested) | |
; 001h - already in PM (386+, A20 not tested) | |
; 0FFh - A20 disabled (32-bit CPU in RM) | |
; | |
GzIsSupportedCPU proc | |
pushf ; save flags | |
cli ; make sure no ISR will interfere now | |
; | |
pushf ; 1. make sure have at least 386 | |
pop ax ; AX=flags | |
xor ah, 40h ; toggle NT | |
push ax ; stack: modified_flags,original_flags | |
popf ; | |
pushf ; stack: modified_flags_from_cpu,original_flags | |
pop dx ; DX=flags passed via CPU | |
mov al, dh ; | |
xor al, ah ; | |
jnz NotSupportedCPU ; improper CPU | |
; | |
smsw ax ; 2. make sure are in Real Mode | |
and al, 1 ; | |
jnz NotSupportedCPU ; if already in PM (maybe VM86) | |
; | |
push ds ; 3. make sure A20 is enabled | |
push es ; | |
push bx ; | |
xor bx, bx ; | |
mov ds, bx ; | |
mov ax, -1 ; | |
mov es, ax ; | |
xor [bx], ah ; change byte[000000h] | |
mov al, es:[bx + 10h] ; get byte[100000h] | |
xor [bx], ah ; change byte[000000h] | |
xor al,es:[bx + 10h] ; compare byte[100000h] with its previous value | |
; 0 if unchanged, -1 means [000000h]==[100000h] | |
pop bx ; | |
pop es ; | |
pop ds ; | |
; | |
NotSupportedCPU: popf ; restore flags | |
test al, al ; test error code | |
ret | |
GzIsSupportedCPU endp |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment