feat(kernel): map low memory using bitmap

This commit is contained in:
d0p1 🏳️‍⚧️ 2025-01-13 16:15:34 +01:00
parent 7f5c45b19d
commit a36c8b00ed
11 changed files with 235 additions and 70 deletions

View file

@ -12,11 +12,16 @@ ASMINCS = sys/bootinfo.inc \
sys/register.inc sys/register.inc
KERNEL = vmstupid.sys KERNEL = vmstupid.sys
MM_SRCS = bootstrap.inc \
mm.inc \
pmm.inc \
vmm.inc
SRCS = kernel.asm \ SRCS = kernel.asm \
const.inc \ const.inc \
klog.inc \ klog.inc \
mm/mm.old.inc \ $(addprefix mm/, $(MM_SRCS)) \
mm/pmm.old.inc \
lock.inc \ lock.inc \
gdt.inc \ gdt.inc \
isr.inc \ isr.inc \

View file

@ -16,3 +16,7 @@ BUILD_DATE equ "@DATE@"
; ------------- OTHER ----------- ; ------------- OTHER -----------
CR = 0x0D CR = 0x0D
LF = 0x0A LF = 0x0A
CONFIG_COMPAT_I386 = 0
CONFIG_TRACE_PMM = 1

View file

@ -11,6 +11,40 @@ CGA_CURSOR_LOW = 0xF
CGA_COLUMNS = 80 CGA_COLUMNS = 80
CGA_LINES = 24 CGA_LINES = 24
CGA_COLOR_FG_BLACK = 0x00
CGA_COLOR_FG_BLUE = 0x01
CGA_COLOR_FG_GREEN = 0x02
CGA_COLOR_FG_CYAN = 0x03
CGA_COLOR_FG_RED = 0x04
CGA_COLOR_FG_MAGENTA = 0x05
CGA_COLOR_FG_BROWN = 0x06
CGA_COLOR_FG_LIGHT_GRAY = 0x07
CGA_COLOR_FG_DARK_GRAY = 0x08
CGA_COLOR_FG_LIGHT_BLUE = 0x09
CGA_COLOR_FG_LIGHT_GREEN = 0x0A
CGA_COLOR_FG_LIGHT_CYAN = 0x0B
CGA_COLOR_FG_LIGHT_RED = 0x0C
CGA_COLOR_FG_LIGHT_MAGENTA = 0x0D
CGA_COLOR_FG_YELLOW = 0x0E
CGA_COLOR_FG_WHITE = 0x0F
CGA_COLOR_BG_BLACK = 0x00
CGA_COLOR_BG_BLUE = 0x10
CGA_COLOR_BG_GREEN = 0x20
CGA_COLOR_BG_CYAN = 0x30
CGA_COLOR_BG_RED = 0x40
CGA_COLOR_BG_MAGENTA = 0x50
CGA_COLOR_BG_BROWN = 0x60
CGA_COLOR_BG_LIGHT_GRAY = 0x70
CGA_COLOR_BG_DARK_GRAY = 0x80
CGA_COLOR_BG_LIGHT_BLUE = 0x90
CGA_COLOR_BG_LIGHT_GREEN = 0xA0
CGA_COLOR_BG_LIGHT_CYAN = 0xB0
CGA_COLOR_BG_LIGHT_RED = 0xC0
CGA_COLOR_BG_LIGHT_MAGENTA = 0xD0
CGA_COLOR_BG_YELLOW = 0xE0
CGA_COLOR_BG_WHITE = 0xF0
;; Function: cga_getpos ;; Function: cga_getpos
;; ;;
;; Out: ;; Out:
@ -94,7 +128,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, 0x07 mov ah, byte [cga_color]
mov word [edx], ax mov word [edx], ax
mov cx, [ebp-0x2] mov cx, [ebp-0x2]
inc cx inc cx
@ -134,3 +168,5 @@ cga_putc:
cga_device: cga_device:
db 'video', 0, 0, 0 db 'video', 0, 0, 0
cga_color db CGA_COLOR_FG_LIGHT_GRAY

View file

@ -46,20 +46,15 @@ kmain:
call mm_bootstrap call mm_bootstrap
xchg bx, bx
; init pmm (kend, 0x400000)
mov eax, kend
mov ebx, 0xC0400000
call pmm_init call pmm_init
; init vmm ; init vmm
call mm_init ;call mm_init
mov eax, 0xC0400000 ;mov eax, 0xC0400000
mov ebx, [stBootInfo.high_mem] ;mov ebx, [stBootInfo.high_mem]
add ebx, KERNEL_VIRT_BASE ;add ebx, KERNEL_VIRT_BASE
call pmm_free_range ;call pmm_free_range
;mov eax, [stBootInfo.low_mem] ;mov eax, [stBootInfo.low_mem]
;call heap_init ;call heap_init
@ -121,8 +116,7 @@ kmain:
include 'klog.inc' include 'klog.inc'
include 'dev/console.inc' include 'dev/console.inc'
include 'dev/dev.inc' include 'dev/dev.inc'
include 'mm/bootstrap.inc' include 'mm/mm.inc'
include 'mm/mm.old.inc'
include 'lock.inc' include 'lock.inc'
include 'gdt.inc' include 'gdt.inc'
include 'syscall.inc' include 'syscall.inc'

