feat(kernel): PMM alloc and free pages

This commit is contained in:
d0p1 🏳️‍⚧️ 2025-01-14 12:34:39 +01:00
parent 7a0690cdd8
commit cadddcbb13
4 changed files with 157 additions and 36 deletions

View file

@ -45,6 +45,10 @@ CGA_COLOR_BG_LIGHT_MAGENTA = 0xD0
CGA_COLOR_BG_YELLOW = 0xE0 CGA_COLOR_BG_YELLOW = 0xE0
CGA_COLOR_BG_WHITE = 0xF0 CGA_COLOR_BG_WHITE = 0xF0
macro CGA_SET_COLOR col {
mov byte [bCGAColor], col
}
;; Function: cga_getpos ;; Function: cga_getpos
;; ;;
;; Out: ;; Out:
@ -128,7 +132,7 @@ cga_putc:
mov cx, [ebp-0x2] mov cx, [ebp-0x2]
shl cx, 1 shl cx, 1
add edx, ecx add edx, ecx
mov ah, byte [cga_color] mov ah, byte [bCGAColor]
mov word [edx], ax mov word [edx], ax
mov cx, [ebp-0x2] mov cx, [ebp-0x2]
inc cx inc cx
@ -169,4 +173,4 @@ cga_putc:
cga_device: cga_device:
db 'video', 0, 0, 0 db 'video', 0, 0, 0
cga_color db CGA_COLOR_FG_LIGHT_GRAY bCGAColor db CGA_COLOR_FG_LIGHT_GRAY

View file

@ -48,16 +48,13 @@ kmain:
call pmm_init call pmm_init
; init vmm mov eax, 4
;call mm_init call pmm_alloc
xchg bx, bx
;mov eax, 0xC0400000 mov edx, 4
;mov ebx, [stBootInfo.high_mem] call pmm_free
;add ebx, KERNEL_VIRT_BASE xchg bx, bx
;call pmm_free_range
;mov eax, [stBootInfo.low_mem]
;call heap_init
call pic_init call pic_init

View file

@ -4,10 +4,22 @@
COM1 = 0x3F8 COM1 = 0x3F8
macro TRACE { macro TRACE msg, [arg] {
mov byte [cga_color], CGA_COLOR_FG_CYAN common
_ARGS = 0
reverse
match anything, arg \{
_ARGS = _ARGS + 4
push dword arg
\}
common
CGA_SET_COLOR CGA_COLOR_FG_CYAN
mov eax, msg
call klog call klog
mov byte [cga_color], CGA_COLOR_FG_LIGHT_GRAY if _ARGS
add esp, _ARGS
end if
CGA_SET_COLOR CGA_COLOR_FG_LIGHT_GRAY
} }
;; Function: _klog_print_str ;; Function: _klog_print_str
@ -81,7 +93,7 @@ _klog_print_unsigned:
@@: @@:
pop eax pop eax
add al, 0 add al, '0'
mov dx, COM1 mov dx, COM1
out dx, al out dx, al
pusha pusha

View file

