1
0
tetros/bios/stage2.asm
Mark cf60d6734a
All checks were successful
CI / Typos (push) Successful in 13s
CI / Clippy (push) Successful in 32s
CI / Build (push) Successful in 1m15s
Comments
2025-03-04 19:41:22 -08:00

73 lines
1.7 KiB
NASM

SECTION .text
USE16
%include "gdt.asm"
%include "thunk.asm"
stage2.entry:
mov si, stage_msg
call print
mov al, '3'
call print_char
call print_line
; enable A20-Line via IO-Port 92, might not work on all motherboards
in al, 0x92
or al, 2
out 0x92, al
protected_mode:
; disable interrupts
cli
; load protected mode GDT
lgdt [gdtr]
; set protected mode bit of cr0
mov eax, cr0
or eax, 1
mov cr0, eax
; far jump to load CS with 32 bit segment
; We need to do this because we are entering 32-bit mode,
; but the instruction pipeline still has 16-bit instructions.
;
; gdt.pm32_code is a multiple of 8, so it always ends with three zero bits.
; The GDT spec abuses this fact, and uses these last three bits to store other
; data (table type and privilege). In this case, 000 is what we need anyway.
;
; Also note that CS isn't an address in protected mode---it's a GDT descriptor.
jmp gdt.pm32_code:protected_mode_inner
; We can now use 32-bit instructions!
USE32
protected_mode_inner:
; load all the other segments with 32 bit data segments
mov eax, gdt.pm32_data
mov ds, eax
mov es, eax
mov fs, eax
mov gs, eax
mov ss, eax
; Place stage 3 stack at 448 KiB
; (512KiB minus 64KiB disk buffer)
mov esp, 0x70000
; push arguments to `start()`
mov eax, thunk.int10
push eax
; Call `start()`.
; 0x18 skips ELF headers.
mov eax, [stage3 + 0x18]
call eax
.halt:
; Halt if `start()` ever returns (it shouldn't, but just in case)
; Without this, we'll try to execute whatever comes next in memory.
cli
hlt
jmp .halt