2012-01-22 6 views
6

ロングストーリー。良いリンカースクリプトを作成する方法を学びたいので、プラットフォーム/アーキテクチャー/ベンダーを変更する必要があります。私は何をすべきかを知らずに、再びゼロに固執しません。私は仕事の難しさに関心がありません。それはそれを理解するほどです。リンカースクリプトの作成と検証に関するアドバイス

は、私はそれがあったように、プログラミングのためのベースやスケルトンを作成し、STMの32ビットのCortex-M3チップ上で開発するために、projectの並べ替えを始めました。 jsiei97 STM32F103RB(私はTI Stellaris LM3S828も持っていますが、それはもう一つの問題です)の助けを借りて、ライセンスされたIDEの必要はありません。私は学生なので、ほとんどの学生はそのようなものを買う余裕がありません。

私はODevとEclipseプラグインがあることを理解していますが、さまざまなブログ、Wiki、ドキュメント/マニュアルページを読んでいますが、ほとんどのプロジェクトでは、理由と事柄に関する説明をほとんど知らないリンカスクリプトが定義されている。

私はSTM32のためのarm-none-eabiツールチェーンをコンパイルしましたが、私がハングアップする場所はリンカースクリプトです。 CodeSourceryにも同様に1つ必要です。私はgnuのmanページを読んだ後に、それらを作成する方法とその構文についての基本的な考え方を持っていますが、明白な.text、.bss、.data 。

私はrudimentary versionを作成しましたが、セクション定義を要求するリンクエラーが発生し、それが問題になります。私はそれらを定義する方法を知っていますが、私がやっていることが近いものさえあれば問題を知ることができます。ここで

+0

gnuリンカースクリプトは、非常に痛いです。そして、gcc 3.xから4.xまでの作業はこれまで以上に動作しませんでした。私はいつもあなたの足元から敷物を引き出しても、それがどんなにうまくいくかを考えています。 –

+0

これは当てはまります。私はそれだけを期待することができます。しかし、4.xから5.xまでは、しっかりした作業が可能で、変更ログに従うことが重要です。何か大きな変化が起こるはずです。 – Crewe

答えて

2

はSTM32F105RBの作業リンカスクリプト(R8およびRC用のバージョンもあります)です。

https://github.com/anrope/stm-arp/blob/github/arp.rb.ld(下のテキスト)

私の最高級の頭の推測では、あなたが文句を言わないということです何かを変えなければならない。おそらく、MEMORY {}ステートメントで定義されたリージョンの起源。うまくいけばコメントはあなたに役立つでしょう。

私はこれをGNU/GCCクロスコンパイラで使用しました。コンパイルした後、コードにnmを実行して、セクションが正しいアドレスに配置されていることを確認すると便利です。

編集:

http://sourceware.org/binutils/docs/ld/

とGCCのnmを使用して、標準のリンカスクリプトでクロスコンパイルの出力を調べて: 私は、GNU ldのマニュアルを参照して一緒にこのリンカスクリプトをつなぎ。私は基本的に出力されていたすべてのセクションを特定し、どのセクションが実際に有用であるか、メモリ内でSTM32F105のどこに行くべきかを理解しました。

各セクションの目的をリンカースクリプトにメモしました。

/* 
arp.{r8,rb,rc}.ld : 
These linker scripts (one for each memory density of the stm32f105) are used by 
the linker to arrange program symbols and sections in memory. This is especially 
important for sections like the interrupt vector, which must be placed where the 
processor is hard-coded to look for it. 
*/ 

/*stm32f105 dev board linker script*/ 

/* 
OUTPUT_FORMAT() defines the BFD (binary file descriptor) format 
OUTPUT_FORMAT(default, big, little) 
*/ 
OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") 
/* ENTRY() defines the symbol at which to begin executing code */ 
ENTRY(_start) 
/* tell ld where to look for archive libraries */ 
/*SEARCH_DIR("/home/arp/stm/ctc/arm-eabi/lib")*/ 
/*SEARCH_DIR("/home/arp/stm/ccbuild/method2/install/arm-eabi/lib")*/ 
SEARCH_DIR("/home/arp/stm32dev-root/usrlol/arm-eabi/lib") 

/* 
MEMORY{} defines the memory regions of the target device, 
and gives them an alias for use later in the linker script. 
*/ 

/* stm32f105rb */ 
MEMORY 
{ 
    ram (rwx) : ORIGIN = 0x20000000, LENGTH = 32k 
    flash (rx) : ORIGIN = 0x08000000, LENGTH = 128k 
    option_bytes_rom (rx) : ORIGIN = 0x1FFFF800, LENGTH = 16 
} 

_sheap = _ebss + 4; 
_sstack = _ebss + 4; 
/*placed __stack_base__ trying to figure out 
global variable overwrite issue 
__stack_base__ = _ebss + 4;*/ 

_eheap = ORIGIN(ram) + LENGTH(ram) - 1; 
_estack = ORIGIN(ram) + LENGTH(ram) - 1; 

