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:
parent
70fd0823dd
commit
9d510e51b7
|
@ -13,3 +13,4 @@ end_current_task: jmp [0x00000838]
|
||||||
|
|
||||||
; memory jump table
|
; memory jump table
|
||||||
allocate_memory: jmp [0x00000840]
|
allocate_memory: jmp [0x00000840]
|
||||||
|
free_memory: jmp [0x00000844]
|
||||||
|
|
|
@ -1,35 +1,191 @@
|
||||||
; memory allocator routines
|
; 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
|
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
|
; allocate a block of memory
|
||||||
; inputs:
|
; inputs:
|
||||||
; r0: size in bytes
|
; r0: size in bytes
|
||||||
; outputs:
|
; 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:
|
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 r1
|
||||||
push r2
|
push r2
|
||||||
|
|
||||||
mov r1, MEMORY_TOP
|
; point to the header
|
||||||
mov r2, [free_base]
|
sub r0, HEADER_SIZE
|
||||||
sub r1, r2
|
mov r2, r0
|
||||||
cmp r1, r0
|
|
||||||
iflteq jmp allocate_memory_full
|
; add it to the free list
|
||||||
mov r1, [free_base]
|
mov r1, 0
|
||||||
add [free_base], r0
|
call block_set_prev
|
||||||
mov r0, r1
|
mov r0, r2
|
||||||
|
mov r1, [free_list_head]
|
||||||
pop r2
|
call block_set_next
|
||||||
pop r1
|
|
||||||
ret
|
cmp [free_list_head], 0
|
||||||
allocate_memory_full:
|
ifnz mov r1, r0
|
||||||
mov r0, 0
|
ifnz mov r0, [free_list_head]
|
||||||
|
ifnz call block_set_prev
|
||||||
|
|
||||||
|
mov [free_list_head], r2
|
||||||
|
|
||||||
pop r2
|
pop r2
|
||||||
pop r1
|
pop r1
|
||||||
|
pop r0
|
||||||
ret
|
ret
|
||||||
|
|
||||||
free_base: data.32 kernel_bottom
|
free_list_head: data.32 kernel_bottom
|
||||||
|
|
|
@ -31,6 +31,7 @@ jump_table:
|
||||||
; memory jump table
|
; memory jump table
|
||||||
org.pad 0x00000840
|
org.pad 0x00000840
|
||||||
data.32 allocate_memory
|
data.32 allocate_memory
|
||||||
|
data.32 free_memory
|
||||||
|
|
||||||
; initialization code
|
; initialization code
|
||||||
entry:
|
entry:
|
||||||
|
@ -38,7 +39,10 @@ entry:
|
||||||
mov r0, BACKGROUND_COLOR
|
mov r0, BACKGROUND_COLOR
|
||||||
call fill_background
|
call fill_background
|
||||||
|
|
||||||
draw_startup_text:
|
; initialize the memory allocator
|
||||||
|
call initialize_allocator
|
||||||
|
|
||||||
|
; draw the startup text
|
||||||
mov r0, startup_str
|
mov r0, startup_str
|
||||||
mov r1, 16
|
mov r1, 16
|
||||||
mov r2, 464
|
mov r2, 464
|
||||||
|
|
Loading…
Reference in New Issue
Block a user