View file

@ -4,6 +4,12 @@
COM1 = 0x3F8 COM1 = 0x3F8
macro TRACE {
mov byte [cga_color], CGA_COLOR_FG_CYAN
call klog
mov byte [cga_color], CGA_COLOR_FG_LIGHT_GRAY
}
;; Function: _klog_print_str ;; Function: _klog_print_str
;; ;;
;; In: EAX - Null-terminated string to print ;; In: EAX - Null-terminated string to print
@ -213,7 +219,7 @@ klog:
; display log time ; display log time
call _klog_print_time call _klog_print_time
mov ecx, 4 mov ecx, 8
.begin: .begin:
mov al, [esi] mov al, [esi]
or al, al or al, al
@ -299,6 +305,8 @@ klog:
mov eax, szCRLF mov eax, szCRLF
call _klog_print_str call _klog_print_str
pop esi
leave leave
ret ret

9
kernel/mm/mm.inc Normal file
View file

@ -0,0 +1,9 @@
MM_KERNEL_PTE_BASE = 0xFFC00000
include '../sys/mmu.inc'
include 'bootstrap.inc'
include 'pmm.inc'
include 'vmm.inc'
mm_init:
ret

View file

@ -1,34 +0,0 @@
MM_PTE_BASE = 0xFFC00000
MM_VIRT_TEMP = 0xD0000000
;; EAX - Physical address to map
mm_map_temp:
mov ecx, MM_PTE_BASE + (MM_VIRT_TEMP shr 12)
or eax, 0x3
mov [ecx], eax
if COMPAT_I386
mov eax, 0x40000 + (1023 * PAGE_SIZE)
mov cr3, eax
else
mov eax, MM_VIRT_TEMP
invlpg [eax]
end if
ret
mm_unmap_temp:
mov ecx, MM_PTE_BASE + (MM_VIRT_TEMP shr 12)
mov dword [ecx], 0
if COMPAT_I386
mov eax, 0x40000 + (1023 * PAGE_SIZE)
mov cr3, eax
else
mov eax, MM_VIRT_TEMP
invlpg [eax]
end if
ret
mm_init:
ret

View file

