feat(kernel): PMM alloc and free pages
This commit is contained in:
		
							parent
							
								
									7a0690cdd8
								
							
						
					
					
						commit
						cadddcbb13
					
				
					 4 changed files with 157 additions and 36 deletions
				
			
		| 
						 | 
					@ -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
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue