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
This commit is contained in:
bunnie 2024-05-21 15:58:10 +08:00
parent f9867bdca5
commit 8b487361b2

View file

@ -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::<MemoryRegionExtra>()
);
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::<XousAlloc>()
);
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::<XousPid>()
);
println!(
" processes: {:x} -> {:x}",
cfg.processes.as_ptr() as usize,
cfg.processes.as_ptr() as usize + cfg.processes.len() * size_of::<InitialProcess>()
);
#[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::<SwapHal>()
);
} 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::<u8>()
);
} 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::<usize>()
);
}
}
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::<usize>() - 1) & !(mem::size_of::<usize>() - 1);
rpt_pages = (rpt_pages + size_of::<usize>() - 1) & !(size_of::<usize>() - 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::<XousAlloc>(),
size_of::<XousAlloc>(),
);
}
@ -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::<usize>()));
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::<XousAlloc>()
runtime_page_tracker as usize + rpt_pages * size_of::<XousAlloc>()
);
}
@ -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::<usize>() - 1) & !(mem::size_of::<usize>() - 1);
xpt_pages = (xpt_pages + size_of::<usize>() - 1) & !(size_of::<usize>() - 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::<XousPid>()
xpt_pages * size_of::<XousPid>()
);
cfg.init_size += xpt_pages * mem::size_of::<XousPid>();
cfg.init_size += xpt_pages * size_of::<XousPid>();
// 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::<usize>()));
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::<XousPid>()
extra_page_tracker as usize + xpt_pages * size_of::<XousPid>()
);
}
}
@ -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::<usize>()) 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::<PageTable>();
let swap_pt_size = process_count * size_of::<PageTable>();
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::<usize>())) }
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::<u32>() + swap_xarg.data[0] as usize - 7;
let final_len = cfg.args.size() / size_of::<u32>() + 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::<u32>();
let mut arg_index = cfg.args.size() / size_of::<u32>();
// 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::<usize>() + 2,
a.size as usize / size_of::<usize>() + 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::<u32>(),
)
core::slice::from_raw_parts(xarg.data.as_ptr() as *const u8, xarg.data.len() * size_of::<u32>())
};
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::<u32>(),
)
core::slice::from_raw_parts_mut(runtime_arg_buffer as *mut u8, final_len * size_of::<u32>())
};
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::<usize>()
runtime_arg_buffer as usize + final_len * size_of::<usize>()
);
}
}
@ -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::<usize>()) }
as *const u8;
unsafe { cfg.base_addr.add(inie.load_offset as usize / size_of::<usize>()) } 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::<usize>());
let src_addr = cfg.base_addr.add(prog.load_offset as usize / size_of::<usize>());
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::<usize>()) as usize,
top.add(load_size_rounded as usize / mem::size_of::<usize>()) as usize,
top.add(prog.text_size as usize / size_of::<usize>()) as usize,
top.add(load_size_rounded as usize / size_of::<usize>()) 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::<usize>()),
top.add(load_size_rounded as usize / mem::size_of::<usize>()),
top.add(prog.text_size as usize / size_of::<usize>()),
top.add(load_size_rounded as usize / size_of::<usize>()),
)
};
@ -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::<usize>() - 1);
.add((prog.load_offset + prog.text_size + 4) as usize / size_of::<usize>() - 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::<usize>()) as usize,
top.add(load_size_rounded as usize / mem::size_of::<usize>()) as usize
top.add(prog.data_size as usize / size_of::<usize>()) as usize,
top.add(load_size_rounded as usize / size_of::<usize>()) as usize
);
bzero(
top.add(prog.data_size as usize / mem::size_of::<usize>()),
top.add(load_size_rounded as usize / mem::size_of::<usize>()),
top.add(prog.data_size as usize / size_of::<usize>()),
top.add(load_size_rounded as usize / size_of::<usize>()),
)
}
}
@ -821,7 +892,7 @@ where
if VDBG {
println!(
"COPY (align {}): {:08x} - {:08x} {} {:08x} - {:08x}",
mem::size_of::<T>(),
size_of::<T>(),
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::<T>());
core::ptr::copy_nonoverlapping(src, dest, count / size_of::<T>());
}