GCCプロジェクトで変数や関数を指定のセクションに配置する方法

お世話になります。
セクションの配置で手こずっており、ご教授頂けると幸いです。

統合開発環境:e2studio 2022-01 (22.1.0)
ツールチェイン:GCC for Renesas RX ver8.3.0.202104

bios.c内で記述している関数を.textから.new_sectionに配置させたく、下記ページを参考にlinker_script.ldを記述しました。
しかし、エラーでビルドできないでいます。何が原因が分かりますでしょうか。

linker_script.ldに追加記述したbios.oのパスを通すのか。その場合、何処に設定する必要があるのか。

はたまた全く見当違いなことなのか…

よろしくお願いいたします。

参考ページ「GCCプロジェクトで変数や関数を指定のセクションに配置する方法」
ja-support.renesas.com/.../19508395

<linker_script.ld>
.text 0xFFE00000 : AT(0xFFE00000)
{
*(.text)
*(.text.*)
*(P)
*(EXCLUDE_FILE(bios.c) .text)
etext = .;
} >ROM



.new_section :
{
bios.o(.text)
} >RAM


<エラー内容>
Extracting support files...
17:17:11 **** プロジェクト linker_script_test に対する構成 HardwareDebug の 逐次ビルド ****
make -j6 all
'rx-elf-gcc -O0 -ffunction-sections -fdata-sections -fdiagnostics-parseable-fixits -Wstack-usage=100 -g2 -mcpu=rx64m -misa=v2 -mlittle-endian-data -o "linker_script_test.elf" ./src/smc_gen/r_pincfg/Pin.o ./src/smc_gen/r_bsp/mcu/rx65n/mcu_clocks.o ./src/smc_gen/r_bsp/mcu/rx65n/mcu_init.o ./src/smc_gen/r_bsp/mcu/rx65n/mcu_interrupts.o ./src/smc_gen/r_bsp/mcu/rx65n/mcu_mapped_interrupts.o ./src/smc_gen/r_bsp/mcu/rx65n/vecttbl.o ./src/smc_gen/r_bsp/mcu/all/dbsct.o ./src/smc_gen/r_bsp/mcu/all/lowlvl.o ./src/smc_gen/r_bsp/mcu/all/lowsrc.o ./src/smc_gen/r_bsp/mcu/all/mcu_locks.o ./src/smc_gen/r_bsp/mcu/all/r_bsp_common.o ./src/smc_gen/r_bsp/mcu/all/r_bsp_cpu.o ./src/smc_gen/r_bsp/mcu/all/r_bsp_interrupts.o ./src/smc_gen/r_bsp/mcu/all/r_bsp_locking.o ./src/smc_gen/r_bsp/mcu/all/r_bsp_mcu_startup.o ./src/smc_gen/r_bsp/mcu/all/r_bsp_software_interrupt.o ./src/smc_gen/r_bsp/mcu/all/r_rx_intrinsic_functions.o ./src/smc_gen/r_bsp/mcu/all/reset_program.o ./src/smc_gen/r_bsp/mcu/all/resetprg.o ./src/smc_gen/r_bsp/mcu/all/sbrk.o ./src/smc_gen/r_bsp/board/generic_rx65n/hwsetup.o ./src/smc_gen/general/r_cg_hardware_setup.o ./src/smc_gen/general/r_smc_cgc.o ./src/smc_gen/general/r_smc_cgc_user.o ./src/smc_gen/general/r_smc_interrupt.o ./src/smc_gen/Config_TMR0_TMR1/Config_TMR0_TMR1.o ./src/smc_gen/Config_TMR0_TMR1/Config_TMR0_TMR1_user.o ./src/smc_gen/Config_PORT/Config_PORT.o ./src/smc_gen/Config_PORT/Config_PORT_user.o ./src/bios.o ./src/confirm.o ./src/linker_script_test.o -T "C:/Users/PC0263u/e2_studio/workspace/linker_script_test/src/linker_script.ld" -Wl,--start-group -lm -lc -lgcc -Wl,--end-group -nostartfiles -Wl,-e_PowerON_Reset -Wl,-M=linker_script_test.map'
rx-elf-gcc @"linker_script_test.elf.in"
c:/programdata/gcc for renesas rx 8.3.0.202104-gnurx-elf/rx-elf/rx-elf/bin/../lib/gcc/rx-elf/8.3.0.202104-GNURX/../../../../rx-elf/bin/ld.exe: cannot find bios.o
collect2.exe: error: ld returned 1 exit status
makefile:98: recipe for target 'linker_script_test.elf' failed
make: *** [linker_script_test.elf] Error 1
"make -j6 all" terminated with exit code 2. Build might be incomplete.

