Skip to content

OpenServoCore/memory-layout-ch32

Repository files navigation

memory-layout-ch32

Demo for ch32-rs/ch32-data#26 — using LMA/VMA linker separation to represent CH32's dual flash addresses:

  • VMA = 0x0000_0000 (CODE) — execution address
  • LMA = 0x0800_0000 (FLASH) — programming address

See memory.x and link.x for the implementation. Sections use >CODE AT>FLASH.

Build & Flash

cargo build

rust-objcopy -O binary \
  --only-section .vector_table \
  --only-section .text \
  --only-section .rodata \
  --only-section .data \
  target/riscv32ec-unknown-none-elf/debug/memory-layout-ch32 \
  target/riscv32ec-unknown-none-elf/debug/firmware.bin

wlink flash --chip CH32V003 target/riscv32ec-unknown-none-elf/debug/firmware.bin

probe-rs attach --chip CH32V003 target/riscv32ec-unknown-none-elf/debug/memory-layout-ch32

Notes

probe-rs

probe-rs won't be able to flash because ch32-rs/flash-algorithms expects 0x0000_0000 and internally translates to 0x0800_0000.

.uninit sections

Crates like defmt-rtt place buffers in .uninit.* sections. Without explicit (NOLOAD) placement, these get an LMA assigned, causing wlink to see loadable segments spanning flash to RAM (~384MB) and fail. probe-rs silently ignores them. This is a pre-existing issue unrelated to this experiment, however.

The objcopy --only-section approach above avoids this.

Alternatively, link.x could include:

.uninit (NOLOAD) : ALIGN(4)
{
    *(.uninit .uninit.*);
} >RAM

This will guard all .uninit sections, and I think probably appropriate to be included in link.x, but this is a separate issue...

About

A test for ch32 LMA/VMA separation

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors