The ARM development board that I use has 1Mx16 of flash on board. In order to program the flash a program was required that would write a given file into the flash. Due to the way that the ATMEL At91C series function this actually means that 2 programs are required, the first runs from the internal RAM of the processor whilst the second needs to run in the external RAM on the board. The reason for 2 programs is very simple. The first, running from internal RAM, is used when the flash has no code in it or the code within the flash deos not map the external SRAM into the memory map.The second program is required when the external RAM has been mapped into the processor memory map. First a bit of background on the ATMEL ARM processor.
The ATMEL ARM processor comes with some internal RAM and has a number of programmable chip select lines that can be programmed to provide a suitable memory map for the external devices. Generally speaking the program memory (FLASH or EPROM) is connected to chip select 0 and at powerup this is where the program counter is initialised to, all the other chip selects are disabled at this point, the internal SRAM is enabled at a set address.. Thus the program starts running. The first thing the program must do is re-program the memory map and switch in any other devices being used. When the memory is re-mapped the internal SRAM is always mapped to the start of the address space where the chip select 0 was at power up.
If the program memory is blank, i.e. and erased flash chip then the processor will create an exception and run the exception handler. Of course, the flash is empty so the exception handler is not there and so the processor will sit doing nothing. By using the JTAG debug port a program can be introduced into the internal SRAM and run from here. This can only be done by the JTAG port. The internal SRAM always appears at the same address at reset until it is re-mapped to the start of the address space. To re-map the chip selects the chip select registers need to be programmed and then the re-map register is triggered to make the changes happen. Note that the remapper program has to ensure that the program counter gets filled with the address that the program will appear at after the re-mapping process just before the mapping is triggered. Thankfully due to the pipelining of the processor this is resonably easy.
The flash programmer detailed here has the same code but is linked to run at 2 different addresses. The first is in the internal SRAM so that the flash can be programmed initially, whilst the second runs fromthe external SRAM. The code to be programmed into the flash is stored in a byte array within the program so there is a special program that takes the code to be programmed and turns it into an array in a special file that is then linked to the flash programmer. I have tested this with a very small proram that merely re-maps the memory of the device and sets up the chip select outputs. The program to be placed into the flash has to be built and then turned into a binary file using objcopy. This file is then run through a program called gen_progfile to generate the byte array source file that is linked into the flash programmer. The main makefile shows an example of this in the section building the boot.bin file, also shown below.
$(CC) -g -c boot.s
arm-elf-ld -Ttext 0x01000000 -e 0x01000000 -o boot.elf boot.o
arm-elf-objcopy -S -O binary boot.elf boot.bin
./gen_progfile boot.bin prog_array.c
The output file is called prog_array.c and this contains the byte array for the programmer. The two files generated by running the comand 'make all' are called prog_boot.bin ( the version for running from the internal non-mapped SRAM) and prog.bin (the version for running from the external RAM mapped at address 0x2000000).
Future versions of this program could be made to program only some sectors of the flash, so that say a boot sector would be left alone and then the rest of the flash could be used as program storage that the program in the boot sector will load and run if it exists.