don't rely on BIOS for returning to real mode

git-svn-id: svn://kolibrios.org@5032 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
CleverMouse 2014-08-15 11:18:27 +00:00
parent 6a10b418b1
commit cd8fe59acc
3 changed files with 72 additions and 33 deletions

View File

@ -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

View File

@ -350,6 +350,34 @@ proc map_page_table stdcall, lin_addr:dword, phis_addr:dword
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

View File

@ -5452,22 +5452,6 @@ end if
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 @@ do_acpi_power_off:
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,7 +5619,33 @@ scan_rsdp:
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,$