17:17:12 Build Failed. 3 errors, 0 warnings. (took 657ms)

  • mitsuさん、こんにちは。NoMaYと申します。

    'rx-elf-gcc -O0 -ffunction-sections -fdata-sections 略 ./src/bios.o ./src/confirm.o ./src/linker_script_test.o 略
    rx-elf-gcc @"linker_script_test.elf.in"
    c:/programdata/gcc for renesas rx 8.3.0.202104-gnurx-elf/rx-elf/rx-elf/bin/../lib/gcc/rx-elf/8.3.0.202104-GNURX/../../../../rx-elf/bin/ld.exe: cannot find bios.o

     
    すみません、念の為、まず、bios.oが生成されているか、その場所にあるか、確認してみて頂けませんか?

    > はたまた全く見当違いなことなのか…

    確かにFAQには書いてありますが、GCC関連では余り見掛けないやり方のようにも思います。関数ひとつひとつを__attribute__()でセクション指定していくのが良くあるやり方のように思います。

    ちなみに、今回のファイル内の関数丸ごとすべてRAMに配置したいということの目的は何でしょうか?

  • NoMaY様

    お世話になります。

    *.oファイルは下記フォルダ内に生成されていました。(bios.o、confirm.o、linker_script_test.o)

    …workspace\linker_script_test\HardwareDebug\src

    やはり一つ一つ指定していくのがよくあるやり方なのですね…

    目的としては、アプリケーションや機能を変更せず、rx631からrx651へのデバイス置き換えです。

    その中でユーザーブートによるROM書き換えが実装されており、

    ユーザーブート部とコントロール部がROM(一部RAMも)内で分かれてセクション管理されております。

    rx631ではHEW環境で#pragma sectionを使用してセクション管理されているのですが、

    今回のrx651のGCC環境でセクション管理をする方法が無いかと探していた次第です。

    一つ一つ指定していくには多くのファイル、関数・変数になっており、

    ソースファイル単位で指定されているものが多くあった為、一括で指定できるやり方を探しておりました。

  • mitsuさん、こんにちは。NoMaYです。

    置き換え案件でそういう事情なのですね。.o ファイルはあったということですね。私の方でも試してみます。

  • mitsuさん、こんにちは。NoMaYです。

    これは、こうしないといけない、ようです。特にポイントは、赤文字の行を残してはいけない、という点です。これを残しておくと、紫文字の行の効果が無くなります! あと、細かい点は、-ffunction-sectionsを指定した場合はセクション名が単なる.textでは無い点とか、mitsuさんも気にされていたパスの件とか、ですね。[追記] 除外ファイルが複数ある場合にはEXCLUDE_FILE()内で*/bios.oの後ろにスペースで区切って複数並べれば良いと思います。

    [追記その2] 元の行を残してはいけない、という意味ではFAQの記述が分かり難いですね、、、[ここまで追記]

    誤)

        .text 0xFFE00000 : AT(0xFFE00000)
        {
            *(.text)
            *(.text.*)
            *(P)
            *(EXCLUDE_FILE(bios.c) .text)
            etext = .;
        } >ROM
        :
        :
        :
        .new_section :
        {
            bios.o(.text)
        } >RAM

     
    正)

        .text 0xFFE00000: AT(0xFFE00000)
        {
            *(.text)
            *(EXCLUDE_FILE(*/bios.o) .text.*)
            *(P)
            etext = .;
        } > ROM
        :
        :
        :
        .new_section :
        {
            */bios.o(.text.*)
        } > RAM

     
    マップファイル:

    .new_section    0x0000000000000780        0xb load address 0x00000000ffe03c04
     */bios.o(.text.*)
     .text.func_in_bios_dot_c
                    0x0000000000000780        0xb ./src/bios.o
                    0x0000000000000780                func_in_bios_dot_c

     
    ソース bios.c

    extern int func_in_bios_dot_c(void);

    int func_in_bios_dot_c(void)
    {
        return 0;
    }

     

  • NoMaY様

    ご丁寧にありがとうございます。

    無事にセクション配置を変えることができました。

    また、複数のファイルを指定する場合も、*/を頭につけてスペース区切ることで

    配置できることも確認させて頂きました。

    改めまして、ありがとうございました。