You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
50 lines
1.8 KiB
Rust
50 lines
1.8 KiB
Rust
// SPDX-License-Identifier: MIT OR Apache-2.0
|
|
//
|
|
// Copyright (c) 2018-2020 Andre Richter <andre.o.richter@gmail.com>
|
|
|
|
//! Relocation code.
|
|
|
|
use crate::{bsp, runtime_init};
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
// Public Code
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
/// Relocates the own binary from `bsp::cpu::BOARD_DEFAULT_LOAD_ADDRESS` to the `__binary_start`
|
|
/// address from the linker script.
|
|
///
|
|
/// # Safety
|
|
///
|
|
/// - Only a single core must be active and running this function.
|
|
/// - Function must not use the `bss` section.
|
|
pub unsafe fn relocate_self() -> ! {
|
|
let range = bsp::memory::binary_range_inclusive();
|
|
let mut reloc_destination_addr = *range.start();
|
|
let reloc_end_addr_inclusive = *range.end();
|
|
|
|
// The address of where the previous firmware loaded us.
|
|
let mut src_addr = bsp::memory::board_default_load_addr();
|
|
|
|
// TODO Make it work for the case src_addr > reloc_addr as well.
|
|
let diff = reloc_destination_addr as usize - src_addr as usize;
|
|
|
|
// Copy the whole binary.
|
|
//
|
|
// This is essentially a `memcpy()` optimized for throughput by transferring in chunks of T.
|
|
loop {
|
|
core::ptr::write_volatile(reloc_destination_addr, core::ptr::read_volatile(src_addr));
|
|
reloc_destination_addr = reloc_destination_addr.offset(1);
|
|
src_addr = src_addr.offset(1);
|
|
|
|
if reloc_destination_addr > reloc_end_addr_inclusive {
|
|
break;
|
|
}
|
|
}
|
|
|
|
let relocated_runtime_init_addr = runtime_init::runtime_init as *const () as usize + diff;
|
|
let relocated_runtime_init: fn() -> ! =
|
|
core::mem::transmute(relocated_runtime_init_addr as *const ());
|
|
|
|
relocated_runtime_init()
|
|
}
|