Как было сделано у меня (AT91SAM7S32): бутлоадер (написанный на ассемблере, размер ограничен 0x400) при старте копирует себя в ОЗУ, выполняет REMAP, выполняет переход по адресу в ОЗУ
Код
ldr PC, =(0x200000 + continueEntry - 0x100000)
continueEntry
; enable main oscillator and PLL
, настраивает тактирование и прочее, включает PIO контроллер, по состоянию двух пинов решает, пытаться запустить приложение или перейти в ожидание команд через DBGU. В случае попытки запуска бутлоадер проверяет (по фиксированному адресу во флэш) размер и контрольную сумму приложения, если проверка прошла, копирует векторы (из известного места во флэш) в адрес 0x20 (туда ведь уже отмаплено ОЗУ) и делает ldr PC, =0 (переход по вектору сброса). При любой ошибке следует переход на ожидание команд через DBGU). Команд всего 2 - "hello" и передача прошивки. Прошивка передаётся блоками размером со страницу флэша (в данном случае 128 байт), очередной полученный блок бутлоадер записывает во флэш, после чего отправляет подтверждение. После окончания загрузки следует попытка запуска приложения.
Само приложение построено с "дыркой" в начале рамером 0x400 - размер таблицы переходов + слово (размер приложения) + слово (контрольная сумма). При передаче бутлоадеру используется самописная программа, которая загружает бинарник в память, записывает на место размер и контрольную сумму, и потом с адреса 0x400 передаёт всё остальное постранично бутлоадеру. Соответственно при старте приложения тактирование уже настроено, можно заниматься более полезными делами.
На всякий случай начало бутлоадера:
CODE
; exception vectors - начало бутлоадера
exception_block_start
ldr pc, Reset_Addr
ldr pc, Undef_Addr
ldr pc, SWI_Addr
ldr pc, PAbt_Addr
ldr pc, DAbt_Addr
nop
ldr pc, [pc, #-0xF20] ; go to by IRQ vector
ldr pc, [pc, #-0xF20] ; go to by FIQ vector
exception_vectors
; address map for exeption vectors - сюда копируются векторы приложения
Reset_Addr
DCD Reset_Handler
Undef_Addr
DCD Undef_Handler
SWI_Addr
DCD SWI_Handler
PAbt_Addr
DCD PAbt_Handler
DAbt_Addr
DCD DAbt_Handler
exception_block_end
И начало приложения:
CODE
; exception vectors
exVectorsStart
ldr pc, Reset_Addr
ldr pc, Undef_Addr
ldr pc, SWI_Addr
ldr pc, PAbt_Addr
ldr pc, DAbt_Addr
nop
ldr pc, [pc, #-0xF20] ; go to by IRQ vector
ldr pc, [pc, #-0xF20] ; go to by FIQ vector
exVectorsEnd
; место для загрузчика
SPACE (0x400 - (exVectorsEnd - exVectorsStart))
; место для размещения данных загрузчика
SPACE 8
; address map for exeption vectors
exTableStart
Reset_Addr
DCD Reset_Handler
Undef_Addr
DCD Undef_Handler
SWI_Addr
DCD SWI_Handler
PAbt_Addr
DCD PAbt_Handler
DAbt_Addr
DCD DAbt_Handler
exTableEnd