Introduce new memory allocator, now with the ability to free memory!!

This is a super simple linked list memory allocator, written with
lots of help from my friend hyenasky.
This commit is contained in:
Ry 2022-06-23 00:30:59 -07:00
parent 70fd0823dd
commit 9d510e51b7
3 changed files with 181 additions and 20 deletions

View File

@ -13,3 +13,4 @@ end_current_task: jmp [0x00000838]
; memory jump table
allocate_memory: jmp [0x00000840]
free_memory: jmp [0x00000844]

View File

@ -1,35 +1,191 @@
; memory allocator routines
; this is a very basic memory allocator, it doesn't even allow freeing
; TODO: make this better
; block header fields:
; data.32 size - size of block, NOT INCLUDING THE HEADER
; data.32 prev - pointer to previous free block, or zero
; data.32 next - pointer to next free block, or zero
const HEADER_SIZE: 12
const MEMORY_TOP: 0x02000000
initialize_allocator:
push r0
push r1
mov [free_list_head], kernel_bottom
; set the free block size to MEMORY_TOP - [free_list_head]
mov r0, [free_list_head]
mov r1, MEMORY_TOP
sub r1, r0
mov [r0], r1
; mark this as the only free block
add r0, 4
mov [r0], 0
add r0, 4
mov [r0], 0
pop r1
pop r0
ret
; allocate a block of memory
; inputs:
; r0: size in bytes
; outputs:
; r0: pointer to allocated block (or zero if no blocks free)
; r0: pointer to allocated block (or zero if no blocks free of requested size)
allocate_memory:
push r1
push r10
push r11
mov [block], [free_list_head]
; r10: real_size = requested size + header size
mov r10, r0
add r10, HEADER_SIZE
allocate_memory_while_block:
mov r0, [block]
call block_get_size
cmp r0, r10
ifgteq jmp allocate_memory_good_block
; block = block->next
mov r0, [block]
call block_get_next
mov [block], r0
cmp [block], 0
ifnz jmp allocate_memory_while_block
; if we reach this point, no good blocks were found
mov r0, 0
pop r11
pop r10
pop r1
ret
allocate_memory_good_block:
mov r11, r10
add r11, HEADER_SIZE
add r11, 16
mov r0, [block]
call block_get_size
cmp r0, r11
ifgt jmp allocate_memory_good_block_carve
; next = block->next
; prev = block->prev
mov r0, [block]
call block_get_next
mov [next], r0
mov r0, [block]
call block_get_prev
mov [prev], r0
cmp [next], 0
ifnz call allocate_memory_good_block_set_nextprev
cmp [prev], 0
ifnz jmp allocate_memory_good_block_set_prevnext
mov [free_list_head], [next]
allocate_memory_good_block_ret:
mov r0, [block]
add r0, HEADER_SIZE
pop r11
pop r10
pop r1
ret
allocate_memory_good_block_carve:
; block->size -= real_size
mov r0, [block]
call block_get_size
sub r0, r10
mov r1, r0
mov r0, [block]
call block_set_size
; block += block->size
mov r0, [block]
call block_get_size
add [block], r0
; block->size = real_size
mov r0, [block]
mov r1, r10
call block_set_size
jmp allocate_memory_good_block_ret
allocate_memory_good_block_set_nextprev:
; next->prev = prev
mov r0, [next]
mov r1, [prev]
call block_set_prev
ret
allocate_memory_good_block_set_prevnext:
; prev->next = next
mov r0, [prev]
mov r1, [next]
call block_set_next
jmp allocate_memory_good_block_ret
block: data.32 0
next: data.32 0
prev: data.32 0
block_get_size:
mov r0, [r0]
ret
block_set_size:
mov [r0], r1
ret
block_get_prev:
add r0, 4
mov r0, [r0]
ret
block_set_prev:
add r0, 4
mov [r0], r1
ret
block_get_next:
add r0, 8
mov r0, [r0]
ret
block_set_next:
add r0, 8
mov [r0], r1
ret
; free a block of memory
; inputs:
; r0: pointer to allocated block
; outputs:
; none
free_memory:
push r0
push r1
push r2
mov r1, MEMORY_TOP
mov r2, [free_base]
sub r1, r2
cmp r1, r0
iflteq jmp allocate_memory_full
mov r1, [free_base]
add [free_base], r0
mov r0, r1
pop r2
pop r1
ret
allocate_memory_full:
mov r0, 0
; point to the header
sub r0, HEADER_SIZE
mov r2, r0
; add it to the free list
mov r1, 0
call block_set_prev
mov r0, r2
mov r1, [free_list_head]
call block_set_next
cmp [free_list_head], 0
ifnz mov r1, r0
ifnz mov r0, [free_list_head]
ifnz call block_set_prev
mov [free_list_head], r2
pop r2
pop r1
pop r0
ret
free_base: data.32 kernel_bottom
free_list_head: data.32 kernel_bottom

View File

@ -31,6 +31,7 @@ jump_table:
; memory jump table
org.pad 0x00000840
data.32 allocate_memory
data.32 free_memory
; initialization code
entry:
@ -38,7 +39,10 @@ entry:
mov r0, BACKGROUND_COLOR
call fill_background
draw_startup_text:
; initialize the memory allocator
call initialize_allocator
; draw the startup text
mov r0, startup_str
mov r1, 16
mov r2, 464