@ -37,8 +37,10 @@ DEFN PMMFreeRange
;; Function: _pmm_map_temp_page ;; Function: _pmm_map_temp_page
;; ;;
;; Map physical address at <PMM_VIRT_TEMP>
;;
;; In: ;; In:
;; EAX - physical address to map at <PMM_VIRT_TEMP> ;; EAX - Physical address
_pmm_map_temp_page: _pmm_map_temp_page:
mov ecx, MM_KERNEL_PTE_BASE + (PMM_VIRT_TEMP shr 12) * 4 mov ecx, MM_KERNEL_PTE_BASE + (PMM_VIRT_TEMP shr 12) * 4
or eax, 0x3 or eax, 0x3
@ -53,6 +55,10 @@ else
end if end if
ret ret
;; Function: _pmm_unmap_temp_page
;;
;; Unmap <PMM_VIRT_TEMP>
;;
_pmm_unmap_temp_page: _pmm_unmap_temp_page:
mov ecx, MM_KERNEL_PTE_BASE + (PMM_VIRT_TEMP shr 12) * 4 mov ecx, MM_KERNEL_PTE_BASE + (PMM_VIRT_TEMP shr 12) * 4
mov dword [ecx], 0 mov dword [ecx], 0
@ -94,6 +100,7 @@ _pmm_init_region:
call _pmm_map_temp_page call _pmm_map_temp_page
xor ecx, ecx xor ecx, ecx
sub esi, edi ; compute size
mov [PMM_VIRT_TEMP], esi mov [PMM_VIRT_TEMP], esi
mov [PMM_VIRT_TEMP + PMMFreeRange.next], ecx mov [PMM_VIRT_TEMP + PMMFreeRange.next], ecx
mov ecx, [pPmmFreeListHead] mov ecx, [pPmmFreeListHead]
@ -111,6 +118,9 @@ _pmm_init_region:
leave leave
ret ret
;; Function: _pmm_init_low_memory
;;
;; Initialize bitmap for lower memory (below 1Mb)
_pmm_init_low_memory: _pmm_init_low_memory:
push ebp push ebp
mov ebp, esp mov ebp, esp
@ -153,6 +163,11 @@ _pmm_init_low_memory:
leave leave
ret ret
;; Function: _pmm_merge_block
;;
_pmm_merge_block:
ret
;;; MARK: public functions ;;; MARK: public functions
;; Function: pmm_alloc ;; Function: pmm_alloc
@ -162,24 +177,86 @@ _pmm_init_low_memory:
;; ;;
;; Out: ;; Out:
;; EAX - first page physical address, 0 on error ;; EAX - first page physical address, 0 on error
;; EDX - error code
;; ;;
pmm_alloc: pmm_alloc:
push ebp
mov ebp, esp
push esi
push edi
push ebx
mov edi, eax
shl edi, 12 ; multiply by page size
if CONFIG_TRACE_PMM
TRACE szTracePmmAlloc, edi
end if
xor ebx, ebx
mov eax, [pPmmFreeListHead] mov eax, [pPmmFreeListHead]
mov esi, eax
.loop:
or eax, eax or eax, eax
jnz @f jnz @f
mov edx, ENOMEM mov edx, ENOMEM ; no memory left :'(
ret ; no memory left :'( jmp .end
@@: @@:
call _pmm_map_temp_page call _pmm_map_temp_page
mov eax, dword [PMM_VIRT_TEMP] ; get size
sub eax, edi
jge @f ; found
; get next block
mov ebx, esi ; store previous block address
mov esi, dword [PMM_VIRT_TEMP + PMMFreeRange.next]
call _pmm_unmap_temp_page
mov eax, esi
jmp .loop ; loop next
@@: ; memory found
mov dword [PMM_VIRT_TEMP], eax ; new size
; compute physical address and store it in esi
add esi, eax
or eax, eax ; remove block if no free space left
jnz .finalize
mov edi, dword [PMM_VIRT_TEMP + PMMFreeRange.next]
mov eax, pPmmFreeListHead
; check if previous block is zero
or ebx, ebx
jz @f
call _pmm_unmap_temp_page
mov eax, ebx
call _pmm_map_temp_page
mov eax, PMM_VIRT_TEMP + PMMFreeRange.next
@@:
mov dword [eax], edi ; remove block
.finalize:
call _pmm_unmap_temp_page call _pmm_unmap_temp_page
xor edx, edx
mov eax, esi
.end:
pop ebx
pop edi
pop esi
leave
ret ret
;; Function: pmm_alloc_page ;; Function: pmm_alloc_page
;; ;;
;; Out: ;; Out:
;; EAX - page physical address, 0 on error ;; EAX - page physical address, 0 on error
;; EDX - error code
pmm_alloc_page: pmm_alloc_page:
mov eax, 1 mov eax, 1
call pmm_alloc call pmm_alloc
@ -189,8 +266,48 @@ pmm_alloc_page:
;; ;;
;; In: ;; In:
;; EAX - Start ;; EAX - Start
;; EDX - End ;; EDX - Page count
pmm_free: pmm_free:
; TODO: merge memory block
push ebp
mov ebp, esp
push esi
push edi
shl edx, 12
mov edi, edx
mov esi, eax
if CONFIG_TRACE_PMM
TRACE szTracePmmFree, esi, edi
mov eax, esi
end if
call _pmm_map_temp_page
mov dword eax, [pPmmFreeListHead]
mov dword [PMM_VIRT_TEMP + PMMFreeRange.next], eax
mov dword [PMM_VIRT_TEMP], edi
mov dword [pPmmFreeListHead], esi
call _pmm_unmap_temp_page
pop esi
pop edi
leave
ret
;; Function: pmm_free_page
;;
;; In:
;; EAX - Physical address
pmm_free_page:
mov edx, 1
call pmm_free
ret ret
;; Function: pmm_init ;; Function: pmm_init
@ -204,22 +321,10 @@ pmm_init:
call _pmm_init_low_memory call _pmm_init_low_memory
if CONFIG_TRACE_PMM if CONFIG_TRACE_PMM
mov byte [cga_color], CGA_COLOR_FG_BLUE TRACE szTracePmmBitmap, [au32PmmLowMemBitmap], [au32PmmLowMemBitmap + 4], \
push dword [au32PmmLowMemBitmap + 28] [au32PmmLowMemBitmap + 8], [au32PmmLowMemBitmap + 12], \
push dword [au32PmmLowMemBitmap + 24] [au32PmmLowMemBitmap + 16], [au32PmmLowMemBitmap + 20], \
push dword [au32PmmLowMemBitmap + 20] [au32PmmLowMemBitmap + 24], [au32PmmLowMemBitmap + 28]
push dword [au32PmmLowMemBitmap + 16]
push dword [au32PmmLowMemBitmap + 12]
push dword [au32PmmLowMemBitmap + 8]
push dword [au32PmmLowMemBitmap + 4]
push dword [au32PmmLowMemBitmap]
mov eax, szTracePmmBitmap
TRACE
add esp, 32
end if end if
mov eax, kend - KERNEL_VIRT_BASE mov eax, kend - KERNEL_VIRT_BASE
@ -227,8 +332,8 @@ end if
mov edx, 0x400000 mov edx, 0x400000
sub edx, eax sub edx, eax
jle @f jle @f
cmp edx, PAGE_SIZE cmp edx, PAGE_SIZE
jle @f jle @f
@ -260,4 +365,7 @@ if CONFIG_TRACE_PMM
szTracePmmBitmap db "Trace(PMM): low memory bitmap", CR, LF, \ szTracePmmBitmap db "Trace(PMM): low memory bitmap", CR, LF, \
" %x", CR, LF, " %x", CR, LF, " %x", CR, LF, " %x", CR, LF, \ " %x", CR, LF, " %x", CR, LF, " %x", CR, LF, " %x", CR, LF, \
" %x", CR, LF, " %x", CR, LF, " %x", CR, LF, " %x", 0 " %x", CR, LF, " %x", CR, LF, " %x", CR, LF, " %x", 0
szTracePmmAlloc db "Trace(PMM): Alloc block (size: %u)", 0
szTracePmmFree db "Trace(PMM): Free block (addr: %x, size: %u)", 0
end if end if