マイコンの基礎固め4

前回(マイコン基礎固め3)の記事で決定した出力セクションの構築するためにリンカスクリプトを作成したので紹介する。
STM32CubeIDEで空のプロジェクトを作ると自動的に作成されるリンカスクリプトをベースにしている。

まずメモリ領域だが、ITCM領域を新たに定義し、さらにRAMとして一括りに定されていたDTCM、SRAM1、SRAM2を分離して定義した。

あとは前回の記事(マイコン基礎固め3)で決定した通りにセクションを割り付けただけである。
特別やったこととしてはセクションの初期化をマイコン起動後に行うためにセクションの始まりと終わりのアドレスをシンボルとして定義したくらいか。

*****************************************************************************
** @attention
**
** <h2><center>© COPYRIGHT(c) 2019 STMicroelectronics</center></h2>
**
** Redistribution and use in source and binary forms, with or without modification,
** are permitted provided that the following conditions are met:
**   1. Redistributions of source code must retain the above copyright notice,
**      this list of conditions and the following disclaimer.
**   2. Redistributions in binary form must reproduce the above copyright notice,
**      this list of conditions and the following disclaimer in the documentation
**      and/or other materials provided with the distribution.
**   3. Neither the name of STMicroelectronics nor the names of its contributors
**      may be used to endorse or promote products derived from this software
**      without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
*****************************************************************************

/* エントリーポイントの設定 */
ENTRY(Reset_Handler)

/* スタックポインタの初期値をSRAM2領域の終わりに設定 */
_estack = ORIGIN(SRAM2) + LENGTH(SRAM2);

_Min_Heap_Size = 0x200;     /* ヒープ領域サイズ  */
_Min_Stack_Size = 0x400;    /* スタック領域サイズ */

/* メモリ定義 */
MEMORY
{
    ITCM    (rwx)   : ORIGIN = 0x00000000,  LENGTH = 16K        /* ここにRAM上で実行する関数を配置する */
    FLASH   (rx)    : ORIGIN = 0x00200000,  LENGTH = 2048K      /* ここに命令や変数の初期値などを配置する */
    DTCM    (rwx)   : ORIGIN = 0x20000000,  LENGTH = 128K       /* ここにスタックや変数、配列などを配置する */
    SRAM1   (rwx)   : ORIGIN = 0x20020000,  LENGTH = 368K       /* ここにスタックや変数、配列などを配置する */
    SRAM2   (rwx)   : ORIGIN = 0x2007C000,  LENGTH = 16K        /* ここにスタックや変数、配列などを配置する */
}

