This is a nice clean routine found in the S1 IS firmware (DIGIC I !). For some reason (like the used slow ARM CPU) they decided to use DMA to copy the "start of data" data into RAM. This happens very early in the boot process, no operating system is present yet. The special 0xc0xxxxxx addresses and their use bear a great resemblance to the later DIGIC equivalents, as documented by the Magic Lantern hackers http://magiclantern.wikia.com/wiki/Register_Map
The code is utterly unoptimized.
sub_FF01017C
MOV R12, SP
STMFD SP!, {R11,R12,LR,PC}
SUB R11, R12, #4
SUB SP, SP, #0x10
STR R0, [R11,#-0x10] ; "start of data"-4
STR R1, [R11,#-0x14] ; 0x1000 (destination)
STR R2, [R11,#-0x18] ; 0x124e7 (length in words)
MOV R3, #0
STR R3, [R11,#-0x1C]
MOV R3, #0xC0000004
ADD R3, R3, #0x400000 ; 0xc0400004: clock selection (speed?)
LDR R2, [R3] ; read...
STR R2, [R11,#-0x1C] ; ...and store current value
MOV R3, #0xC0000004
ADD R3, R3, #0x400000 ; 0xc0400004
LDR R2, [R11,#-0x1C]
ORR R1, R2, #0x2000 ; this additional clock is needed
STR R1, [R3] ; value written back
MOV R3, #0xC0000008
ADD R3, R3, #0x400000 ; 0xc0400008: clock control
LDR R2, [R3]
STR R2, [R11,#-0x1C] ; ...saved
MOV R3, #0xC0000008
ADD R3, R3, #0x400000
LDR R2, [R11,#-0x1C]
ORR R1, R2, #0x1000000 ; dma module 0
STR R1, [R3] ; clock control updated
MOV R3, #0xC0000000
ADD R3, R3, #0xA10000 ; 0xc0a10000: dma1 base reg.
MOV R2, #1
STR R2, [R3] ; dma1 enabled
MOV R3, #0xC0000018
ADD R3, R3, #0xA10000 ; 0xc0a10018: src address
LDR R2, [R11,#-0x10] ; indeed this is the source
STR R2, [R3]
MOV R3, #0xC000001C
ADD R3, R3, #0xA10000 ; 0xc0a1001c: dest. address
LDR R2, [R11,#-0x14] ; destination indeed
STR R2, [R3]
MOV R3, #0xC0000020
ADD R3, R3, #0xA10000 ; 0xc0a10020: transfer count (32bit aligned)
LDR R2, [R11,#-0x18] ; length (given in words, not bytes here)
MOV R1, R2
MOV R2, R1,LSL#2 ; length*4 (count of bytes)
STR R2, [R3]
MOV R3, #0xC0000008
ADD R3, R3, #0xA10000 ; 0xc0a10008: control bits
MOV R2, #1 ; control bit0: start the transfer
STR R2, [R3]
loc_FF010240
B loc_FF010248
B loc_FF010288
loc_FF010248
MOV R3, #0xC0000010
ADD R3, R3, #0xA10000 ; 0xc0a10010, some status
LDR R2, [R3] ; load status
STR R2, [R11,#-0x1C]
LDR R2, [R11,#-0x1C]
AND R3, R2, #1
CMP R3, #0
BEQ loc_FF010270 ; jump if bit0=0
B loc_FF010288 ; jump if bit0=1
B loc_FF010284
loc_FF010270
LDR R2, [R11,#-0x1C] ; status saved previously
AND R3, R2, #2
CMP R3, #0
BEQ loc_FF010284 ; jump if bit1 = 0
B loc_FF010288 ; jump if bit1 = 1 (finished)
loc_FF010284
B loc_FF010240 ; loop back, let's wait
loc_FF010288 ; finished, switch off related hardware
MOV R3, #0xC0000004
ADD R3, R3, #0x400000 ; 0xc0400004
LDR R2, [R3] ; value read
STR R2, [R11,#-0x1C] ; ... and stored
MOV R3, #0xC0000004
ADD R3, R3, #0x400000 ; 0xc0400004
LDR R2, [R11,#-0x1C] ; load previous value
BIC R1, R2, #0x2000 ; clear a bit
STR R1, [R3] ; write it back
MOV R3, #0xC0000008 ; 0xc0400008
ADD R3, R3, #0x400000
LDR R2, [R3] ; value read
STR R2, [R11,#-0x1C] ; ... and stored
MOV R3, #0xC0000008
ADD R3, R3, #0x400000 ; 0xc0400008
LDR R2, [R11,#-0x1C] ; load previous value
BIC R1, R2, #0x1000000 ; clear a bit
STR R1, [R3] ; write it back
LDMDB R11, {R11,SP,PC}
This camera only uses this DMA, maybe there are no more DMA channels in DIGIC I.
On the other hand, on DIGIC II+ p&s models all DMA channels are potentially in use (haven't noticed this before)
typical code snippet: ldr r1, =0xc0a10000 mov r0, #1 str r0, [r1, r4, lsl #16] ; r4 = channel (0..3)