update bootloader code to use read_volatile for address 0x0 #15

Merged
muellerr merged 1 commits from bootloader-tweak into main 2026-03-12 18:35:09 +01:00
3 changed files with 13 additions and 36 deletions
+5 -5
View File
@@ -1,16 +1,16 @@
all: check \
build \
check-fmt \
clippy-all \
docs-all
clippy \
docs
check: check-va108xx check-va416xx
build: build-va108xx build-va416xx
check-fmt: check-fmt-va108xx check-fmt-va416xx
fmt: fmt-va108xx fmt-va416xx fmt-shared-hal
clippy-all: clippy-va108xx clippy-va416xx clippy-shared-hal
docs-all: docs-va108xx docs-va416xx docs-shared-hal
clean-all: clean-va108xx clean-va416xx
clippy: clippy-va108xx clippy-va416xx clippy-shared-hal
docs: docs-va108xx docs-va416xx docs-shared-hal
clean: clean-va108xx clean-va416xx
[working-directory: 'va108xx']
check-va108xx:
+4 -17
View File
@@ -110,8 +110,8 @@ fn main() -> ! {
let mut nvm = M95M01::new(dp.spic, clk_config);
if FLASH_SELF {
let mut first_four_bytes: [u8; 4] = [0; 4];
read_four_bytes_at_addr_zero(&mut first_four_bytes);
#[allow(clippy::zero_ptr)]
let first_four_bytes = unsafe { core::ptr::read_volatile(0x0 as *const u32) }.to_ne_bytes();
let bootloader_data = {
unsafe {
&*core::ptr::slice_from_raw_parts(
@@ -180,8 +180,8 @@ fn check_own_crc(
// I'd prefer to use [core::slice::from_raw_parts], but that is problematic
// because the address of the bootloader is 0x0, so the NULL check fails and the functions
// panics.
let mut first_four_bytes: [u8; 4] = [0; 4];
read_four_bytes_at_addr_zero(&mut first_four_bytes);
#[allow(clippy::zero_ptr)]
let first_four_bytes = unsafe { core::ptr::read_volatile(0x0 as *const u32) }.to_ne_bytes();
let mut digest = CRC_ALGO.digest();
digest.update(&first_four_bytes);
digest.update(unsafe {
@@ -214,19 +214,6 @@ fn check_own_crc(
}
}
// Reading from address 0x0 is problematic in Rust.
// See https://users.rust-lang.org/t/reading-from-physical-address-0x0/117408/5.
// This solution falls back to assembler to deal with this.
fn read_four_bytes_at_addr_zero(buf: &mut [u8; 4]) {
unsafe {
core::arch::asm!(
"ldr r0, [{0}]", // Load 4 bytes from src into r0 register
"str r0, [{1}]", // Store r0 register into first_four_bytes
in(reg) BOOTLOADER_START_ADDR as *const u8, // Input: src pointer (0x0)
in(reg) buf as *mut [u8; 4], // Input: destination pointer
);
}
}
fn check_app_crc(app_sel: AppSel) -> bool {
if DEBUG_PRINTOUTS && DEFMT_PRINTOUT {
defmt::info!("Checking image {:?}", app_sel);
+4 -14
View File
@@ -115,8 +115,8 @@ fn main() -> ! {
let nvm = Nvm::new(dp.spi3, &clocks);
if FLASH_SELF {
let mut first_four_bytes: [u8; 4] = [0; 4];
read_four_bytes_at_addr_zero(&mut first_four_bytes);
#[allow(clippy::zero_ptr)]
let first_four_bytes = unsafe { core::ptr::read_volatile(0x0 as *const u32) }.to_ne_bytes();
let bootloader_data = {
unsafe {
&*core::ptr::slice_from_raw_parts(
@@ -177,8 +177,8 @@ fn check_own_crc(wdt: &OptWdt, nvm: &Nvm, cp: &cortex_m::Peripherals) {
// I'd prefer to use [core::slice::from_raw_parts], but that is problematic
// because the address of the bootloader is 0x0, so the NULL check fails and the functions
// panics.
let mut first_four_bytes: [u8; 4] = [0; 4];
read_four_bytes_at_addr_zero(&mut first_four_bytes);
#[allow(clippy::zero_ptr)]
let first_four_bytes = unsafe { core::ptr::read_volatile(0x0 as *const u32) }.to_ne_bytes();
let mut digest = CRC_ALGO.digest();
digest.update(&first_four_bytes);
digest.update(unsafe {
@@ -212,16 +212,6 @@ fn check_own_crc(wdt: &OptWdt, nvm: &Nvm, cp: &cortex_m::Peripherals) {
}
}
fn read_four_bytes_at_addr_zero(buf: &mut [u8; 4]) {
unsafe {
core::arch::asm!(
"ldr r0, [{0}]", // Load 4 bytes from src into r0 register
"str r0, [{1}]", // Store r0 register into first_four_bytes
in(reg) BOOTLOADER_START_ADDR as *const u8, // Input: src pointer (0x0)
in(reg) buf as *mut [u8; 4], // Input: destination pointer
);
}
}
fn check_app_crc(app_sel: AppSel, wdt: &OptWdt) -> bool {
if DEBUG_PRINTOUTS && DEFMT_PRINTOUTS {
defmt::info!("Checking image {:?}", app_sel);