/* SECTIONS{} defines all the ELF sections we want to create */ 
SECTIONS 
{ 
    /* 
    set . to an initial value (0 here). 
    . (dot) is the location counter. New sections are placed at the 
    location pointed to by the location counter, and the location counter 
    is automatically moved ahead the length of the new section. It is important 
    to maintain alignment (not handled automatically by the location counter). 
    */ 
    . = SEGMENT_START("text-segment", 0); 



    /*isr_vector contains the interrupt vector. 

    isr_vector is read only (could be write too?). 

    isr_vector must appear at start of flash (USR), 
    address 0x0800 0000*/ 
    .isr_vector : 
    { 
     . = ALIGN(4); 
     _sisr_vector = .; 

     *(.isr_vector) 

     _eisr_vector = .; 
    } >flash 

    /*text contains executable code. 

    text is read and execute.*/ 
    .text : 
    { 
     . = ALIGN(4); 
     *(.text) 
     . = ALIGN(4); 
     *(.text.*) 
    } >flash 

    /*init contains constructor functions 
    called before entering main. used by crt (?).*/ 
    .init : 
    { 
     . = ALIGN(4); 
     KEEP(*(.init)) 
    } >flash 

    /*fini contains destructor functions 
    called after leaving main. used by crt (?).*/ 
    .fini : 
    { 
     . = ALIGN(4); 
     KEEP(*(.fini)) 
    } >flash 

    /* rodata contains read only data.*/ 
    .rodata : 
    { 
     . = ALIGN(4); 
     *(.rodata) 

     /* sidata contains the initial values 
     for variables in the data section. 

     sidata is read only.*/ 
     . = ALIGN(4); 
     _sidata = .; 
    } >flash 

    /*data contains all initalized variables. 

    data is read and write. 
    .data (NOLOAD) : AT(_sidata)*/ 
    .data : AT(_sidata) 
    { 
     . = ALIGN(4); 
     _sdata = .; 

     *(.data) 

     _edata = .; 
    } >ram 

    /*bss contains unintialized variables. 

    bss is read and write. 
    .bss (NOLOAD) :*/ 
    .bss : 
    { 
     . = ALIGN(4); 
     _sbss = .; 
     __bss_start__ = .; 

     *(.bss) 
     . = ALIGN(4); 

     /*COMMON is a special section containing 
     uninitialized data. 

     Example: (declared globally) 
     int temp; //this will appear in COMMON */ 
     *(COMMON) 

     _ebss = .; 
     __bss_end__ = .; 
    } >ram AT>flash 

    . = ALIGN(4); 
    end = .; 

     /* remove the debugging information from the standard libraries */ 
    DISCARD : 
    { 
    libc.a (*) 
    libm.a (*) 
    libgcc.a (*) 
    } 

    /* Stabs debugging sections. */ 
    .stab   0 : { *(.stab) } 
    .stabstr  0 : { *(.stabstr) } 
    .stab.excl  0 : { *(.stab.excl) } 
    .stab.exclstr 0 : { *(.stab.exclstr) } 
    .stab.index 0 : { *(.stab.index) } 
    .stab.indexstr 0 : { *(.stab.indexstr) } 
    .comment  0 : { *(.comment) } 
    /* DWARF debug sections. 
     Symbols in the DWARF debugging sections are relative to the beginning 
     of the section so we begin them at 0. */ 
    /* DWARF 1 */ 
    .debug   0 : { *(.debug) } 
    .line   0 : { *(.line) } 
    /* GNU DWARF 1 extensions */ 
    .debug_srcinfo 0 : { *(.debug_srcinfo) } 
    .debug_sfnames 0 : { *(.debug_sfnames) } 
    /* DWARF 1.1 and DWARF 2 */ 
    .debug_aranges 0 : { *(.debug_aranges) } 
    .debug_pubnames 0 : { *(.debug_pubnames) } 
    /* DWARF 2 */ 
    .debug_info  0 : { *(.debug_info .gnu.linkonce.wi.*) } 
    .debug_abbrev 0 : { *(.debug_abbrev) } 
    .debug_line  0 : { *(.debug_line) } 
    .debug_frame 0 : { *(.debug_frame) } 
    .debug_str  0 : { *(.debug_str) } 
    .debug_loc  0 : { *(.debug_loc) } 
    .debug_macinfo 0 : { *(.debug_macinfo) } 
    /* SGI/MIPS DWARF 2 extensions */ 
    .debug_weaknames 0 : { *(.debug_weaknames) } 
    .debug_funcnames 0 : { *(.debug_funcnames) } 
    .debug_typenames 0 : { *(.debug_typenames) } 
    .debug_varnames 0 : { *(.debug_varnames) } 
} 
+0

私は答えとしてリンクを提供するだけで、変化する可能性があるものの、私たちが話している答えに情報を持ち込むことはできないと言われました。指定したファイルをあなたの答えに追加しました。 –

+1

このスクリプトを作成するために必要な情報は、どこから取得しましたか?あなたは**シープ**、** _ sidata **、** _ sstack **が必要であること、そしてそれらに割り当てるべきことをどうお知りましたか?それが私が探している情報のタイプです。 – Crewe

+1

私は私の答えを編集しました。これらの各セクション(およびそれ以上)は、標準のリンカースクリプトを使用してコンパイルされています。スクリプト内のコメントを確認します。 _sheapはヒープの先頭、_sstackはスタックの先頭です。 – anrope

8

私は単純なリンカースクリプトを使用しています。プラットフォーム間で定期的に再利用します。必要に応じていくつかのアドレスを変更してください。

http://github.com/dwelch67/

はgccのサンプルで多くのサンプル数があり、それらのほとんどは、リンカスクリプトを持っています。

MEMORY 
{ 
    rom : ORIGIN = 0x00000000, LENGTH = 0x40000 
    ram : ORIGIN = 0x10000000, LENGTH = 30K 
} 

SECTIONS 
{ 
    .text : { *(.text*) } > rom 
    .bss : { *(.bss*) } > ram 
} 
+3

+1これは簡単です。誰でもこれを読んで理解することができます。非常に多くの人がメモリマップレジスタなどを直接リンカスクリプトに配置しようとしています。すぐにそれが自分自身の人生にかかっています。不快なことは言わないでください。 – Dan

+1

これは少なくともデータセクションではありませんか? (初期化されたグローバルはどこに行くのですか?) – dbrank0

関連する問題