fix: setup new gdt before bootstrapping MM

This commit is contained in:
d0p1 🏳️‍⚧️ 2025-01-21 09:48:54 +01:00
parent 549c063b38
commit e6b057fe78
13 changed files with 289 additions and 142 deletions

View file

@ -16,7 +16,7 @@ KERNEL = vmstupid.sys
MM_SRCS = bootstrap.inc \
mm.inc \
pmm.inc \
vmm.inc
vmem.inc
SRCS = kernel.asm \
const.inc \

View file

@ -23,4 +23,5 @@ LF = 0x0A
CONFIG_COMPAT_I386 = 0
CONFIG_TRACE_PMM = 1
CONFIG_TRACE_VMEM = 1
CONFIG_TRACE_SVM = 1
CONFIG_TRACE_VMM = 1

View file

@ -44,21 +44,6 @@ kmain:
mov eax, szMsgBuildDate
call klog
call mm_bootstrap
call pmm_init
call vmm_bootstrap
mov eax, 4
call pmm_alloc
xchg bx, bx
mov edx, 4
call pmm_free
xchg bx, bx
call pic_init
; clear tss
mov ecx, sizeof.TSS
xor ax, ax
@ -73,6 +58,19 @@ kmain:
call gdt_flush
call tss_flush
call mm_bootstrap
call mm_init
mov eax, 4
call pmm_alloc
xchg bx, bx
mov edx, 4
call pmm_free
xchg bx, bx
call pic_init
call idt_setup
mov ax, 100 ; 100Hz

View file

@ -4,7 +4,28 @@ MM_KERNEL_PTE_BASE = 0xFFC00000
include 'bootstrap.inc'
include 'pmm.inc'
include 'vmem.inc'
include 'vmm.inc'
mm_init:
call pmm_init
call vmem_bootstrap
mov eax, stVmemKernel
push dword 4
push dword 5
push dword 0
push dword 0
push dword 0
mov edx, PMM_VIRT_TEMP
mov ecx, kend
sub edx, ecx
push edx
mov edx, szVmemKernelName
call vmem_create
add esp, 24
ret
szVmemKernelName db "kmem", 0
stVmemKernel Vmem

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

@ -0,0 +1,9 @@
;; File: svm.inc
;;
;; Simple Virtual Memory Manager mostly inspired by <UVM at https://www.usenix.org/legacy/event/usenix99/full_papers/cranor/cranor.pdf>
include 'svm/amap.inc'
include 'svm/pager.inc'
include 'svm/object.inc'
include 'svm/space.inc'
include 'svm/kernel.inc'

6
kernel/mm/svm/amap.inc Normal file
View file

@ -0,0 +1,6 @@
;; File: amap.inc
struc SvmAmap {
.pages ListHead
}

4
kernel/mm/svm/kernel.inc Normal file
View file

@ -0,0 +1,4 @@
;; File: kernel.inc
stKernelMap SvmSpace

10
kernel/mm/svm/object.inc Normal file
View file

@ -0,0 +1,10 @@
;; File: object.inc
struc SvmObject {
.refcount dd ?
.amap dd ?
.object dd ?
.ops dd ?
}

5
kernel/mm/svm/page.inc Normal file
View file

@ -0,0 +1,5 @@
;; File: page.inc
struc SvmPage {
.physaddr dd ?
}

11
kernel/mm/svm/pager.inc Normal file
View file

@ -0,0 +1,11 @@
;; File: pager.inc
struc SvmPagerOps {
.init dd ?
.reference dd ?
.detach dd ?
.fault dd ?
.get dd ?
.put dd ?
.markdirty dd ?
}

59
kernel/mm/svm/space.inc Normal file
View file

