2

我创建了一个最小的裸机应用程序,我正在使用 codesourcery gnu powerpc eabi lite 工具链编译它,并使用 USB JTAG TAP 加载到 powerPC 目标上。该应用程序是从一个用于配置硬件和设置 eabi 寄存器的程序集文件、一个包含无限循环的 main.c 文件、一个链接描述文件和一个 Makefile 文件创建的。

我找到了大量关于 powerpc 的启动代码、eabi 的寄存器初始化以及用于创建链接器脚本的 gnu 链接器的文档,并试图密切关注它。

我让应用程序编译并运行,直到它到达 main。我遇到的问题是,当组装例程完成并执行 rfi 时,我看到 PC 转换为 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);
}
4

0 回答 0