/kernel/trunk/boot/shutdown.inc |
---|
13,8 → 13,24 |
$Revision$ |
use32 |
become_real: |
cli |
lgdt [realmode_gdt-OS_BASE] |
jmp 8:@f |
use16 |
@@: |
mov ax, 10h |
mov ds, ax |
mov es, ax |
mov fs, ax |
mov gs, ax |
mov ss, ax |
mov eax, cr0 |
and eax, not 80000001h |
mov cr0, eax |
jmp 0x1000:pr_mode_exit |
align 4 |
pr_mode_exit: |
; setup stack |
/kernel/trunk/core/memory.inc |
---|
350,6 → 350,34 |
ret |
endp |
; Allocates a physical page for master page table |
; that duplicates first Mb of OS_BASE at address 0; |
; used for starting APs and for shutting down, |
; where it is important to execute code in trivial-mapped pages. |
; Returns eax = allocated physical page. |
proc create_trampoline_pgmap |
; The only non-trivial moment: |
; we need a linear address to fill information, |
; but we don't need it outside of this function, |
; so we're returning physical address. |
; Therefore, allocate memory with kernel_alloc, |
; this will allocate physical page and a linear address somewhere, |
; and deallocate only linear address with free_kernel_space. |
stdcall kernel_alloc, 0x1000 |
mov edi, eax |
mov esi, master_tab |
mov ecx, 1024 |
rep movsd |
mov ecx, [master_tab+(OS_BASE shr 20)] |
mov [eax], ecx |
mov edi, eax |
call get_pg_addr |
push eax |
stdcall free_kernel_space, edi |
pop eax |
ret |
endp |
align 4 |
proc init_LFB |
locals |
/kernel/trunk/kernel.asm |
---|
5452,22 → 5452,6 |
call IRQ_mask_all |
if 0 |
mov word [OS_BASE+0x467+0], pr_mode_exit |
mov word [OS_BASE+0x467+2], 0x1000 |
mov al, 0x0F |
out 0x70, al |
mov al, 0x05 |
out 0x71, al |
mov al, 0xFE |
out 0x64, al |
hlt |
jmp $-1 |
else |
cmp byte [OS_BASE + 0x9030], 2 |
jnz no_acpi_power_off |
5613,21 → 5597,6 |
jmp $ |
no_acpi_power_off: |
mov word [OS_BASE+0x467+0], pr_mode_exit |
mov word [OS_BASE+0x467+2], 0x1000 |
mov al, 0x0F |
out 0x70, al |
mov al, 0x05 |
out 0x71, al |
mov al, 0xFE |
out 0x64, al |
hlt |
jmp $-1 |
scan_rsdp: |
add eax, OS_BASE |
.s: |
5650,8 → 5619,34 |
stc |
.ok: |
ret |
end if |
no_acpi_power_off: |
call create_trampoline_pgmap |
mov cr3, eax |
jmp become_real+0x10000 |
iglobal |
align 4 |
realmode_gdt: |
; selector 0 - not used |
dw 23 |
dd realmode_gdt-OS_BASE |
dw 0 |
; selector 8 - code from 1000:0000 to 1000:FFFF |
dw 0FFFFh |
dw 0 |
db 1 |
db 10011011b |
db 00000000b |
db 0 |
; selector 10h - data from 1000:0000 to 1000:FFFF |
dw 0FFFFh |
dw 0 |
db 1 |
db 10010011b |
db 00000000b |
db 0 |
endg |
if ~ lang eq sp |
diff16 "end of .text segment",0,$ |
end if |