Merge pull request 'feature/nikocs/smaller_init_system' (#6) from feature/nikocs/smaller_init_system into develop
Reviewed-on: #6
This commit is contained in:
		
						commit
						4cdc657d10
					
				
					 17 changed files with 279 additions and 22 deletions
				
			
		|  | @ -1,6 +1,6 @@ | |||
| [workspace] | ||||
| members = ["liblbos"] | ||||
| exclude = ["turntable", "makeddi", "ddi", "example"] | ||||
| exclude = ["blood", "turntable", "makeddi", "ddi", "example"] | ||||
| 
 | ||||
| [package] | ||||
| name = "lbos" | ||||
|  |  | |||
							
								
								
									
										2
									
								
								blood/.gitignore
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								blood/.gitignore
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,2 @@ | |||
| /target | ||||
| /.idea | ||||
							
								
								
									
										14
									
								
								blood/Cargo.lock
									
										
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								blood/Cargo.lock
									
										
									
										generated
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,14 @@ | |||
| # This file is automatically @generated by Cargo. | ||||
| # It is not intended for manual editing. | ||||
| version = 4 | ||||
| 
 | ||||
| [[package]] | ||||
| name = "blood" | ||||
| version = "0.1.0" | ||||
| dependencies = [ | ||||
|  "liblbos", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "liblbos" | ||||
| version = "0.1.1" | ||||
							
								
								
									
										25
									
								
								blood/Cargo.toml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								blood/Cargo.toml
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,25 @@ | |||
| [package] | ||||
| name = "blood" | ||||
| version = "0.1.0" | ||||
| edition = "2024" | ||||
| 
 | ||||
| [dependencies] | ||||
| liblbos = { path = "../liblbos" } | ||||
| 
 | ||||
| [profile.dev] | ||||
| panic = "abort" | ||||
| opt-level = "s" | ||||
| debug-assertions = false | ||||
| overflow-checks = false | ||||
| 
 | ||||
| [profile.release] | ||||
| panic = "abort" | ||||
| opt-level = "z" | ||||
| debug-assertions = false | ||||
| overflow-checks = false | ||||
| lto = true | ||||
| codegen-units = 1 | ||||
| 
 | ||||
| [features] | ||||
| default = ["arch_riscv32"] | ||||
| arch_riscv32 = ["liblbos/arch_riscv32"] | ||||
							
								
								
									
										16
									
								
								blood/build.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								blood/build.rs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,16 @@ | |||
| fn main() { | ||||
|     let arch = std::env::var("LBOS_ARCH").unwrap_or("riscv32".to_string()); | ||||
|     println!("cargo:rerun-if-env-changed=LBOS_ARCH"); | ||||
|     println!("cargo:rustc-cfg=feature=\"arch_{}\"", arch); | ||||
| 
 | ||||
|     println!("cargo:rerun-if-changed=src/arch/{}/asm", arch); | ||||
| 
 | ||||
|     // specify the linker.ld script
 | ||||
|     println!("cargo:rustc-link-arg=-Tsrc/arch/{arch}/asm/linker.ld"); | ||||
| 
 | ||||
|     // output relocation info
 | ||||
|     println!("cargo:rustc-link-arg=--emit-relocs"); | ||||
| 
 | ||||
|     // don't page align sections
 | ||||
|     println!("cargo:rustc-link-arg=-n"); | ||||
| } | ||||
							
								
								
									
										2
									
								
								blood/src/arch/mod.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								blood/src/arch/mod.rs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,2 @@ | |||
| #[cfg(feature = "arch_riscv32")] | ||||
| mod riscv32; | ||||
							
								
								
									
										34
									
								
								blood/src/arch/riscv32/asm/linker.ld
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								blood/src/arch/riscv32/asm/linker.ld
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,34 @@ | |||
| OUTPUT_FORMAT( "elf32-littleriscv" ) | ||||
| OUTPUT_ARCH( "riscv" ) | ||||
| 
 | ||||
| ENTRY( _start ) | ||||
| 
 | ||||
| MEMORY | ||||
| { | ||||
|     program (wxa) : ORIGIN = 0x0, LENGTH = 20480 | ||||
| } | ||||
| 
 | ||||
| PHDRS | ||||
| { | ||||
|     prg PT_LOAD ; | ||||
| } | ||||
| 
 | ||||
| SECTIONS { | ||||
|     .text : { | ||||
|         . = ALIGN(512); | ||||
|         *(.text .text.*) | ||||
|     } >program AT>program :prg | ||||
| 
 | ||||
|     .rodata : { | ||||
|         *(.rodata .rodata.*) | ||||
|     } >program AT>program :prg | ||||
| 
 | ||||
|     .data : { | ||||
|         *(.sdata .sdata.*) *(.data .data.*) | ||||
|     } >program AT>program :prg | ||||
| 
 | ||||
|     .bss : { | ||||
|         *(.sbss .sbss.*) | ||||
|         *(.bss .bss.*) | ||||
|     } >program AT>program :prg | ||||
| } | ||||
							
								
								
									
										10
									
								
								blood/src/arch/riscv32/mod.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								blood/src/arch/riscv32/mod.rs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,10 @@ | |||
| use crate::main; | ||||
| 
 | ||||
| #[unsafe(no_mangle)] | ||||
| extern "C" fn _start() -> isize { | ||||
|     unsafe { | ||||
|         main(); | ||||
|     } | ||||
| 
 | ||||
|     0 | ||||
| } | ||||
							
								
								
									
										83
									
								
								blood/src/main.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								blood/src/main.rs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,83 @@ | |||
| #![no_std] | ||||
| #![no_main] | ||||
| 
 | ||||
| use liblbos::fs::{DirectoryReader, FileSystem}; | ||||
| 
 | ||||
| #[panic_handler] | ||||
| fn panic(info: &core::panic::PanicInfo) -> ! { | ||||
|     liblbos::syscalls::write_terminal(b"abort\n"); | ||||
|     loop {} | ||||
| } | ||||
| mod arch; | ||||
| 
 | ||||
| #[unsafe(no_mangle)] | ||||
| extern "C" fn main() { | ||||
|     loop { | ||||
|         const TURNTBL: &str = "TURNTBL.DDI"; | ||||
|         let mut fs = FileSystem::empty(); | ||||
|         if liblbos::ktask::ktask_fsopen(&mut fs) != 0 { | ||||
|             liblbos::syscalls::write_terminal(b"failed to open fs\n"); | ||||
|             continue; | ||||
|         } | ||||
|         let mut dir = DirectoryReader::empty(); | ||||
|         if liblbos::ktask::ktask_fsopendir(&fs, &mut dir, b"/") != 0 { | ||||
|             liblbos::syscalls::write_terminal(b"failed to open dir\n"); | ||||
|             continue; | ||||
|         } | ||||
|         let mut record = liblbos::fs::Record { | ||||
|             name: [0; 12], | ||||
|             record_type: 0, | ||||
|             target: 0, | ||||
|             total_size_bytes: 0, | ||||
|         }; | ||||
|         fn namecmp(record: &liblbos::fs::Record, name: &[u8]) -> bool { | ||||
|             for (i, &x) in record.name.iter().enumerate() { | ||||
|                 if x == 0 { | ||||
|                     return &record.name[..i] == name; | ||||
|                 } | ||||
|             } | ||||
|             false | ||||
|         } | ||||
|         while !namecmp(&record, TURNTBL.as_bytes()) { | ||||
|             if liblbos::ktask::ktask_fsreaddir(&fs, &mut dir, &mut record) != 0 { | ||||
|                 liblbos::syscalls::write_terminal(b"failed to read dir\n"); | ||||
|                 continue; | ||||
|             } | ||||
|             if record.record_type == 0 { | ||||
|                 liblbos::syscalls::write_terminal(b"unexpected eod\n"); | ||||
|             } | ||||
|         } | ||||
|         // found turntable, load it
 | ||||
|         let mut reader = liblbos::fs::FileReader::empty(); | ||||
|         if liblbos::ktask::ktask_fsopenfile(&fs, &record, &mut reader) != 0 { | ||||
|             liblbos::syscalls::write_terminal(b"failed to open file\n"); | ||||
|             continue; | ||||
|         } | ||||
|         let size = record.total_size_bytes as usize; | ||||
|         let buf = liblbos::syscalls::alloc_blocks(size.div_ceil(512)); | ||||
|         if liblbos::ktask::ktask_fsreadfile(&fs, &mut reader, unsafe { core::slice::from_raw_parts_mut(buf as *mut _, size) }) != 0 { | ||||
|             liblbos::syscalls::write_terminal(b"failed to read file\n"); | ||||
|         } | ||||
| 
 | ||||
|         let mut task_setup = liblbos::TaskSetup { | ||||
|             epc: 0, | ||||
|             stack_block_count: 2, | ||||
|             ddi_first_addr: 0, | ||||
|             ddi_size: 0, | ||||
|             environment: 0, | ||||
|             wait_for_task_exit: false, | ||||
|         }; | ||||
| 
 | ||||
|         if liblbos::ktask::ktask_loadddifile(buf, size, &mut task_setup as *mut _ as usize) != 0 { | ||||
|             liblbos::syscalls::write_terminal(b"failed to load ddi\n"); | ||||
|             liblbos::syscalls::free_blocks(buf, size.div_ceil(512)); | ||||
|             continue; | ||||
|         } | ||||
| 
 | ||||
|         liblbos::syscalls::free_blocks(buf, size.div_ceil(512)); | ||||
| 
 | ||||
|         liblbos::syscalls::create_task(task_setup); | ||||
| 
 | ||||
|         liblbos::syscalls::wait_until_alone(); | ||||
|     } | ||||
| } | ||||
|  | @ -8,6 +8,7 @@ mkdir -p mount | |||
| mount "${storage_device}" mount | ||||
| 
 | ||||
| echo "COPYING..." | ||||
| cp -v blood/target/riscv32imac-unknown-none-elf/release/BLOOD.DDI mount | ||||
| cp -v turntable/target/riscv32imac-unknown-none-elf/release/TURNTBL.DDI mount | ||||
| cp -v example/target/riscv32imac-unknown-none-elf/release/EXAMPLE.DDI mount | ||||
| 
 | ||||
|  |  | |||
|  | @ -9,6 +9,8 @@ mod arch; | |||
| #[repr(C)] | ||||
| pub struct TaskSetup { | ||||
|     pub epc: usize, | ||||
|     pub stack_block_count: usize, | ||||
|     /// MUST BE NON-ZERO
 | ||||
|     pub ddi_first_addr: usize, | ||||
|     pub ddi_size: usize, | ||||
|     pub environment: usize, | ||||
|  |  | |||
|  | @ -81,6 +81,8 @@ pub enum SysCall { | |||
|     /// if there is no device providing a gpu, this will not do anything
 | ||||
|     FlushFramebufferRect = 18, | ||||
| 
 | ||||
|     /// doens't return until all other tasks besides the current task and the ktask have exited
 | ||||
|     WaitUntilAlone = 333, | ||||
|     /// initializes kernel, ONLY CALL ONCE! IN FACT, YOU PROBABLY NEVER NEED TO CALL THIS
 | ||||
|     InitKernel = 666 | ||||
| } | ||||
|  | @ -110,6 +112,7 @@ pub fn usize2sc(u: usize) -> SysCall { | |||
|         16 => SysCall::EnableFramebufferConsole, | ||||
|         17 => SysCall::FramebufferPointer, | ||||
|         18 => SysCall::FlushFramebufferRect, | ||||
|         333 => SysCall::WaitUntilAlone, | ||||
|         666 => SysCall::InitKernel, | ||||
|         _ => SysCall::NoAction, | ||||
|     } | ||||
|  | @ -199,6 +202,10 @@ pub fn flush_framebuffer_rect(x: usize, y: usize, w: usize, h: usize) { | |||
|     syscall(SysCall::FlushFramebufferRect, x, y, w, h, 0, 0); | ||||
| } | ||||
| 
 | ||||
| pub fn wait_until_alone() { | ||||
|     syscall(SysCall::WaitUntilAlone, 0, 0, 0, 0, 0, 0); | ||||
| } | ||||
| 
 | ||||
| pub fn init_kernel() { | ||||
|     syscall(SysCall::InitKernel, 0, 0, 0, 0, 0, 0); | ||||
| } | ||||
|  | @ -81,6 +81,7 @@ extern "C" fn _virt_init() -> ! { | |||
| 
 | ||||
|     create_task(TaskSetup { | ||||
|         epc: ktask as usize, | ||||
|         stack_block_count: 2, | ||||
|         ddi_first_addr: 0, | ||||
|         ddi_size: 0, | ||||
|         environment: 0, | ||||
|  |  | |||
							
								
								
									
										15
									
								
								src/main.rs
									
										
									
									
									
								
							
							
						
						
									
										15
									
								
								src/main.rs
									
										
									
									
									
								
							|  | @ -32,7 +32,7 @@ pub extern "C" fn ktask() -> ! { | |||
|     syscalls::init_kernel(); | ||||
|     print(b"kernel ready!\n"); | ||||
| 
 | ||||
|     // load TURNTBL.DDI
 | ||||
|     // load BLOOD.DDI
 | ||||
| 
 | ||||
|     { | ||||
|         fn fserr() { | ||||
|  | @ -62,13 +62,13 @@ pub extern "C" fn ktask() -> ! { | |||
|             record_name == name | ||||
|         } | ||||
| 
 | ||||
|         while !namecmp(&record, b"TURNTBL.DDI") { | ||||
|         while !namecmp(&record, b"BLOOD.DDI") { | ||||
|             if !fs::read_one_record( | ||||
|                 unsafe { &*(&fs as *const _ as *const _) }, | ||||
|                 unsafe { &mut *(&mut dir as *mut _ as *mut _) }, | ||||
|                 unsafe { &mut *(&mut record as *mut _ as *mut _) } | ||||
|             ) { | ||||
|                 print(b"TURNTBL.DDI NOT FOUND ):"); | ||||
|                 print(b"BLOOD.DDI NOT FOUND ):"); | ||||
|                 print(b"\n"); | ||||
|                 rough_panic(['t', 't', 'b']); | ||||
|             } | ||||
|  | @ -89,23 +89,28 @@ pub extern "C" fn ktask() -> ! { | |||
|             unsafe { &mut *(&mut reader as *mut _ as *mut _) }, | ||||
|             unsafe { core::slice::from_raw_parts_mut(buf as *mut _, size) } | ||||
|         ) != 0 { | ||||
|             print(b"TURNTBL.DDI READ ERROR ):"); | ||||
|             print(b"BLOOD.DDI READ ERROR ):"); | ||||
|             print(b"\n"); | ||||
|             rough_panic(['f', 'r', 'e']); | ||||
|         } | ||||
| 
 | ||||
|         // load the ddi
 | ||||
|         let file_contents = unsafe { core::slice::from_raw_parts(buf as *const _, size) }; | ||||
|         let file_size = size; | ||||
|         if let Ok((entrypoint, first_addr, size)) = ddi::load_ddi(&file_contents) { | ||||
|             // free the buffer
 | ||||
|             syscalls::free_blocks(buf, file_size.div_ceil(512)); | ||||
| 
 | ||||
|             create_task(TaskSetup { | ||||
|                 epc: entrypoint, | ||||
|                 stack_block_count: 1, | ||||
|                 ddi_first_addr: first_addr, | ||||
|                 ddi_size: size, | ||||
|                 environment: 0, | ||||
|                 wait_for_task_exit: false, | ||||
|             }); | ||||
|         } else { | ||||
|             print(b"TURNTBL.DDI INVALID DDI ):"); | ||||
|             print(b"BLOOD.DDI INVALID DDI ):"); | ||||
|             print(b"\n"); | ||||
|             rough_panic(['t', 't', 'b']); | ||||
|         } | ||||
|  |  | |||
|  | @ -26,7 +26,7 @@ impl MemoryManager { | |||
|                 uart.putstr("heap_start: "); | ||||
|                 uart.put_bytes(&u32_hex(_heap_start as u32)); | ||||
|                 uart.putstr("totalmem: "); | ||||
|                 uart.put_bytes(&u32_hex(_heap_size as u32)); | ||||
|                 uart.put_bytes(&u32_hex(_heap_size as u32 / BLOCK_SIZE as u32)); | ||||
|                 uart.putstr("\n"); | ||||
|             } | ||||
|         } | ||||
|  |  | |||
|  | @ -12,10 +12,9 @@ pub enum TaskWait { | |||
|     HardBlockDevOperation = 1 << 0, | ||||
|     WaitForNotification = 1 << 1, | ||||
|     WaitForTaskExit = 1 << 2, | ||||
|     WaitUntilAlone = 1 << 7, | ||||
| } | ||||
| 
 | ||||
| pub const STACK_SIZE_IN_BLOCKS: usize = 8; | ||||
| 
 | ||||
| pub const MAX_TASKS: usize = 8; | ||||
| 
 | ||||
| pub static TC: Spinlock<TrafficControl> = Spinlock::new(TrafficControl::empty()); | ||||
|  | @ -69,13 +68,15 @@ pub fn handle_syscall( | |||
|             SysCall::CreateTask => { | ||||
|                 let add = a1 as *mut TaskSetup; | ||||
| 
 | ||||
|                 let stack_size_in_blocks = unsafe { (*add).stack_block_count }; | ||||
| 
 | ||||
|                 tc.init_mem_if_not(); | ||||
|                 let sp = unsafe { | ||||
|                     tc.memory_manager | ||||
|                         .as_mut() | ||||
|                         .unwrap_unchecked() | ||||
|                         .alloc_n_blocks(STACK_SIZE_IN_BLOCKS) | ||||
|                 } + (BLOCK_SIZE * STACK_SIZE_IN_BLOCKS); | ||||
|                         .alloc_n_blocks(stack_size_in_blocks) | ||||
|                 } + (BLOCK_SIZE * stack_size_in_blocks); | ||||
| 
 | ||||
|                 #[cfg(feature = "arch_virt")] | ||||
|                 let t = Some(Task { | ||||
|  | @ -83,6 +84,7 @@ pub fn handle_syscall( | |||
|                     environment: unsafe { (*add).environment }, | ||||
|                     want_exit: false, | ||||
|                     sp, | ||||
|                     stack_size_in_blocks, | ||||
|                     wait: 0, | ||||
|                     incoming_notifications: [const { None }; MAX_TASKS], | ||||
|                     ackwait: [0; MAX_TASKS], | ||||
|  | @ -90,7 +92,7 @@ pub fn handle_syscall( | |||
|                     ddi_mem_start: unsafe { | ||||
|                         (*add).ddi_first_addr | ||||
|                     }, | ||||
|                     ddi_mem_blocks_count: unsafe { (*add).ddi_size / BLOCK_SIZE }, | ||||
|                     ddi_mem_blocks_count: unsafe { (*add).ddi_size.div_ceil(BLOCK_SIZE) }, | ||||
|                     trap_frame: arch::virt::tasks::setup_task(sp), | ||||
|                 }); | ||||
| 
 | ||||
|  | @ -371,6 +373,13 @@ pub fn handle_syscall( | |||
|                 crate::dev::framebuffer_push(&mut tc, x, y, w, h); | ||||
|                 0 | ||||
|             } | ||||
|             SysCall::WaitUntilAlone => { | ||||
|                 let ci = tc.current; | ||||
|                 let mut task = tc.tasks[ci].as_mut().unwrap(); | ||||
|                 task.wait |= TaskWait::WaitForTaskExit as u32; | ||||
|                 suspend = true; | ||||
|                 0 | ||||
|             } | ||||
|         }, | ||||
|         suspend, | ||||
|     ) | ||||
|  | @ -380,7 +389,12 @@ pub fn context_switch<'a>(tc: &'a mut TrafficControl, current: Task) -> Option<& | |||
|     let ci = tc.current; | ||||
|     tc.tasks[ci] = Some(current); | ||||
| 
 | ||||
|     let mut remaining_tasks = 0; | ||||
| 
 | ||||
|     for i in 0..tc.tasks.len() { | ||||
|         if tc.tasks[i].is_some() { | ||||
|             remaining_tasks += 1; | ||||
|         } | ||||
|         let want_exit = tc.tasks[i] | ||||
|             .as_ref() | ||||
|             .map(|task| task.want_exit) | ||||
|  | @ -390,12 +404,13 @@ pub fn context_switch<'a>(tc: &'a mut TrafficControl, current: Task) -> Option<& | |||
|             let sp = tc.tasks[i].as_ref().map(|v| v.sp).unwrap_or(0); | ||||
|             let ddi_start_block = tc.tasks[i].as_ref().map(|v| v.ddi_mem_start).unwrap_or(0); | ||||
|             let ddi_blocks_count = tc.tasks[i].as_ref().map(|v| v.ddi_mem_blocks_count).unwrap_or(0); | ||||
|             let stack_size_in_blocks = tc.tasks[i].as_ref().map(|v| v.stack_size_in_blocks).unwrap_or(0); | ||||
|             if sp != 0 { | ||||
|                 unsafe { | ||||
|                     tc.memory_manager | ||||
|                         .as_mut() | ||||
|                         .unwrap_unchecked() | ||||
|                         .free_n_blocks(sp - (BLOCK_SIZE * STACK_SIZE_IN_BLOCKS), STACK_SIZE_IN_BLOCKS) | ||||
|                         .free_n_blocks(sp - (BLOCK_SIZE * stack_size_in_blocks), stack_size_in_blocks) | ||||
|                 }; | ||||
|                 unsafe { | ||||
|                     tc.memory_manager.as_mut().unwrap_unchecked() | ||||
|  | @ -414,6 +429,17 @@ pub fn context_switch<'a>(tc: &'a mut TrafficControl, current: Task) -> Option<& | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     // if remaining_tasks <= 2, then we need to wake up WaitUntilAlone tasks
 | ||||
|     if remaining_tasks <= 2 { | ||||
|         for task in &mut tc.tasks { | ||||
|             if let Some(task) = task { | ||||
|                 if task.wait & TaskWait::WaitForTaskExit as u32 != 0 { | ||||
|                     task.wait &= !(TaskWait::WaitForTaskExit as u32); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     let mut next_task = tc.current + 1; | ||||
|     if next_task >= MAX_TASKS { | ||||
|         next_task = 0; | ||||
|  | @ -421,6 +447,19 @@ pub fn context_switch<'a>(tc: &'a mut TrafficControl, current: Task) -> Option<& | |||
| 
 | ||||
|     for _ in 0..(MAX_TASKS + 1) { | ||||
|         if let Some(task) = tc.tasks[next_task].as_ref() { | ||||
|             // check stack pointer and if it's oob
 | ||||
|             #[cfg(feature = "arch_virt")] | ||||
|             { | ||||
|                 if task.sp != 0 { | ||||
|                     if task.trap_frame.regs[2] < task.sp - (task.stack_size_in_blocks * BLOCK_SIZE) { | ||||
|                         let uart = serial_port(); | ||||
|                         if let Some(uart) = uart { | ||||
|                             uart.putstr("stack overflow\n"); | ||||
|                         } | ||||
|                         rough_panic([';', '-', ';']) | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             if task.wait == 0 && { | ||||
|                 let mut waiting = false; | ||||
|                 for v in &task.ackwait { | ||||
|  | @ -464,6 +503,7 @@ pub struct Task { | |||
|     pub want_exit: bool, | ||||
|     /// THE ORIGINAL STACK POINTER THAT THE TASK STARTED WITH
 | ||||
|     pub sp: usize, | ||||
|     pub stack_size_in_blocks: usize, | ||||
|     pub wait: u32, | ||||
|     pub incoming_notifications: [Option<usize>; MAX_TASKS], | ||||
|     pub ackwait: [u8; MAX_TASKS], // 3 = they have not yet received the notification, 1 = they have received the notification, 0 = we know they received the notification, or don't care
 | ||||
|  |  | |||
|  | @ -187,13 +187,16 @@ fn attempt_run_file(env: &Environment<'_>, name: &str) { | |||
|         current_directory_path: CURRENT_DIR_PATH.load(Ordering::Relaxed) as usize, | ||||
|         current_directory_path_len: CURRENT_DIR_PATH_LEN.load(Ordering::Relaxed), | ||||
|     }; | ||||
|     // fixme: turntable task needs to exit, but it owns the environment memory.
 | ||||
|     // fixme: we need to somehow pass the environment to the task, and have it free the memory
 | ||||
| 
 | ||||
|     let mut task_setup = liblbos::TaskSetup { | ||||
|         epc: 0, | ||||
|         stack_block_count: 8, | ||||
|         ddi_first_addr: 0, | ||||
|         ddi_size: 0, | ||||
|         environment: &e as *const _ as usize, | ||||
|         wait_for_task_exit: true, | ||||
|         environment: 0, | ||||
|         wait_for_task_exit: false, | ||||
|     }; | ||||
| 
 | ||||
|     if liblbos::ktask::ktask_loadddifile(buf, size, &mut task_setup as *mut _ as usize) != 0 { | ||||
|  | @ -206,11 +209,11 @@ fn attempt_run_file(env: &Environment<'_>, name: &str) { | |||
| 
 | ||||
|     liblbos::syscalls::create_task(task_setup); | ||||
| 
 | ||||
|     // yeah we're extending its lifetime
 | ||||
|     #[allow(clippy::drop_non_drop)] | ||||
|     drop(e); | ||||
| 
 | ||||
|     println("\ntask exited\n"); | ||||
|     if CURRENT_DIR_PATH.load(Ordering::Relaxed) as usize != 0 { | ||||
|         // free
 | ||||
|         liblbos::syscalls::free_blocks(CURRENT_DIR_PATH.load(Ordering::Relaxed) as usize, CURRENT_DIR_PATH_LEN.load(Ordering::Relaxed).div_ceil(512)); | ||||
|     } | ||||
|     liblbos::syscalls::exit(); | ||||
| } | ||||
| 
 | ||||
| fn execute(cmd: &str, environment: &mut Environment<'_>) { | ||||
|  | @ -233,6 +236,10 @@ fn execute(cmd: &str, environment: &mut Environment<'_>) { | |||
|                 if NO_EXIT.load(Ordering::Relaxed) { | ||||
|                     println("cannot exit as task 1"); | ||||
|                 } else { | ||||
|                     if CURRENT_DIR_PATH.load(Ordering::Relaxed) as usize != 0 { | ||||
|                         // free
 | ||||
|                         liblbos::syscalls::free_blocks(CURRENT_DIR_PATH.load(Ordering::Relaxed) as usize, CURRENT_DIR_PATH_LEN.load(Ordering::Relaxed).div_ceil(512)); | ||||
|                     } | ||||
|                     liblbos::syscalls::exit(); | ||||
|                 } | ||||
|             } | ||||
|  | @ -260,8 +267,7 @@ fn hex(mut n: u8) -> [u8; 2] { | |||
| mod arch; | ||||
| mod terminal; | ||||
| 
 | ||||
| #[unsafe(no_mangle)] | ||||
| extern "C" fn main() { | ||||
| fn main_wrapper() { | ||||
|     let tid = liblbos::syscalls::current_task(); | ||||
|     NO_EXIT.store(tid == 1, Ordering::Relaxed); | ||||
| 
 | ||||
|  | @ -341,3 +347,12 @@ extern "C" fn main() { | |||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[unsafe(no_mangle)] | ||||
| extern "C" fn main() { | ||||
|     main_wrapper(); | ||||
|     if CURRENT_DIR_PATH.load(Ordering::Relaxed) as usize != 0 { | ||||
|         // free
 | ||||
|         liblbos::syscalls::free_blocks(CURRENT_DIR_PATH.load(Ordering::Relaxed) as usize, CURRENT_DIR_PATH_LEN.load(Ordering::Relaxed).div_ceil(512)); | ||||
|     } | ||||
| } | ||||
		Loading…
	
	Add table
		
		Reference in a new issue