/* セクション定義 */
SECTIONS
{
    /* ".isr_vector"セクションを"FLASH"領域に配置 */
    /* ISRベクタテーブルが配置される */
    .isr_vector :
    {
        . = ALIGN(4);
        KEEP(*(.isr_vector)) /* Startup code */
        . = ALIGN(4);
    } >FLASH

    /* ".textセクション"を"FLASH"領域に配置 */
    .text :
    {
        . = ALIGN(4);
        *(.text)           /* .text sections (code) */
        *(.text*)          /* .text* sections (code) */
        *(.glue_7)         /* glue arm to thumb code */
        *(.glue_7t)        /* glue thumb to arm code */
        *(.eh_frame)

        KEEP (*(.init))
        KEEP (*(.fini))

        . = ALIGN(4);
        _etext = .;        /* define a global symbols at end of code */
    } >FLASH

    /* ".rodata"セクションを"FLASH"領域に配置 */
    .rodata :
    {
        . = ALIGN(4);
        *(.rodata)         /* .rodata sections (constants, strings, etc.) */
        *(.rodata*)        /* .rodata* sections (constants, strings, etc.) */
        . = ALIGN(4);
    } >FLASH

    .ARM.extab :
    {
        . = ALIGN(4);
        *(.ARM.extab* .gnu.linkonce.armextab.*)
        . = ALIGN(4);
    } >FLASH

    .ARM : 
    {
        . = ALIGN(4);
        __exidx_start = .;
        *(.ARM.exidx*)
        __exidx_end = .;
        . = ALIGN(4);
    } >FLASH

    .preinit_array :
    {
        . = ALIGN(4);
        PROVIDE_HIDDEN (__preinit_array_start = .);
        KEEP (*(.preinit_array*))
        PROVIDE_HIDDEN (__preinit_array_end = .);
        . = ALIGN(4);
    } >FLASH

    .init_array :
    {
        . = ALIGN(4);
        PROVIDE_HIDDEN (__init_array_start = .);
        KEEP (*(SORT(.init_array.*)))
        KEEP (*(.init_array*))
        PROVIDE_HIDDEN (__init_array_end = .);
        . = ALIGN(4);
    } >FLASH

    .fini_array :
    {
        . = ALIGN(4);
        PROVIDE_HIDDEN (__fini_array_start = .);
        KEEP (*(SORT(.fini_array.*)))
        KEEP (*(.fini_array*))
        PROVIDE_HIDDEN (__fini_array_end = .);
        . = ALIGN(4);
    } >FLASH

    /* ".data"セクションのLMAを取得 */
    _sidata = LOADADDR(.data);

    /* ".data"セクションの初期値を"FLASH"領域に配置し"DTCM"領域も確保する */
    .data :
    {
        . = ALIGN(4);
        _sdata = .;        /* create a global symbol at data start */
        *(.data)           /* .data sections */
        *(.data*)          /* .data* sections */

        . = ALIGN(4);
        _edata = .;        /* define a global symbol at data end */

    } >DTCM AT> FLASH

    /* ".bss"セクションを"DTCM"領域に配置 */
    . = ALIGN(4);
    .bss :
    {
        /* This is used by the startup in order to initialize the .bss section */
        _sbss = .;         /* define a global symbol at bss start */
        __bss_start__ = _sbss;
        *(.bss)
        *(.bss*)
        *(COMMON)

        . = ALIGN(4);
        _ebss = .;         /* define a global symbol at bss end */
        __bss_end__ = _ebss;
    } >DTCM
    
    /* User_heap_stack section, used to check that there is enough "RAM" Ram  type memory left */
    ._user_heap_stack :
    {
        . = ALIGN(8);
        PROVIDE ( end = . );
        PROVIDE ( _end = . );
        . = . + _Min_Heap_Size;
        . = . + _Min_Stack_Size;
        . = ALIGN(8);
    } >DTCM
    
    /* .ramfuncセクションのLMAを取得 */
    _siramfunc = LOADADDR(.ramfunc);
    
    /* ".ramfunc"セクションを"FLASH"領域に配置し"ITCM"領域も確保する */
    .ramfunc :
    {
        . = ALIGN(4);
        _sramfunc = .;
        *(.ramfunc)
        *(.ramfunc*)
        . = ALIGN(4);
        _eramfunc = .;
    } >ITCM AT> FLASH
    
    /* ".bss_sram1"セクションを"SRAM1"領域に配置 */
    .bss_sram1 :
    {
        . = ALIGN(4);
        _sbss_sram1 = .;
        *(.bss_sram1)
        *(.bss_sram1*)
        . = ALIGN(4);
        _ebss_sram1 = .;
    } >SRAM1
    
    /* ".bss_sram2"セクションを"SRAM2"領域に配置 */
    .bss_sram2 :
    {
        . = ALIGN(4);
        _sbss_sram2 = .;
        *(.bss_sram2)
        *(.bss_sram2*)
        . = ALIGN(4);
        _ebss_sram2 = .;
    } >SRAM2

    /* Remove information from the compiler libraries */
    /DISCARD/ :
    {
        libc.a ( * )
        libm.a ( * )
        libgcc.a ( * )
    }

    .ARM.attributes 0 : { *(.ARM.attributes) }
}