From 8b487361b2c4fa332da8e3f270ffcb93b58cd002 Mon Sep 17 00:00:00 2001 From: bunnie Date: Tue, 21 May 2024 15:58:10 +0800 Subject: [PATCH] clean up bzero some errors were made in clearing memory because we weren't using the Rust type system to our advantage. This cleans up the phase 1 loader to use the native types of the block plus the slice length we intend to create to block-zero the correct region size. also simplify mem::size_of to size_of --- loader/src/phase1.rs | 149 ++++++++++++++++++++++++++++++++----------- 1 file changed, 110 insertions(+), 39 deletions(-) diff --git a/loader/src/phase1.rs b/loader/src/phase1.rs index e3fc37b43..7ad070225 100644 --- a/loader/src/phase1.rs +++ b/loader/src/phase1.rs @@ -1,4 +1,4 @@ -use core::{mem, slice}; +use core::{mem::size_of, slice}; #[cfg(feature = "atsama5d27")] pub use crate::platform::atsama5d27::load::InitialProcess; @@ -73,6 +73,76 @@ pub fn phase_1(cfg: &mut BootConfig) { #[cfg(feature = "swap")] allocate_swap(cfg); + // debug addresses of all key cfg fields + #[cfg(feature = "debug-print")] + { + println!("*** CFG debug ***"); + println!(" base_addr: {:x}", cfg.base_addr as usize); + println!( + " regions: {:x} -> {:x}", + cfg.regions.as_ptr() as usize, + cfg.regions.as_ptr() as usize + cfg.regions.len() * size_of::() + ); + println!( + " sram_start: {:x}, sram_end: {:x}", + cfg.sram_start as usize, + cfg.sram_start as usize + cfg.sram_size + ); + println!( + " RPT: {:x} -> {:x}", + cfg.runtime_page_tracker.as_ptr() as usize, + cfg.runtime_page_tracker.as_ptr() as usize + + cfg.runtime_page_tracker.len() * size_of::() + ); + println!( + " XPT: {:x} -> {:x}", + cfg.extra_page_tracker.as_ptr() as usize, + cfg.extra_page_tracker.as_ptr() as usize + cfg.extra_page_tracker.len() * size_of::() + ); + println!( + " processes: {:x} -> {:x}", + cfg.processes.as_ptr() as usize, + cfg.processes.as_ptr() as usize + cfg.processes.len() * size_of::() + ); + #[cfg(feature = "swap")] + { + if let Some(hal) = cfg.swap_hal.as_ref() { + println!( + " (Stack) HAL: {:x} -> {:x}", + hal as *const SwapHal as usize, + hal as *const SwapHal as usize + size_of::() + ); + } else { + println!(" NO SWAP HAL!!!"); + } + if let Some(hal) = cfg.swap_hal.as_ref() { + println!( + " (Stack) HAL decrypt buf: {:x} -> {:x}", + hal.buf_as_ref().as_ptr() as usize, + hal.buf_as_ref().as_ptr() as usize + hal.buf_as_ref().len() * size_of::() + ); + } else { + println!(" NO SWAP HAL!!!"); + } + println!( + " swap_root: {:x} -> {:x}", + cfg.swap_root.as_ptr() as usize, + cfg.swap_root.as_ptr() as usize + cfg.swap_root.len() * size_of::() + ); + } + } + + println!("Runtime Page Tracker: {} bytes", cfg.runtime_page_tracker.len()); + #[cfg(feature = "swap")] + if SDBG { + println!("Occupied RPT entries (at this point, the list should be nil):"); + for (_i, entry) in cfg.runtime_page_tracker.iter().enumerate() { + if entry.raw_vpn() != 0 { + println!(" {:x}: {:x} [{}]", _i, entry.raw_vpn(), entry.timestamp()); + } + } + } + // Additionally, from this point on all allocations come from // their respective processes rather than kernel memory. @@ -114,7 +184,7 @@ pub fn allocate_regions(cfg: &mut BootConfig) { let mut rpt_pages = cfg.sram_size / PAGE_SIZE; // Round the tracker to a multiple of the pointer size, so as to keep memory // operations fast. - rpt_pages = (rpt_pages + mem::size_of::() - 1) & !(mem::size_of::() - 1); + rpt_pages = (rpt_pages + size_of::() - 1) & !(size_of::() - 1); // allocate the RPT #[cfg(not(feature = "swap"))] @@ -137,7 +207,7 @@ pub fn allocate_regions(cfg: &mut BootConfig) { cfg.extra_pages, proposed_alloc, page_aligned_alloc, - mem::size_of::(), + size_of::(), ); } @@ -150,7 +220,10 @@ pub fn allocate_regions(cfg: &mut BootConfig) { } assert!((runtime_page_tracker as usize) < (cfg.sram_start as usize) + cfg.sram_size); unsafe { - bzero(runtime_page_tracker, runtime_page_tracker.add(rpt_pages / mem::size_of::())); + bzero( + runtime_page_tracker as *mut XousAlloc, + (runtime_page_tracker as *mut XousAlloc).add(rpt_pages), + ); } cfg.runtime_page_tracker = @@ -160,7 +233,7 @@ pub fn allocate_regions(cfg: &mut BootConfig) { println!( " -> RPT range: {:x} - {:x}", runtime_page_tracker as usize, - runtime_page_tracker as usize + rpt_pages * core::mem::size_of::() + runtime_page_tracker as usize + rpt_pages * size_of::() ); } @@ -179,22 +252,22 @@ pub fn allocate_regions(cfg: &mut BootConfig) { } // Round the tracker to a multiple of the pointer size, so as to keep memory // operations fast. - xpt_pages = (xpt_pages + mem::size_of::() - 1) & !(mem::size_of::() - 1); + xpt_pages = (xpt_pages + size_of::() - 1) & !(size_of::() - 1); println!( "XPT ALLOC init_size bef: {:x}, ext pages: {:x}, rpt alloc: {:x}", cfg.init_size, cfg.extra_pages, - xpt_pages * mem::size_of::() + xpt_pages * size_of::() ); - cfg.init_size += xpt_pages * mem::size_of::(); + cfg.init_size += xpt_pages * size_of::(); // Clear all memory pages such that they're not owned by anyone let extra_page_tracker = cfg.get_top(); println!("xpt value: {:x}", extra_page_tracker as usize); assert!((extra_page_tracker as usize) < (cfg.sram_start as usize) + cfg.sram_size); unsafe { - bzero(extra_page_tracker, extra_page_tracker.add(xpt_pages / mem::size_of::())); + bzero(extra_page_tracker as *mut XousPid, (extra_page_tracker as *mut XousPid).add(xpt_pages)); } cfg.extra_page_tracker = @@ -204,7 +277,7 @@ pub fn allocate_regions(cfg: &mut BootConfig) { println!( " -> XPT range: {:x} - {:x}", extra_page_tracker as usize, - extra_page_tracker as usize + xpt_pages * core::mem::size_of::() + extra_page_tracker as usize + xpt_pages * size_of::() ); } } @@ -217,7 +290,10 @@ pub fn allocate_processes(cfg: &mut BootConfig) { cfg.init_size += table_size; let processes = cfg.get_top(); unsafe { - bzero(processes, processes.add((table_size / mem::size_of::()) as usize)); + bzero( + processes as *mut InitialProcess, + (processes as *mut InitialProcess).add(process_count as usize), + ); } cfg.processes = unsafe { slice::from_raw_parts_mut(processes as *mut InitialProcess, process_count as usize) }; @@ -251,11 +327,13 @@ pub fn allocate_processes(cfg: &mut BootConfig) { #[cfg(feature = "swap")] pub fn allocate_swap(cfg: &mut BootConfig) { let process_count = cfg.init_process_count + 1; - let swap_pt_size = process_count * mem::size_of::(); + let swap_pt_size = process_count * size_of::(); cfg.init_size += swap_pt_size; cfg.swap_offset += swap_pt_size; let swap_pt_base = cfg.get_top(); - unsafe { bzero(swap_pt_base, swap_pt_base.add(swap_pt_size / mem::size_of::())) } + unsafe { + bzero(swap_pt_base as *mut PageTable, (swap_pt_base as *mut PageTable).add(cfg.swap_root.len())) + } // The page table proper is "unbound": we don't put it in a slice, we simply put references // to each page in cfg.swap_root[]. I wonder if this is UB? for (index, root) in cfg.swap_root.iter_mut().enumerate() { @@ -295,7 +373,7 @@ pub fn copy_args(cfg: &mut BootConfig) { // Merge the args list to target RAM // Reserve space for the primary arg list + swap args - swap's XArg structure (7 words long) - let final_len = cfg.args.size() / core::mem::size_of::() + swap_xarg.data[0] as usize - 7; + let final_len = cfg.args.size() / size_of::() + swap_xarg.data[0] as usize - 7; cfg.init_size += final_len * 4; let runtime_arg_buffer = cfg.get_top(); // places the boot image kernel arguments @@ -309,7 +387,7 @@ pub fn copy_args(cfg: &mut BootConfig) { // untouched data is 0 or something and try an optimization based on that). let merged_arg_slice = unsafe { core::slice::from_raw_parts_mut(runtime_arg_buffer as *mut usize, final_len) }; - let mut arg_index = cfg.args.size() / core::mem::size_of::(); + let mut arg_index = cfg.args.size() / size_of::(); // append the swap arguments, and patch the size field accordingly for a in j { @@ -322,7 +400,7 @@ pub fn copy_args(cfg: &mut BootConfig) { let arg_slice = unsafe { core::slice::from_raw_parts( a.data.as_ptr().sub(2) as *const usize, // backup by 2 to accommodate the tag field - a.size as usize / core::mem::size_of::() + 2, + a.size as usize / size_of::() + 2, ) }; if SDBG { @@ -358,18 +436,12 @@ pub fn copy_args(cfg: &mut BootConfig) { let mut digest = crc16::Digest::new(crc16::X25); // safe because we know the entire region can map into a u8 slice with no UB let xarg_data = unsafe { - core::slice::from_raw_parts( - xarg.data.as_ptr() as *const u8, - xarg.data.len() * core::mem::size_of::(), - ) + core::slice::from_raw_parts(xarg.data.as_ptr() as *const u8, xarg.data.len() * size_of::()) }; digest.write(&xarg_data); // patch the CRC let merged_arg_slice_u8 = unsafe { - core::slice::from_raw_parts_mut( - runtime_arg_buffer as *mut u8, - final_len * core::mem::size_of::(), - ) + core::slice::from_raw_parts_mut(runtime_arg_buffer as *mut u8, final_len * size_of::()) }; merged_arg_slice_u8[4..6].copy_from_slice(&digest.sum16().to_le_bytes()); @@ -377,7 +449,7 @@ pub fn copy_args(cfg: &mut BootConfig) { println!( " -> Patched kernel args range: {:x} - {:x}", runtime_arg_buffer as usize, - runtime_arg_buffer as usize + final_len * mem::size_of::() + runtime_arg_buffer as usize + final_len * size_of::() ); } } @@ -446,8 +518,7 @@ fn copy_processes(cfg: &mut BootConfig) { let inie = MiniElf::new(&tag); let mut src_paddr = - unsafe { cfg.base_addr.add(inie.load_offset as usize / mem::size_of::()) } - as *const u8; + unsafe { cfg.base_addr.add(inie.load_offset as usize / size_of::()) } as *const u8; println!("\n\n{} {} has {} sections", tag_type.to_str(), _pid, inie.sections.len()); println!( @@ -752,7 +823,7 @@ fn copy_processes(cfg: &mut BootConfig) { println!("\n\nKernel top: {:x}, extra_pages: {:x}", top as u32, cfg.extra_pages); unsafe { // Copy the program to the target address, rounding it off to the load size. - let src_addr = cfg.base_addr.add(prog.load_offset as usize / mem::size_of::()); + let src_addr = cfg.base_addr.add(prog.load_offset as usize / size_of::()); println!( " Copying TEXT from {:08x}-{:08x} to {:08x}-{:08x} ({} bytes long)", src_addr as usize, @@ -763,16 +834,16 @@ fn copy_processes(cfg: &mut BootConfig) { ); println!( " Zeroing out TEXT from {:08x}-{:08x}", - top.add(prog.text_size as usize / mem::size_of::()) as usize, - top.add(load_size_rounded as usize / mem::size_of::()) as usize, + top.add(prog.text_size as usize / size_of::()) as usize, + top.add(load_size_rounded as usize / size_of::()) as usize, ); memcpy(top, src_addr, prog.text_size as usize + 1); // Zero out the remaining data. bzero( - top.add(prog.text_size as usize / mem::size_of::()), - top.add(load_size_rounded as usize / mem::size_of::()), + top.add(prog.text_size as usize / size_of::()), + top.add(load_size_rounded as usize / size_of::()), ) }; @@ -786,7 +857,7 @@ fn copy_processes(cfg: &mut BootConfig) { // Copy the program to the target address, rounding it off to the load size. let src_addr = cfg .base_addr - .add((prog.load_offset + prog.text_size + 4) as usize / mem::size_of::() - 1); + .add((prog.load_offset + prog.text_size + 4) as usize / size_of::() - 1); println!( " Copying DATA from {:08x}-{:08x} to {:08x}-{:08x} ({} bytes long)", src_addr as usize, @@ -800,12 +871,12 @@ fn copy_processes(cfg: &mut BootConfig) { // Zero out the remaining data. println!( " Zeroing out DATA from {:08x} - {:08x}", - top.add(prog.data_size as usize / mem::size_of::()) as usize, - top.add(load_size_rounded as usize / mem::size_of::()) as usize + top.add(prog.data_size as usize / size_of::()) as usize, + top.add(load_size_rounded as usize / size_of::()) as usize ); bzero( - top.add(prog.data_size as usize / mem::size_of::()), - top.add(load_size_rounded as usize / mem::size_of::()), + top.add(prog.data_size as usize / size_of::()), + top.add(load_size_rounded as usize / size_of::()), ) } } @@ -821,7 +892,7 @@ where if VDBG { println!( "COPY (align {}): {:08x} - {:08x} {} {:08x} - {:08x}", - mem::size_of::(), + size_of::(), src as usize, src as usize + count, count, @@ -829,5 +900,5 @@ where dest as usize + count ); } - core::ptr::copy_nonoverlapping(src, dest, count / mem::size_of::()); + core::ptr::copy_nonoverlapping(src, dest, count / size_of::()); }