I recently started learning assembly and came to know about linker scripts and other low-level details of hardware programming. I am also teaching myself computer architecture and somewhere along the line I came to fear that my picture of the memory model might have been wrong all along.
According to what I understand currently, all the code and data resides on the non-volatile memory just after we 'burn' the binary onto a processor - the RAM being volatile contains nothing upon reset. When the program begins 'executing' it does so from the address 0x0000 which is almost always (AFAIK) the lowest address in Flash. So, instructions are latched onto the bus connecting Flash to the CPU core and that is where the actual execution takes place. However, when we talk about the CPU retrieving or storing data from the memory, we're usually talking about RAM - I am aware that we can read/write data from the program memory as well (I've seen this done on AVRs) but is it not as common? Is it because RAM is faster than ROM that we prefer to store data there?
The accepted answer to this question says that most pieces of code execute out of RAM.
Does this mean that the start-up runtime code (which itself executes from Flash) has to copy all the program opcodes from Flash to RAM and somehow maps the addresses in Flash to point to RAM so that the CPU fetches opcodes from there? Is it similar to the process in which we move the .data sections from ROM to RAM on startup?
I can imagine this to be simpler in von Neumann architectures where the program and data memories share a bus but in Harvard architectures wouldn't this mean that all the code and data have to pass through the CPU registers first?
As you can probably guess, I am a little too confused by this whole business. Having always programmed at a higher abstraction level I am easily troubled with such details. Any help is appreciated.