Загрузка программы в параллельную флеш
Система, построенная на базе процессоров «Мультикор», имеет внешнюю энергонезависимую память для загрузки программы. В данном документе описывается загрузка из параллельной флеш-памяти. Документ иллюстрирует создание проекта для загрузки без использования загрузчика, также он описывает работу загрузчика. Поясняется, как создать проект для его работы из флеш-памяти и записать программу во флеш-память.
Работа с флеш-памятью с использованием программы-загрузчика или из флеш-памяти
Существуют два метода работы программы, находящейся во флеш-памяти:
Использование специальной программы-загрузчика
Процессор стартует с адреса 0xBFC0_0000 (вычитывает инструкцию по этому виртуальному адресу и выполняет ее), что соответствует адресу флеш-памяти. Если по этому адресу лежит программа-загрузчик, а далее во флеш-памяти — сама программа для исполнения, то при включении питания загрузчик скопирует всю основную программу в секции ОЗУ (и секции .data и секцию .text), и она будет исполняться уже оттуда.
Программа-загрузчик читает ELF-заголовок файла, находящегося в памяти по указанному в нем (в загрузчике) адресу и копирует секции ELF-объекта по прописанным в заголовке адресам. Рассмотрим пример программы-загрузчика, подробнее по который можно узнать в статье "Работа с параллельной флеш-памятью"
-
Инициализация порта внешней памяти.
Частоты: RISC CPU 250МГц, MPORT 100МГц, DSP 250МГц, частота подается на все внутренние устройства процессора. Вывод CS0 подключен к SDRAM, SDRCON сконфигурирован для SDRAM.
li $30,0xB82F0000
li $5, 0x00941432
sw $5,CR_PLL($30)
li $5,0xFFFFFFFF
sw $5,CLK_EN($30)
li $5,0x3000FC
sw $5,CSCON0($30)
li $5,0x030D0030
sw $5,SDRCON($30)
li $5,0x00F50222
sw $5,SDRTMR($30)
li $5,0x00000001
sw $5,SDRCSR($30) -
Определяем адрес начала стека загрузчика
li $29,StackTopPtr #set stack
-
И начальный адрес основной программы во флеш-памяти.
li $5,ElfObjectPtr #set elf.obj pointer
-
Проверяем на корректность заголовок ELF файла.
loadelf:
move $30,$31
beqz $5,exit
nop
## check ehp->e_magic ##
lw $4,0x00($5)
bne $4,ELF_MAGIC, exit
nop
## check ehp->e_type ##
lh $4,0x10($5)
bne $4,ET_EXEC, exit
nop
## check ehp->e_machine ##
lh $4,0x12($5)
bne $4,EM_MIPS, exit
nop
## check ehp->e_ehsize ##
lh $4,0x28($5)
bne $4,52, exit
nop
## check ehp->e_phentsize ##
lh $4,0x2a($5)
bne $4,32, exit
nop -
Копируем секции программы в ОЗУ. Определяя параметры секций (копируемые/не копируемые, размер) по таблице формата секций copy_section:
lw $4,0xc($8) # a0 <- eshp[i].sh_addr
lw $2,0x10($8)
add $5,$2 # a1 <- ehp + eshp[i].sh_offset
lw $6,0x14($8) # a2 <- eshp[i].sh_size
#srl $6,2
jal wmemcpy
nop
li $5,ElfObjectPtr -
Переходим на точку входа основной программы.
jr $4
nop