@ -0,0 +1,59 @@
;; File: space
;;
SVM_PROT_READ = PTE_P
SVM_PROT_WRITE = PTE_W
SVM_PROT_ALL = (SVM_PROT_READ or SVM_PROT_WRITE)
struc SvmSpaceEntry {
.start dd ?
.end dd ?
.object dd ?
.protections dd ?
.page_dir dd ?
.link ListEntry
}
struc SvmSpace {
.vmem Vmem
.entries ListHead
; TODO: SvmStats
}
;; Function: svm_map
svm_map:
ret
;; Function: svm_unmap
;;
;; In:
;; EAX - Pointer to <SvmSpace> object.
;; EDX - Address
svm_unmap:
or eax, eax
jnz @f
ret
@@:
push ebp
mov ebp, esp
push esi
push edi
; lock
; remove element
; unlock
; drop object ref
pop edi
pop esi
leave
ret
if CONFIG_TRACE_SVM
szSvmTraceMap db "Trace(SVM): map ", 0
szSvmTraceUnmap db "Trace(SVM): unmap %x", 0
end if

View file

@ -48,7 +48,7 @@ struc Vmem {
.alloc dd ?
.free dd ?
.source dd ?
.vmflag dd ?
.flags dd ?
.freelist dd FREELISTS_N dup(0)
.hashtable dd HASHTABLE_N dup(0)
@ -112,35 +112,49 @@ __hash_table_addr:
leave
ret
;; Function: _vmm_segfree
;;
;; Function: _vmem_segfree
;;
;; In:
;; EAX - Segment address
_vmm_segfree:
;mov ecx, eax
;add ecx, VmSegment.seglist.next
;;
_vmem_segfree:
; XXX: lock
add eax, VmSegment.seglist
mov edx, pVmemFreeSegHead
xchg eax, edx
call list_insert_head
inc [iVmemFreeSegCount]
; XXX: unlock
;mov edx, [pVmmFreeSegHead]
;or edx, edx
;jz @f
;mov [eax + VmSegment.seglist.next], edx
;mov [edx + VmSegment.seglist.prev], ecx
;@@:
; mov [pVmmFreeSegHead], eax
; mov [eax + VmSegment.seglist.prev], ecx
;
; inc [iVmmFreeSegCount]
ret
;
; ;; Function: _vmm_segalloc
;_vmm_segalloc:
; mov eax, [pVmmFreeSegHead]
; or eax, eax
; jz @f
;
; dec [iVmmFreeSegCount]
;@@:
; ret
;; Function: _vmem_segalloc
;;
;; Out:
;; EAX - Pointer to <VmSegment> object on success, 0 on error
_vmem_segalloc:
push ebp
mov ebp, esp
; XXX: lock
mov eax, [pVmemFreeSegHead]
or eax, eax
jz .end
push ebx
mov ebx, eax
call list_remove
sub ebx, VmSegment.seglist
dec [iVmemFreeSegCount]
pop ebx
.end:
; XXX: unlock
leave
ret
;;; MARK: public functions
@ -162,28 +176,72 @@ _vmm_segfree:
vmem_create:
push ebp
mov ebp, esp
sub esp, 8
mov [eax + Vmem.base], ecx
if CONFIG_TRACE_VMEM
push esi
push edi
push ebx
mov esi, eax
mov edi, edx
mov ebx, ecx
mov [ebp - 8], eax
mov [ebp - 4], ecx
mov eax, esi
mov edx, edi
mov ecx, ebx
pop ebx
; zero Vmem object
cld
mov edi, eax
xor eax, eax
mov ecx, sizeof.Vmem shr 2
cld
rep stosd
; copy name
mov esi, edx
mov edx, [ebp - 8]
xor cl, cl
@@:
lodsb
or al, al
jz @f
mov [edx], al
inc edx
inc cl
cmp cl, 15
jl @b
@@:
mov edi, [ebp - 8]
mov ecx, [ebp - 4]
mov [edi + Vmem.base], ecx
; copy other from stack to struct
mov ecx, 28 shr 2
mov esi, ebp
add esi, 8
mov edi, [ebp - 8]
add edi, Vmem.size
rep movsd
mov eax, [ebp - 8]
mov edx, [ebp - 4]
or edx, edx
jnz @f
mov ecx, [eax + Vmem.size]
or ecx, ecx
jz @f
push dword [eax + Vmem.flags]
call vmem_add
add esp, 4
@@:
if CONFIG_TRACE_VMEM
mov esi, [ebp - 8]
mov edx, [esi + Vmem.base]
mov ecx, [esi + Vmem.size]
add ecx, edx
TRACE szTraceVmemCreate, esi, edx, ecx
end if
pop edi
pop esi
end if
leave
ret
@ -263,6 +321,52 @@ vmem_xfree:
;; Out:
;; EAX - Return Address on success, 0 on failure.
vmem_add:
push ebp
mov ebp, esp
push esi
push edi
push ebx
mov esi, eax
mov edi, ebx
mov ebx, ecx
pop ebx
pop edi
pop esi
leave
ret
;; Function: vmem_bootstrap
;;
;; Initialize static segments
;;
vmem_bootstrap:
push ebp
mov ebp, esp
if CONFIG_TRACE_VMEM
TRACE szTraceVmemBootstrap
end if
push ebx
xor ebx, ebx
@@:
mov eax, aVmemStaticSegs
add eax, ebx
call _vmem_segfree
add ebx, sizeof.VmSegment
cmp ebx, STATIC_SEG_COUNT*sizeof.VmSegment
jl @b
pop ebx
leave
ret
;;; MARK: variables
@ -272,7 +376,8 @@ pVmemFreeSegHead dd 0
iVmemFreeSegCount dd 0
if CONFIG_TRACE_VMM
szTraceVmemCreate db "Trace(VMEM): Create %s [%x, %x)", 0
szTraceVmemAdd db "Trace(VMEM): %s: Add span [%x, %x)", 0
szTraceVmemDestroy db "Trace(VMEM): Destroy %s", 0
szTraceVmemBootstrap db "Trace(VMEM): Bootstrap vmem", 0
szTraceVmemCreate db "Trace(VMEM): Create %s [%x, %x)", 0
szTraceVmemAdd db "Trace(VMEM): %s: Add span [%x, %x)", 0
szTraceVmemDestroy db "Trace(VMEM): Destroy %s", 0
end if

View file

@ -1,82 +0,0 @@
;; File: vm.inc
;; Based on <tinyvmem at https://github.com/rdmsr/tinyvmem> and on <Bonwick's paper at https://www.usenix.org/legacy/event/usenix01/full_papers/bonwick/bonwick.pdf>
;; Function: vmm_init
;;
;; Initializes a Vmem arena
;;
;; In:
;; EAX - Pointer to a Vmem dest
;; EDX - Base address
;; ECX - Size
;; ESP[4] - Quantum
;; ESP[8] - Pointer to alloc function
;; ESP[12] - Pointer to free function
;; ESP[16] - Poiter to Vmem source
;; ESP[20] - qcache max
;; ESP[24] - Flags
vmm_init:
push ebp
mov ebp, esp
push esi
push edi
mov [eax + Vmem.base], edx
mov [eax + Vmem.size], ecx
; copy other param from the stack
mov ecx, 28
mov edx, esp
add edx, 4
mov esi, edx
mov edx, eax
add edx, Vmem.quantum
mov edi, edx
rep movsd
mov ecx, [eax + Vmem.size]
or ecx, ecx
jz @f
mov edx, [eax + Vmem.source]
or edx, edx
jnz @f
mov edx, [eax + Vmem.base]
; call vmm_add
add esp, 4
@@:
pop edi
pop esi
leave
ret
;; Function: vmm_bootstrap
;;
vmm_bootstrap:
push ebp
mov ebp, esp
push ebx
xor ebx, ebx
@@:
mov eax, aVmemStaticSegs
add eax, ebx
call _vmm_segfree
add ebx, sizeof.VmSegment
cmp ebx, STATIC_SEG_COUNT*sizeof.VmSegment
jl @b
pop ebx
leave
ret