diff --git a/kernel/Makefile b/kernel/Makefile index b3680f7..81b3655 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -28,6 +28,7 @@ SRCS = kernel.asm \ pic.inc \ idt.inc \ heap.inc \ + queue.inc \ dev/console.inc \ dev/at/pit.inc \ dev/at/cga.inc \ diff --git a/kernel/const.inc.in b/kernel/const.inc.in index f0d66f2..739ffa3 100644 --- a/kernel/const.inc.in +++ b/kernel/const.inc.in @@ -2,6 +2,9 @@ KERNEL_VIRT_BASE = 0xC0000000 KERNEL_OFFSET = 0x100000 KBASE = KERNEL_VIRT_BASE + KERNEL_OFFSET +KERNEL_HEAP_BASE = KERNEL_VIRT_BASE + 0x800000 +KERNEL_HEAP_SIZE = 260046848 + PSIZE = 0x1000 STPDBOOT_MAGIC = 0x53545044 @@ -17,6 +20,7 @@ BUILD_DATE equ "@DATE@" CR = 0x0D LF = 0x0A - CONFIG_COMPAT_I386 = 0 CONFIG_TRACE_PMM = 1 +CONFIG_TRACE_VMEM = 1 +CONFIG_TRACE_VMM = 1 diff --git a/kernel/kernel.asm b/kernel/kernel.asm index 2d55511..5a645dd 100644 --- a/kernel/kernel.asm +++ b/kernel/kernel.asm @@ -47,6 +47,7 @@ kmain: call mm_bootstrap call pmm_init + call vmm_bootstrap mov eax, 4 call pmm_alloc @@ -111,6 +112,7 @@ kmain: jmp .halt include 'klog.inc' + include 'queue.inc' include 'dev/console.inc' include 'dev/dev.inc' include 'mm/mm.inc' @@ -132,7 +134,7 @@ kmain: szMsgKernelAlive db "Kernel (", VERSION_FULL , ") is alive", 0 szMsgBuildDate db "Built ", BUILD_DATE, 0 szErrorBootProtocol db "Error: wrong magic number", 0 - +szKernelHeapStr db "KERNEL-HEAP", 0 ;; Variable: stBootInfo ;; stBootInfo BootInfo diff --git a/kernel/mm/mm.inc b/kernel/mm/mm.inc index eb860e2..cb39bca 100644 --- a/kernel/mm/mm.inc +++ b/kernel/mm/mm.inc @@ -3,6 +3,7 @@ MM_KERNEL_PTE_BASE = 0xFFC00000 include '../sys/mmu.inc' include 'bootstrap.inc' include 'pmm.inc' + include 'vmem.inc' include 'vmm.inc' mm_init: diff --git a/kernel/mm/uvm/uvm.inc b/kernel/mm/uvm/uvm.inc new file mode 100644 index 0000000..f10dce3 --- /dev/null +++ b/kernel/mm/uvm/uvm.inc @@ -0,0 +1,9 @@ + ;; File: uvm.inc + +include 'uvm_km.inc' + + ;; Function: uvm_init + ;; + ;; Sets up the UVM system +uvm_init: + ret diff --git a/kernel/mm/uvm/uvm_km.inc b/kernel/mm/uvm/uvm_km.inc new file mode 100644 index 0000000..e69de29 diff --git a/kernel/mm/uvm/uvm_map.inc b/kernel/mm/uvm/uvm_map.inc new file mode 100644 index 0000000..96f5180 --- /dev/null +++ b/kernel/mm/uvm/uvm_map.inc @@ -0,0 +1,5 @@ + ;; File: uvm_map.inc + +struc VmMap { + +} diff --git a/kernel/mm/vmem.inc b/kernel/mm/vmem.inc new file mode 100644 index 0000000..cdbcac1 --- /dev/null +++ b/kernel/mm/vmem.inc @@ -0,0 +1,278 @@ + ;; File: vmem.inc + ;; + ;; General purpose resource allocator. + ;; Based on and on + +;;; MARK: macros and structs + +VM_BESTFIT = (1 shl 0) +VM_INSTANTFIT = (1 shl 1) +VM_NEXTFIT = (1 shl 2) +VM_SLEEP = (1 shl 3) +VM_NOSLEEP = (1 shl 4) +VM_BOOTSTRAP = (1 shl 5) + +STATIC_SEG_COUNT = 64 + +FREELISTS_N = 4 * 8 +HASHTABLE_N = 16 + +SEGMENT_ALLOCATED = 0 +SEGMENT_FREE = 1 +SEGMENT_SPAN = 2 + +macro GET_LIST reg, N { + bsr reg, reg + xor reg, 31 + add reg, -N + sub reg, 1 +} + +struc VmSegment { + .type db ? + .imported db ? + .base dd ? + .size dd ? + + .spanlist ListEntry + .seglist ListEntry +} +DEFN VmSegment + + ;; Struc: Vmem +struc Vmem { + .name db 16 dup(0) + .base dd ? + .size dd ? + .quantum dd ? + .alloc dd ? + .free dd ? + .source dd ? + .vmflag dd ? + + .freelist dd FREELISTS_N dup(0) + .hashtable dd HASHTABLE_N dup(0) + .spanlist ListHead 0 +} +DEFN Vmem + +;;; MARK: private functions + + ;; Function: _murmur32 + ;; + ;; In: + ;; EAX - Address + ;; + ;; Out: + ;; EAX - Hash + ;; +_murmur32: + ; hash ← hash XOR (hash >> 16) + mov ecx, eax + shr ecx, 16 + xor eax, ecx + ; hash ← hash × 0x85ebca6b + mov ecx, 0x85ebca6b + mul ecx + ; hash ← hash XOR (hash >> 13) + mov ecx, eax + shr ecx, 13 + xor eax, ecx + ; hash ← hash × 0xc2b2ae35 + mov ecx, 0xc2b2ae35 + mul ecx + ; hash ← hash XOR (hash >> 16) + mov ecx, eax + shr ecx, 16 + xor eax, ecx + ret + + ;; Function: _hash_table_addr + ;; + ;; In: + ;; EAX - Vmem + ;; EDX - ADDR +__hash_table_addr: + push ebp + mov ebp, esp + push esi + + mov esi, eax + mov eax, edx + call _murmur32 + and eax, HASHTABLE_N-1 ; x % y (y is a power of two) + shl eax, 2 + + mov edx, esi + add edx, Vmem.hashtable + add edx, eax + mov eax, [edx] + + pop esi + leave + ret + + ;; Function: _vmm_segfree + ;; + ;; In: + ;; EAX - Segment address +_vmm_segfree: + ;mov ecx, eax + ;add ecx, VmSegment.seglist.next + + ;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 + + +;;; MARK: public functions + + ;; Function: vmem_create + ;; + ;; Creates a new arena whose initial span is [Base, Base + Size). + ;; + ;; In: + ;; EAX - Pointer to a object. + ;; EDX - String. + ;; ECX - Base. + ;; ESP[4] - Size in bytes. + ;; ESP[8] - Quantum. + ;; ESP[12] - Alloc function. + ;; ESP[16] - Free function. + ;; ESP[20] - Source. + ;; ESP[24] - Flags. ( or ) +vmem_create: + push ebp + mov ebp, esp + + 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 eax, esi + mov edx, edi + mov ecx, ebx + + pop ebx + pop edi + pop esi +end if + + leave + ret + + ;; Function: vmem_destroy + ;; + ;; Destroys an arena + ;; + ;; In: + ;; EAX - Pointer to a object. +vmem_destroy: + ret + + ;; Function: vmem_alloc + ;; + ;; Allocates n-bytes from arena. + ;; + ;; In: + ;; EAX - Pointer to a object. + ;; EDX - Size in bytes. + ;; ECX - Flags + ;; + ;; Out: + ;; EAX - Allocated address on succes, 0 on failure. +vmem_alloc: + ret + + ;; Function: vmem_free + ;; + ;; Free n-bytes at address to arena + ;; + ;; In: + ;; EAX - Pointer to a object. + ;; EDX - Address. + ;; ECX - Size in bytes. +vmem_free: + ret + + ;; Function: vmem_xalloc + ;; + ;; In: + ;; EAX - Pointer to a object. + ;; EDX - Size in bytes. + ;; ECX - Alignment boundary. + ;; ESP[4] - Phase. + ;; ESP[8] - Nocross. + ;; ESP[12] - Min address. + ;; ESP[16] - Max address. + ;; ESP[20] - Flags. (, , , , ) + ;; + ;; Out: + ;; EAX - Allocated address on succes, 0 on failure. +vmem_xalloc: + ret + + ;; Function: vmem_xfree + ;; + ;; Frees n-bytes at address. + ;; + ;; In: + ;; EAX - Pointer to object. + ;; EDX - Address. + ;; ECX - Size in bytes. +vmem_xfree: + ret + + ;; Function: vmem_add + ;; + ;; Adds a span [Address, Address + Size) to an arena. + ;; + ;; In: + ;; EAX - Pointer to object. + ;; EDX - Address. + ;; ECX - Size in bytes. + ;; ESP[4] - Flags. ( or ) + ;; + ;; Out: + ;; EAX - Return Address on success, 0 on failure. +vmem_add: + ret + +;;; MARK: variables + +aVmemStaticSegs db STATIC_SEG_COUNT*sizeof.VmSegment dup(0) +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 +end if diff --git a/kernel/mm/vmm.inc b/kernel/mm/vmm.inc index 4f337b1..d1381c2 100644 --- a/kernel/mm/vmm.inc +++ b/kernel/mm/vmm.inc @@ -1,80 +1,82 @@ ;; File: vm.inc - ;; Based on + ;; Based on and on -VM_BESTFIT = (1 shl 0) -VM_INSTANTFIT = (1 shl 1) -VM_NEXTFIT = (1 shl 2) -VM_SLEEP = (1 shl 3) -VM_NOSLEEP = (1 shl 4) -VM_BOOTSTRAP = (1 shl 5) - -FREELISTS_N = 4 * 8 -HASHTABLE_N = 16 - -SEGMENT_ALLOCATED = 0 -SEGMENT_FREE = 1 -SEGMENT_SPAN = 2 - -struc VmSegment { - .type db ? - .imported db ? - .base dd ? - .size dd ? -} - -struc VmObject { - .tmp dd ? -} - -struc VmPager { - .tmp dd ? -} - -struc Vmem { - .name db 32 dup(0) - .base dd ? - .size dd ? - .quantum dd ? - .alloc dd ? - .free dd ? - .source dd ? - .qcache_max dd ? - .vmflag dd ? ;; db ? - - .segqueue dd ? - .freelist dd FREELISTS_N dup(0) - .hashtable dd HASHTABLE_N dup(0) - .spanlist dd ? -} - - ;; Subroutine: _murmur32 + ;; Function: vmm_init + ;; + ;; Initializes a Vmem arena ;; ;; In: - ;; EAX - Address - ;; - ;; Out: - ;; EAX - Hash - ;; -_murmur32: - ; hash ← hash XOR (hash >> 16) - mov ecx, eax - shr ecx, 16 - xor eax, ecx - ; hash ← hash × 0x85ebca6b - mov ecx, 0x85ebca6b - mul ecx - ; hash ← hash XOR (hash >> 13) - mov ecx, eax - shr ecx, 13 - xor eax, ecx - ; hash ← hash × 0xc2b2ae35 - mov ecx, 0xc2b2ae35 - mul ecx - ; hash ← hash XOR (hash >> 16) - mov ecx, eax - shr ecx, 16 - xor eax, ecx + ;; 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 -vmem_init: + ;; 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 + + diff --git a/kernel/queue.inc b/kernel/queue.inc new file mode 100644 index 0000000..b454940 --- /dev/null +++ b/kernel/queue.inc @@ -0,0 +1,125 @@ + ;; File: queue.inc + +;;; MARK: doubly linked lists + + ;; Group: List + ;; Doubly linked lists + + ;; Struc: ListHead +struc ListHead initial { + .first dd initial +} + + ;; Struc: ListEntry +struc ListEntry { + .next dd ? + .prev dd ? +} + + ;; Function: list_insert_head + ;; + ;; In: + ;; EAX - Head (see ) + ;; EDX - Element (see ) + ;; +list_insert_head: + mov ecx, [eax] + mov [edx], ecx + or ecx, ecx + jz @f + mov [ecx + 4], edx +@@: + mov [eax], edx + mov [edx + 4], edx + ret + + ;; Function: list_remove + ;; + ;; In: + ;; EAX - Element. +list_remove: + mov ecx, [eax + 4] + mov edx, [eax] + or edx, edx + jz @f + mov [edx + 4], ecx +@@: + mov [ecx], edx + ret + + ;; Function: list_map + ;; + ;; In: + ;; EAX - Pointer to + ;; EDX - Function to apply + ;; +list_map: + push ebp + mov ebp, esp + + push esi + push edi + + ; save function pointer + mov esi, edx + + ; load first elem + mov edi, [eax] +@@: + or edi, edi + jz @f ; exit loop if element is null + + mov eax, edi + call esi + + mov edi, [edi] ; load next element + jmp @b +@@: + pop edi + pop esi + + leave + ret + +;;; MARK: doubly linked tail queues + + ;; Group: TailQ + ;; doubly linked tail queues + + ;; Struc: TailQHead +struc TailQHead { + .first dd ? + .last dd $$ +} + + ;; Struc: TailQEntry +struc TailQEntry { + .next dd ? + .prev dd ? +} + + ;; Function: tailq_insert_head + ;; + ;; In: + ;; EAX - Head. + ;; EDX - Element. +tailq_insert_head: + + ret + + ;; Function: tailq_insert_after + ;; +tailq_insert_after: + ret + + ;; Function: tailq_insert_tail +tailq_insert_tail: + ret + + ;; Function: tailq_remove +tailq_remove: + ret + + ;; Function: tailq_map +tailq_map: + ret diff --git a/kernel/sys/cpu.inc b/kernel/sys/cpu.inc index 85a2019..1bcd5ef 100644 --- a/kernel/sys/cpu.inc +++ b/kernel/sys/cpu.inc @@ -1,7 +1,7 @@ ;; File: cpu.inc - ;; Structure: tss + ;; Struc: tss ;; ;; > 31 23 15 7 0 ;; > +----------|----------+----------|----------+ @@ -93,7 +93,7 @@ struc GDTGate { } - ;; Structure: IDTGate + ;; Struc: IDTGate ;; .offset_low - TODO ;; .selector - TODO ;; .zero - TODO