From 309ac8cd1503a83df20c1d455ab36967627fd76c Mon Sep 17 00:00:00 2001 From: Ry Date: Thu, 23 Jun 2022 15:16:55 -0700 Subject: [PATCH] Use the memory allocator for tasks' code memory --- kernel/main.asm | 58 +++++++++++++++++++++++++++++++++++---------- kernel/task.asm | 62 +++++++++++++++++-------------------------------- 2 files changed, 67 insertions(+), 53 deletions(-) diff --git a/kernel/main.asm b/kernel/main.asm index 97ca2bf..a573eb2 100644 --- a/kernel/main.asm +++ b/kernel/main.asm @@ -9,8 +9,6 @@ const FOX32OS_VERSION_PATCH: 0 const BACKGROUND_COLOR: 0xFF674764 const TEXT_COLOR: 0xFFFFFFFF -const STARTUP_TASK_LOAD_ADDRESS: 0x03000000 - jmp entry jump_table: @@ -75,26 +73,36 @@ entry: cmp r0, 0 ifz jmp boot_disk_1 - ; read the startup file into memory starting at STARTUP_TASK_LOAD_ADDRESS + ; allocate memory for the startup file + mov r0, startup_file_struct + call ryfs_get_size + call allocate_memory + cmp r0, 0 + ifz jmp memory_error + + ; read the startup file into memory + mov r1, r0 mov r0, startup_file_struct - mov r1, STARTUP_TASK_LOAD_ADDRESS call ryfs_read_whole_file ; relocate and execute it as a new task run_startup_task: - mov r0, STARTUP_TASK_LOAD_ADDRESS + mov r0, r1 call parse_fxf_binary + mov r3, r1 mov r1, r0 mov r0, 0 mov r2, rsp sub r2, 4 call new_task - ; when the startup file yields for the first time, we'll end up back here - ; jump back to it without adding this "task" (not really a task) into the queue - ; end_current_task_no_mark is used specifically because it doesn't mark the current task (still set to 0) as unused - ; this does not return - call end_current_task_no_mark + ; when the startup file yields for the first time, we'll end up back here. + ; jump back to it without adding this "task" (not really a task) into the queue. + ; end_current_task_no_mark_no_free is used specifically because it doesn't mark + ; the current task (still set to 0) as unused, and it doesn't free the memory + ; block. + ; this does not return. + call end_current_task_no_mark_no_free ; if startup.cfg is invalid, try loading the raw contents of disk 1 as an FXF binary ; if disk 1 is not inserted, then fail @@ -105,12 +113,21 @@ boot_disk_1: ifz jmp startup_error ; a disk is inserted, load it!! + + ; allocate memory for the startup file + ; r31 contains disk size + mov r0, r31 + call allocate_memory + cmp r0, 0 + ifz jmp memory_error + div r31, 512 inc r31 + mov r2, r0 ; destination pointer + mov r5, r0 mov r0, 0 ; sector counter - mov r2, STARTUP_TASK_LOAD_ADDRESS ; destination pointer - mov r3, 0x80003001 ; command to read a sector from disk 01 into memory + mov r3, 0x80003001 ; command to read a sector from disk 1 into memory mov r4, 0x80002000 ; command to set the location of the buffer boot_disk_1_loop: out r4, r2 ; set the memory buffer location @@ -119,6 +136,7 @@ boot_disk_1_loop: add r2, 512 ; increment the destination pointer loop boot_disk_1_loop + mov r1, r5 jmp run_startup_task startup_error: @@ -136,6 +154,21 @@ startup_error: call draw_format_str_to_background rjmp 0 +memory_error: + mov r0, BACKGROUND_COLOR + call fill_background + + mov r0, memory_error_str + mov r1, 16 + mov r2, 464 + mov r3, TEXT_COLOR + mov r4, 0x00000000 + mov r10, FOX32OS_VERSION_MAJOR + mov r11, FOX32OS_VERSION_MINOR + mov r12, FOX32OS_VERSION_PATCH + call draw_format_str_to_background + rjmp 0 + get_os_version: mov r0, FOX32OS_VERSION_MAJOR mov r1, FOX32OS_VERSION_MINOR @@ -148,6 +181,7 @@ get_os_version: startup_str: data.str "fox32 - OS version %u.%u.%u" data.8 0 startup_error_str: data.str "fox32 - OS version %u.%u.%u - startup.cfg is invalid!" data.8 0 +memory_error_str: data.str "fox32 - OS version %u.%u.%u - not enough memory to load startup file!" data.8 0 startup_file: data.str "startup cfg" startup_file_struct: data.32 0 data.32 0 diff --git a/kernel/task.asm b/kernel/task.asm index 8f83e74..7c4b852 100644 --- a/kernel/task.asm +++ b/kernel/task.asm @@ -3,17 +3,21 @@ ; add a new task to the queue and jump to it immediately ; inputs: ; r0: task ID -; r1: task instruction pointer -; r2: task stack pointer +; r1: pointer to task code +; r2: pointer to task stack +; r3: pointer to memory block to free when task ends ; outputs: ; none new_task: - bse [task_id_bitmap], r0 ; mark this task ID as used + ; mark this task ID as used + bse [task_id_bitmap], r0 - mov r4, r2 - mov r3, r1 - mov r2, r0 + mov r4, r2 ; stack pointer + mov r5, r3 ; memory block pointer + mov r3, r1 ; instruction pointer + mov r2, r0 ; task ID + ; add to the queue mov r0, [task_queue_ptr] call task_store mov [task_queue_ptr], r0 @@ -38,6 +42,7 @@ yield_task: jmp yield_task_0 ; switch to the next task without adding the current task back into the queue +; this will automatically free the task's code block ; inputs: ; none ; outputs: @@ -46,7 +51,9 @@ end_current_task: mov r0, current_task ; get the current task struct call task_load bcl [task_id_bitmap], r2 ; mark this task ID as unused -end_current_task_no_mark: + mov r0, r5 ; memory block pointer + call free_memory +end_current_task_no_mark_no_free: pop r0 ; pop the return address off of the stack cmp [task_queue_ptr], task_queue_bottom @@ -104,6 +111,8 @@ task_load: add r0, 4 mov r4, [r0] ; stack pointer add r0, 4 + mov r5, [r0] ; memory block pointer + add r0, 4 ret task_store: @@ -113,6 +122,8 @@ task_store: add r0, 4 mov [r0], r4 ; stack pointer add r0, 4 + mov [r0], r5 ; memory block pointer + add r0, 4 ret task_empty: @@ -123,43 +134,12 @@ task_empty: task_panic_str: data.str "Task queue empty! Hanging here" data.8 10 data.8 0 -const TASK_SIZE: 12 +const TASK_SIZE: 16 task_id_bitmap: data.32 0 current_task: data.32 0 ; task ID data.32 0 ; instruction pointer data.32 0 ; stack pointer + data.32 0 ; memory block pointer task_queue_ptr: data.32 task_queue_bottom -task_queue_bottom: - data.32 0 data.32 0 data.32 0 - data.32 0 data.32 0 data.32 0 - data.32 0 data.32 0 data.32 0 - data.32 0 data.32 0 data.32 0 - data.32 0 data.32 0 data.32 0 - data.32 0 data.32 0 data.32 0 - data.32 0 data.32 0 data.32 0 - data.32 0 data.32 0 data.32 0 - data.32 0 data.32 0 data.32 0 - data.32 0 data.32 0 data.32 0 - data.32 0 data.32 0 data.32 0 - data.32 0 data.32 0 data.32 0 - data.32 0 data.32 0 data.32 0 - data.32 0 data.32 0 data.32 0 - data.32 0 data.32 0 data.32 0 - data.32 0 data.32 0 data.32 0 - data.32 0 data.32 0 data.32 0 - data.32 0 data.32 0 data.32 0 - data.32 0 data.32 0 data.32 0 - data.32 0 data.32 0 data.32 0 - data.32 0 data.32 0 data.32 0 - data.32 0 data.32 0 data.32 0 - data.32 0 data.32 0 data.32 0 - data.32 0 data.32 0 data.32 0 - data.32 0 data.32 0 data.32 0 - data.32 0 data.32 0 data.32 0 - data.32 0 data.32 0 data.32 0 - data.32 0 data.32 0 data.32 0 - data.32 0 data.32 0 data.32 0 - data.32 0 data.32 0 data.32 0 - data.32 0 data.32 0 data.32 0 - data.32 0 data.32 0 data.32 0 +task_queue_bottom: data.fill 0, 512 ; 32 tasks * 4 entries per task * 4 bytes per word = 512