Are the instructions fetched from RAM or ROM in an ARM micro-controller?

ARM cores are actually what is called modified Harvard architecture. In this case, ROM and RAM sit in the same address space, so an ARM processor can execute code out of either or access either as data. In the modified Harvard architecture, the processing core is directly connected to two separate instruction and data caches. This allows for high performance due to being able to access instructions and data simultaneously. At a high level the combined address space makes the whole system act like a Von Neumann architecture.

The structure of the address space is determined by the physical connections between the processing core itself and any memories and peripherals. For the most part the layout of the address space will be fixed with particular ranges corresponding to memory-mapped peripherals, mask ROM, Flash, RAM, etc. However, there may be some ability to remap certain sections of address space or to configure peripherals or external memories to sit in specific regions of the address space.


The ARM architecture is a von Neumann architecture, not a Harvard architecture. That means it uses a unified address space for both instructions and data. Whether any particular address contains RAM or ROM is up to the system designer. Instructions can be fetched from either.


ARM microcontrollers, the newer Cortex-M ones, have modes to operate either from RAM or ROM. Check, for example, BOOT0 and BOOT1 bits in STM32's Reference Manual. This pretty much configures the start address of execution by actually aliasing the actual memory addresses into a fixed memory address segment (0x0000 0000 to 0x0007 FFFF).

The Cortex-M core has four types of "memory": RAM, ROM (flash and System Memory), FSMC and peripheral. RAM is, well, internal static RAM. ROM is internal flash or the unwritable embedded bootloader. FSMC allows using external memory (both RAM and ROM, depending what the external hardware is). Peripheral memory are specific registers that map to peripheral functions, like UARTs, ADCs, etc. The hardware to access them is separate to gain speed (Harvard-style), specially because flash is slower than SRAM.

Yet, all of those are unified in a single address space (Von Neumann-style), which makes access to them simplified from a programmer's perspective. They differ only by their address ranges (implementation-dependent). The BOOT pins allow configuration between three start addresses: one in RAM, one in ROM (read-only bootloader) and another one in ROM (flash). This makes it possible to answer your question as "both". I never tried, but it appears to be possible to jump from one segment to another.

Keep in mind, however, that those memories still cannot be dealt with equally. You can't arbitrarily write to ROM. It's flash, making them rewritable, but you must use a special procedure to write to them (it's usually called something like "using flash as EEPROM" to store program data, or "bootloader" when storing program code, usually at startup).


Curious info:

When one executes from flash (ROM), the instructions are retrieved directly from ROM. There's usually some startup code that copies data from ROM to RAM (initialized global variables, usually stored in the data section). The Reference Manual also carries this info

When booting from SRAM, in the application initialization code, you have to relocate the vector table in SRAM using the NVIC exception table and offset register.

which is usually carried out by the startup code.