vexpress-a9 board maps both RAM and flash at address 0
The vexpress-a9 board has a bug where it maps both a RAM MemoryRegion and a flash MemoryRegion to address 0. You can see this in the "info mtree" output:
address-space: memory
0000000000000000-ffffffffffffffff (prio 0, i/o): system
0000000000000000-0000000003ffffff (prio 0, romd): alias vexpress.flashalias @vexpress.flash0 0000000000000000-0000000003ffffff
0000000000000000-0000000003ffffff (prio 0, ram): alias vexpress.lowmem @vexpress.highmem 0000000000000000-0000000003ffffff
0000000010000000-0000000010000fff (prio 0, i/o): arm-sysctl
0000000010004000-0000000010004fff (prio 0, i/o): pl041
(etc)
As it happens, the flash "wins" so the RAM mapping is useless.
In real hardware, this low part of memory is remappable, both at runtime by the guest writing to a control register, and configurably as to what you get out of reset -- you can have the first flash device, or the second, or the DDR2 RAM, or the external AXI bus (which for QEMU means "nothing there"). In an ideal world we would support that remapping both at runtime and via a machine property to select the out-of-reset behaviour. In a less ideal world we should at least (a) document that what you get is always the first flash bank and (b) avoid that has-no-effect mapping of the RAM underneath the flash.
I think the double-mapping happened as a result of commit 6ec1588e in 2014, which changed "we always map the RAM to the low addresses" to "we always map flash in the low addresses" but forgot to stop mapping the RAM.