views:

139

answers:

4

Dear Pundits,

I have basic doubt regarding executable stored in ROM.

As I know the executable with text and RO attributes is stored in ROM. Question is as ROM is for Read Only Memory, what happens if there is situation where the code needs to write into memory?

I am not able to conjure up any example to cite here (probably I am ignorant of such situation or I am missing out basic stuff ;) but any light on this topic can greatly help me to understand! :)

Last off - 1. Is there any such situation? 2. In such a case is copying the code from ROM to RAM is the answer?

Answer with some example can greatly help..

Many thanks in advance!

/MS

+2  A: 

Normally only program code, constants and initialisation data are stored in ROM. A separate memory area in RAM is used for stack, heap, etc.

Paul R
Hi Paul,I know we configure the stack, heap, data, RW sections to suitable RAM location, but my doubt is what if the code section (that is in ROM) needs to write into memory? (which happens to be in ROM itself!)Does the linker generate code section with read/write attributes and finally it resides into RAM? But all we do is flash the executable into ROM, so how does this transfer to RAM happens?Why do we need RAM then, "where code is copied from ROM into RAM and then executed"? (it can be straightforward from ROM right?Thanks for your answer.. :)Best regards..
MS
In most operating systems code segments are read-only, even if they are resident in RAM. This makes for more robust programs and fewer security issues. So the fact that your code is in ROM really makes no difference - you should never normally need to write to this segment. If you need to use self-modifying code or other such hackery then you will have to do this in RAM and then possibly mark the page as executable (OS-dependent).
Paul R
+3  A: 

Read-only memory is read only because of hardware restrictions. The program might be in an EEPROM, flash memory protected from writes, a CD-ROM, or anything where the hardware physically disallows writing. If software writes to ROM, the hardware is incapable of changing the stored data, so nothing happens.

So if a software program in ROM wants to write to memory, it writes to RAM. That's the only option. If a program is running from ROM and wants to change itself, it can't because it can't write to ROM. But yes, the program can run from RAM.

In fact, running from ROM is rare except in the smallest embedded systems. Operating systems copy executable code from ROM to RAM before running it. Sometimes code is compressed in ROM and must be decompressed into RAM before running. If RAM is full, the operating system uses paging to manage it. The reason running from ROM is so rare is because ROM is slower than RAM and sometimes code needs to be changed by the loader before running.

Note that if you have code that modifies itself, you really have to know your system. Many systems use data-execution prevention (DEP). Executable code goes in read+execute areas of RAM. Data goes in read+write areas. So on these systems, code can never change itself in RAM.

indiv
MS
@MS: The reason the current system works so well is because executable code is very small compared to data. You do spend twice, but code can be shared via libraries. And even complex programs tend to be smaller than a high-resolution jpeg image. But fast, cheap persistent RAM would be nice technology to have, for sure. Speed is important in general-purpose PCs, which is why there are often multi-tiered caching schemes: hard drive cached to flash cached to RAM cached to processor L1 and L2. In systems tailored to a specific use, executing from flash might be fast enough.
indiv
Thanks Indiv! I am wondering now what goes into ROM when we flash the executable? what happens to the data that it needs when read/write happens?If only the executable (code) that we are flashing into ROM then how is the memory map setup for code that is in ROM and data that is in RAM during execution?
MS
+2  A: 

There are few legitimate reasons why you would want to modify the code section at runtime. The compiler itself will not generate code that requires that.

Your linker will have an option to generate a MAP file. This will tell you where all memory objects are located.

The linker chooses where to locate based on a linker script (which you can customise to organise memory as you require). Typically on a FLASH based microcontroller code and constant data will be placed in ROM. Also placed in ROM are the initialisation data for non-zero initialised static data, this is copied to RAM before main() is called. Zero initialised static data is simply cleared to zero before main().

It is possible to arrange for the linker to locate some or all of the code in ROM and have the run-time start-up code copy it to RAM in the same way as the non-zero static data, but the code must either be relocatable or be located to RAM in the first instance, you cannot usually just copy code intended to run from ROM to RAM and expect it to run since it may have absolute address references in it (unless perhaps your target has an MMU and can remap the address space). Locating in RAM on micro-controllers is normally done to increase execution speed since RAM is typically faster than FLASH when high clock speeds are used, producing fewer or zero wait states. It may also be used when code is loaded at runtime from a filesystem rather than stored in ROM. Even when loaded into RAM, if the processor has an MMU it is likely that the code section in RAM section will be marked read-only.

Clifford
@Clifford: Thank you! I am able to put it all together now. :)
MS
A: 

Harvard architecture microcontrollers

Many small microcontrollers (Microchip PIC, Atmel AVR, Intel 8051, Cypress PSoC, etc.) have a Harvard architecture. They can only execute code from the program memory (flash or ROM). It's possible to copy any byte from program memory to RAM. However, (2) copying executable instructions from ROM to to RAM is not the answer -- with these small microcontrollers, the program counter always refers to some address in the program memory. It's not possible to execute code in RAM.

Copying data from ROM to RAM is pretty common. When power is first applied, a typical firmware application zeros all the RAM and then copies the initial values of non-const global and static variables out of ROM into RAM just before main() starts. Whenever the application needs to push a fixed string out the serial port, it reads that string out of ROM.

With early versions of these microcontrollers, an external "device programmer" connected to the microcontroller is the only way change the program. In normal operation, the device was nowhere near a "device programmer". If the software running on the microcontroller needed to write to program memory ROM -- sorry, too bad -- it was impossible. Many embedded systems had non-volatile EEPROM that the code could write to -- but this was only for storing data values. The microcontroller could only execute code in the program ROM, not the EEPROM or RAM. People did may wonderful things with these microcontrollers, including BASIC interpreters and bytecode Forth interpreters. So apparently (1) code never needs to write to program memory.

With a few recent "self-programming" microcontrollers (from Atmel, Microchip, Cypress, etc.), there's special hardware on the chip that allows software running on the microcontroller to erase and re-program blocks of its own program memory flash. Some few applications use this "self-programming" feature to read and write data to "extra" flash blocks -- data that is never executed, so it doesn't count as self-modifying code -- but this isn't doing anything you couldn't do with a bigger EEPROM. So far I have only seen two kinds of software running on Harvard-architecture microcontrollers that write new executable software to its own program Flash: bootloaders and Forth compilers.

When the Arduino bootloader (bootstrap loader) runs and detects that a new application firmware image is available, it downloads the new application firmware (into RAM), and writes it to Flash. The next time you turn on the system it's now running shiny new version 16.98 application firmware rather than clunky old version 16.97 application firmware. (The Flash blocks containing the bootloader itself, of course, are left unchanged). This would be impossible without the "self-programming" feature of writing to program memory.

Some Forth implementations run on a small microcontroller, compiling new executable code and using the "self-programming" feature to store it in program Flash -- a process somewhat analogous to the JVM's "just-in-time" compiling. (All other languages seem to require a compiler far too large and complicated to run on a small microcontroller, and therefore have a edit-compile-download-run cycle that takes much more wall clock time).

David Cary