From 4ed1a1ca20d11c6bf793621b7219b93ddd881006 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 11 Mar 2026 14:55:32 +0100 Subject: [PATCH] update bootloader code to use `read_volatile` for address 0x0 --- justfile | 10 +++++----- va108xx/bootloader/src/main.rs | 21 ++++----------------- va416xx/bootloader/src/main.rs | 18 ++++-------------- 3 files changed, 13 insertions(+), 36 deletions(-) diff --git a/justfile b/justfile index e133eaf..295fc5d 100644 --- a/justfile +++ b/justfile @@ -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: diff --git a/va108xx/bootloader/src/main.rs b/va108xx/bootloader/src/main.rs index 04f0946..ab91088 100644 --- a/va108xx/bootloader/src/main.rs +++ b/va108xx/bootloader/src/main.rs @@ -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); diff --git a/va416xx/bootloader/src/main.rs b/va416xx/bootloader/src/main.rs index 154db0c..82e747a 100644 --- a/va416xx/bootloader/src/main.rs +++ b/va416xx/bootloader/src/main.rs @@ -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); -- 2.43.0