2

codesourcery gnu powerpc eabi lite ツールチェーンを使用してコンパイルし、USB JTAG TAP を使用して powerPC ターゲットにロードする最小限のベア メタル アプリケーションを作成しました。アプリケーションは、ハードウェアの構成と eabi のレジスタのセットアップに使用されるアセンブリ ファイル、無限ループを含む main.c ファイル、リンカー スクリプト、および Makefile から作成されます。

powerpc のスタートアップ コード、eabi のレジスタの初期化、およびリンカー スクリプトを作成するための gnu リンカーに関する多くのドキュメントを見つけたので、詳しく調べてみました。

メインに到達するまで、アプリケーションをコンパイルして実行します。私が抱えている問題は、アセンブリ ルーチンが完了し、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