@ -8,6 +8,13 @@
;; > └─────┘ └─────┘ ;; > └─────┘ └─────┘
;; ;;
;;; MARK: macros and structs
;; Constant: PMM_VIRT_TEMP
PMM_VIRT_TEMP = 0xD0000000
PMM_BITMAP_USED = 0x0
PMM_BITMAP_FREE = 0x1
;; Macro: PAGE_ALIGN_UP reg ;; Macro: PAGE_ALIGN_UP reg
macro PAGE_ALIGN_UP reg { macro PAGE_ALIGN_UP reg {
add reg, PAGE_SIZE - 1 add reg, PAGE_SIZE - 1
@ -26,37 +33,128 @@ struc PMMFreeRange {
} }
DEFN PMMFreeRange DEFN PMMFreeRange
;;; MARK: private functions
;; Function: _pmm_map_temp_page ;; Function: _pmm_map_temp_page
;; ;;
;; In:
;; EAX - physical address to map at <PMM_VIRT_TEMP>
_pmm_map_temp_page: _pmm_map_temp_page:
mov ecx, MM_KERNEL_PTE_BASE + (PMM_VIRT_TEMP shr 12) * 4
or eax, 0x3
mov [ecx], eax
if CONFIG_COMPAT_I386
mov eax, 0x40000 + (1023 * PAGE_SIZE)
mov cr3, eax
else
mov eax, PMM_VIRT_TEMP
invlpg [eax]
end if
ret ret
_pmm_unmap_temp_page: _pmm_unmap_temp_page:
mov ecx, MM_KERNEL_PTE_BASE + (PMM_VIRT_TEMP shr 12) * 4
mov dword [ecx], 0
if CONFIG_COMPAT_I386
mov eax, 0x40000 + (1023 * PAGE_SIZE)
mov cr3, eax
else
mov eax, PMM_VIRT_TEMP
invlpg [eax]
end if
ret ret
;; Function: _pmm_init_region
;;
;; Add new memory region to the linked list.
;;
;; In:
;; EAX - Start
;; EDX - End
;;
_pmm_init_region: _pmm_init_region:
push ebp push ebp
mov ebp, esp mov ebp, esp
push edi
push esi
mov edi, eax
mov esi, edx
push edx
push eax push eax
call _pmm_map_temp_page mov eax, szMsgPmmFreeRange
call klog
pop eax pop eax
pop edx
call _pmm_map_temp_page
xor ecx, ecx xor ecx, ecx
mov [MM_VIRT_TEMP], edx mov [PMM_VIRT_TEMP], esi
mov [MM_VIRT_TEMP + PMMFreeRange.next], ecx mov [PMM_VIRT_TEMP + PMMFreeRange.next], ecx
mov ecx, [pPMMFreeListHead] mov ecx, [pPmmFreeListHead]
or ecx, ecx or ecx, ecx
jz @f jz @f
mov [MM_VIRT_TEMP + PMMFreeRange.next], ecx mov [PMM_VIRT_TEMP + PMMFreeRange.next], ecx
@@: @@:
mov [pPMMFreeListHead], eax mov [pPmmFreeListHead], edi
call _pmm_unmap_temp_page call _pmm_unmap_temp_page
pop edi
pop esi
leave leave
ret ret
_pmm_init_low_memory:
push ebp
mov ebp, esp
mov eax, [stBootInfo.low_mem]
push eax
xor eax, eax
push eax
mov eax, szMsgPmmFreeRange
call klog
add esp, 8
; clear bitmap
push edi
xor eax, eax
mov ecx, 8
mov edi, au32PmmLowMemBitmap
rep stosd
mov edi, au32PmmLowMemBitmap
xor eax, eax
xor ecx, ecx
@@:
add eax, PAGE_SIZE
cmp eax, [stBootInfo.low_mem]
jg @f
mov ebx, 1
shl ebx, cl
or [edi], ebx
inc ecx
cmp ecx, 32
jb @b
xor ecx, ecx
add edi, 4
jmp @b
@@:
pop edi
leave
ret
;;; MARK: public functions
;; Function: pmm_alloc ;; Function: pmm_alloc
;; ;;
;; In: ;; In:
@ -64,7 +162,18 @@ _pmm_init_region:
;; ;;
;; Out: ;; Out:
;; EAX - first page physical address, 0 on error ;; EAX - first page physical address, 0 on error
;;
pmm_alloc: pmm_alloc:
mov eax, [pPmmFreeListHead]
or eax, eax
jnz @f
mov edx, ENOMEM
ret ; no memory left :'(
@@:
call _pmm_map_temp_page
call _pmm_unmap_temp_page
ret ret
;; Function: pmm_alloc_page ;; Function: pmm_alloc_page
@ -84,33 +193,47 @@ pmm_alloc_page:
pmm_free: pmm_free:
ret ret
;; Function: _pmm_init_region
;;
;; Add new memory region to the linked list.
;;
;; In:
;; EAX - Start
;; EDX - End
;;
;; Function: pmm_init ;; Function: pmm_init
;; ;;
;; Out: ;; Out:
;; EAX - return -1 on error ;; EAX - return -1 on error
pmm_init: pmm_init:
mov eax, szMsgMmInit mov eax, szMsgPmmInit
call klog call klog
mov eax, kend call _pmm_init_low_memory
if CONFIG_TRACE_PMM
mov byte [cga_color], CGA_COLOR_FG_BLUE
push dword [au32PmmLowMemBitmap + 28]
push dword [au32PmmLowMemBitmap + 24]
push dword [au32PmmLowMemBitmap + 20]
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
mov eax, kend - KERNEL_VIRT_BASE
PAGE_ALIGN_UP eax PAGE_ALIGN_UP eax
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
mov edx, 0x400000 mov edx, 0x400000
call _pmm_init_region call _pmm_init_region
@@: @@:
@ -122,10 +245,19 @@ pmm_init:
xor eax, eax ; TODO: check if enough memory and so on xor eax, eax ; TODO: check if enough memory and so on
ret ret
;;; MARK: variables
;; Variable: pPMMFreeListHead ;; Variable: pPMMFreeListHead
;; Hold first free list entry physical address ;; Hold first free list entry physical address
pPMMFreeListHead dd 0 pPmmFreeListHead dd 0
au32PmmLowMemBitmap rd 8
szMsgPmmInit db "PMM: initialize", 0 szMsgPmmInit db "PMM: initialize", 0
szMsgPmmFreeRange db "PMM: add free memory region %x - %x", 0 szMsgPmmFreeRange db "PMM: add free memory region %x - %x", 0
szErrorNoMemLeft db "Error(PMM): no free memory left", 0 szErrorNoMemLeft db "Error(PMM): no free memory left", 0
if CONFIG_TRACE_PMM
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", 0
end if

View file

@ -1,2 +1,13 @@
ENXIO = 6 ;; File: errno.inc
;; Constant: ENODEV
;; No such device.
ENODEV = 19 ENODEV = 19
;; Constant: ENOMEM
;; Not enough space.
ENOMEM = 20
;; Constant: ENXIO
;; No such device or address.
ENXIO = 6