paulbergmann_mpstubs/boot/startup_ap.asm

67 lines
1.8 KiB
NASM

; Startup of the remaining application processors (in real mode)
; and switching to 'Protected Mode' with a temporary GDT.
; This code is relocated by ApplicationProcessor::relocateSetupCode()
[SECTION .setup_ap_seg]
[GLOBAL setup_ap_gdt]
[GLOBAL setup_ap_gdtd]
; Unlike the bootstrap processor, the application processors have not been
; setup by the boot loader -- they start in real mode (16 bit) and have to be
; switched manually to protected mode (32 bit)
[BITS 16]
setup_ap:
; Initialize segment register
mov ax, cs ; Code segment and...
mov ds, ax ; .. data segment should point to the same segment
; (we don't use stack / stack segment)
; Disable interrupts
cli
; Disable non maskable interrupts (NMI)
mov al, 0x80
out 0x70, al
; load temporary real mode Global Descriptor Table (GDT)
lgdt [setup_ap_gdtd - setup_ap]
; Switch to protected mode:
; enable protected mode bit (1 << 0) in control register 0
mov eax, cr0
or eax, 1
mov cr0, eax
; Far jump to 32 bit `startup_ap` function
jmp dword 0x08:startup_ap
; memory reserved for temporary real mode GDT
; initialized by ApplicationProcessor::relocateSetupCode()
ALIGN 4
setup_ap_gdt:
dq 0,0,0,0,0 ; reserve memory for at least 5 GDT entries
; memory reserved for temporary real mode GDT descriptor
; initialized by ApplicationProcessor::relocateSetupCode()
setup_ap_gdtd:
dw 0,0,0,0,0 ; reserve memory for GDT descriptor
[SECTION .text]
[BITS 32]
; Segment initialization defined in `boot/startup.asm`
[EXTERN segment_init]
; protected mode (32 bit) startup code for application processor
startup_ap:
; reload all segment selectors (since they still point to the real mode GDT)
mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
; Use same segment initialization function as bootstrap processor
jmp segment_init