use fn E820 of int 15h to query memory map (if available)

git-svn-id: svn://kolibrios.org@1103 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Evgeny Grechnikov (Diamond) 2009-06-04 19:43:17 +00:00
parent f705611d81
commit 7931378fda
4 changed files with 129 additions and 16 deletions

View File

@ -815,9 +815,12 @@ end if
dec al dec al
mov [boot_dev], al mov [boot_dev], al
; GET MEMORY MAP
include 'detect/biosmem.inc'
; READ DISKETTE TO MEMORY ; READ DISKETTE TO MEMORY
; cmp [boot_dev],0 cmp [boot_dev],0
jne no_sys_on_floppy jne no_sys_on_floppy
mov si,diskload mov si,diskload
call print call print

View File

@ -453,7 +453,7 @@ proc new_mem_resize stdcall, new_size:dword
@@: @@:
call alloc_page call alloc_page
test eax, eax test eax, eax
jz .exit jz .exit_pop
stdcall map_page_table, edi, eax stdcall map_page_table, edi, eax
@ -491,6 +491,9 @@ proc new_mem_resize stdcall, new_size:dword
jb @B jb @B
jmp .update_size jmp .update_size
.exit_pop:
pop edi
pop esi
.exit: .exit:
xor eax, eax xor eax, eax
inc eax inc eax

View File

@ -14,6 +14,9 @@ MEM_UC equ 0 ;uncached memory
align 4 align 4
proc mem_test proc mem_test
; if we have BIOS with fn E820, skip the test
cmp dword [BOOT_VAR-OS_BASE + 0x9100], 0
jnz .ret
mov eax, cr0 mov eax, cr0
and eax, not (CR0_CD+CR0_NW) and eax, not (CR0_CD+CR0_NW)
@ -29,27 +32,80 @@ proc mem_test
cmp dword [edi], 'TEST' cmp dword [edi], 'TEST'
xchg ebx, dword [edi] xchg ebx, dword [edi]
je @b je @b
mov [MEM_AMOUNT-OS_BASE], edi
and eax, not (CR0_CD+CR0_NW) ;enable caching and eax, not (CR0_CD+CR0_NW) ;enable caching
mov cr0, eax mov cr0, eax
mov eax, edi inc dword [BOOT_VAR-OS_BASE + 0x9100]
xor eax, eax
mov [BOOT_VAR-OS_BASE + 0x9104], eax
mov [BOOT_VAR-OS_BASE + 0x9108], eax
mov [BOOT_VAR-OS_BASE + 0x910C], edi
mov [BOOT_VAR-OS_BASE + 0x9110], eax
.ret:
ret ret
endp endp
align 4 align 4
proc init_mem proc init_mem
mov eax, [MEM_AMOUNT-OS_BASE] ; calculate maximum allocatable address and number of allocatable pages
mov [pg_data.mem_amount-OS_BASE], eax mov edi, BOOT_VAR-OS_BASE + 0x9104
mov ecx, [edi-4]
xor esi, esi ; esi will hold total amount of memory
xor edx, edx ; edx will hold maximum allocatable address
.calcmax:
; round all to pages
mov eax, [edi]
test eax, 0xFFF
jz @f
neg eax
and eax, 0xFFF
add [edi], eax
adc dword [edi+4], 0
sub [edi+8], eax
sbb dword [edi+12], 0
jc .unusable
@@:
and dword [edi+8], not 0xFFF
jz .unusable
; ignore memory after 4 Gb
cmp dword [edi+4], 0
jnz .unusable
mov eax, [edi]
cmp dword [edi+12], 0
jnz .overflow
add eax, [edi+8]
jnc @f
.overflow:
mov eax, 0xFFFFF000
@@:
cmp edx, eax
jae @f
mov edx, eax
@@:
sub eax, [edi]
mov [edi+8], eax
add esi, eax
jmp .usable
.unusable:
and dword [edi+8], 0
.usable:
add edi, 20
loop .calcmax
.calculated:
mov [MEM_AMOUNT-OS_BASE], esi
mov [pg_data.mem_amount-OS_BASE], esi
shr esi, 12
mov [pg_data.pages_count-OS_BASE], esi
shr eax, 12 shr edx, 12
mov [pg_data.pages_count-OS_BASE], eax add edx, 31
shr eax, 3 and edx, not 31
mov [pg_data.pagemap_size-OS_BASE], eax shr edx, 3
mov [pg_data.pagemap_size-OS_BASE], edx
add eax, (sys_pgmap-OS_BASE)+4095 add edx, (sys_pgmap-OS_BASE)+4095
and eax, not 4095 and edx, not 4095
mov [tmp_page_tabs], eax mov [tmp_page_tabs], edx
mov edx, (((sys_pgmap-OS_BASE) + 0xFFFFFF) and not 0xFFFFFF) shr 12 mov edx, (((sys_pgmap-OS_BASE) + 0xFFFFFF) and not 0xFFFFFF) shr 12
mov [pg_data.kernel_pages-OS_BASE], edx mov [pg_data.kernel_pages-OS_BASE], edx
@ -121,14 +177,63 @@ endp
align 4 align 4
proc init_page_map proc init_page_map
; mark all memory as unavailable
mov edi, sys_pgmap-OS_BASE mov edi, sys_pgmap-OS_BASE
mov ecx, [pg_data.pagemap_size-OS_BASE] mov ecx, [pg_data.pagemap_size-OS_BASE]
shr ecx, 2 shr ecx, 2
or eax, -1 xor eax, eax
cld cld
rep stosd rep stosd
; scan through memory map and mark free areas as available
mov ebx, BOOT_VAR-OS_BASE + 0x9104
mov edx, [ebx-4]
.scanmap:
mov ecx, [ebx+8]
shr ecx, 12 ; ecx = number of pages
jz .next
mov edi, [ebx]
shr edi, 12 ; edi = first page
mov eax, edi
neg eax
shr edi, 5
add edi, sys_pgmap-OS_BASE
and eax, 31
jz .startok
sub ecx, eax
jbe .onedword
push ecx
mov ecx, eax
xor eax, eax
inc eax
shl eax, cl
dec eax
or [edi], eax
add edi, 4
pop ecx
.startok:
push ecx
shr ecx, 5
or eax, -1
rep stosd
pop ecx
and ecx, 31
not eax
shl eax, cl
or [edi], eax
jmp .next
.onedword:
add ecx, eax
@@:
dec eax
bts [edi], eax
loop @b
.next:
add ebx, 20
dec edx
jnz .scanmap
; mark kernel memory as allocated (unavailable)
mov ecx, [tmp_page_tabs] mov ecx, [tmp_page_tabs]
mov edx, [pg_data.pages_count-OS_BASE] mov edx, [pg_data.pages_count-OS_BASE]
shr ecx, 12 shr ecx, 12
@ -146,7 +251,7 @@ proc init_page_map
mov ecx, ebx mov ecx, ebx
and ecx, 31 and ecx, 31
shl eax, cl shl eax, cl
mov [edi], eax and [edi], eax
add edi, OS_BASE add edi, OS_BASE
mov [page_start-OS_BASE], edi; mov [page_start-OS_BASE], edi;

View File

@ -23,6 +23,8 @@
; 0x9046 - word - flags ; 0x9046 - word - flags
; 0:907F byte number of BIOS hard disks ; 0:907F byte number of BIOS hard disks
; 0:9080 Nbytes BIOS hard disks ; 0:9080 Nbytes BIOS hard disks
; 0:9100 word available physical memory map: number of blocks
; 0:9104 available physical memory map: blocks
; ;
; Runtime: ; Runtime:
; ;