Я создал минимальное приложение «голое железо», которое я компилирую с помощью набора кодов gnu powerpc eabi lite и загружаю на цель powerPC с помощью USB JTAG TAP.Приложение создается из файла сборки, используемого для настройки оборудования и настройки регистров для eabi, файла main.c, который содержит бесконечный цикл, скрипт компоновщика и файл Makefile.
Я нашел хорошийДокументация по коду запуска для powerpc, инициализации регистра для eabi и компоновщику gnu для создания сценария компоновщика, и я постарался внимательно им следовать.,Проблема, с которой я сталкиваюсь, заключается в том, что после завершения процедур сборки и выполнения rfi я вижу, как ПК переходит в main (), как и ожидалось.Однако выполнение первой инструкции в main (lis r9, 0) приводит к исключению, 0x700 (недопустимая инструкция или исключение fp).
Процедура сборки изначально содержала код для аннулирования данных L1 и кэшей инструкций и отключениязатем они включают только кэш инструкций L1.Подозревая, что часть этого кода была неправильной, я удалил большую ее часть, и у меня был только минимум.
Может ли быть, что я пропустил шаг инициализации среды выполнения C?Есть еще идеи?Заранее благодарим за помощь.
Код сборки теперь состоит только из следующего:
.text
.global resetHandler
.global _start
.global __eabi
.space(0x0100) /* locate start at hreset vector */
_start:
b resetHandler
.space(0x3000) /* locate the remainder past the exception vector space */
resetHandler:
xor r3, r3, r3
/* set SRR0 to main */
addis r3,r0,main@h
ori r3,r3,main@l
mtspr srr0,r3
/* save machine state register to srr1 */
mfmsr r0
mtspr srr1, r0
xor r1, r1, r1
lis r1, _stack_start@h
addi r1, r1, _stack_start@l
bl __eabi
/* place the address of done in the link register */
xor r3, r3, r3
addis r3, 0, done@h
ori r3, r3, done@l
mtlr r3
rfi
__eabi:
addis r13,r0,_SDA_BASE_@h
ori r13,r13,_SDA_BASE_@l
addis r2,r0,_SDA2_BASE_@h
ori r2,r2,_SDA2_BASE_@l
blr
done:
b .
Сценарий компоновщика следующий:
OUTPUT_ARCH(powerpc)
ENTRY(resetHandler)
SEARCH_DIR(.)
MEMORY
{
ram (rwx) : ORIGIN = 0x000000, LENGTH = 1M
}
_STACK_SIZE = 8k;
_HEAP_SIZE = 32k;
SECTIONS
{
.text :
{
*(.text*)
*(.rodata*)
} >ram
.data : ALIGN (8)
{
_final_data_start = .;
*(.data)
_final_data_end = .;
} >ram
.sdata : { *(.sdata) } >ram
.sbss : { *(.sbss) } >ram
.sdata2 : { *(.sdata2) } >ram
.sbss2 : { *(.sbss2) } >ram
.bss : ALIGN (8)
{
_bss = .;
*(.bss*)
. = ALIGN (8);
_ebss = .;
} >ram
.stack :
{
_stack_end = .;
. = . + _STACK_SIZE;
. = ALIGN(16);
__stack = .;
}
.heap :
{
__heap = .;
. = . + _HEAP_SIZE;
. = ALIGN(16);
_heap_end = .;
}
_stack_start = __stack;
_heap_start = __heap;
_SDA2_BASE_ = ADDR(.sdata2);
_SDA_BASE_ = ADDR(.sdata);
}