This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] RTOS/AM3357:GCC 编译中的堆配置

Guru**** 2585275 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/630038/rtos-am3357-heap-configuration-in-gcc-build

器件型号:AM3357
Thread 中讨论的其他器件:SYSBIOS

工具/软件:TI-RTOS

您好!

我使用用于 Sitara 的 SYBIOS 的 Linux/gcc 编译工程。
最近 、我不得不将堆大小增加到24MB、并注意到堆区域包含在二进制文件中、因此也增长到了24MB 以上。

我使用的工具链:arm-none-eabi-gcc (4.8.4-1+11-1) 4.8.4 20141219 (发布)

这是我的堆配置:

VAR mainHeap = HeapMem.create()
mainHeap.size = 25165824;
mainHeap.sectionName =".biosheap";
Memory.defaultHeapInstance = mainHeap;

Program.sectMap[".c_int00"]= new Program.SectionSpec ();
Program.sectMap[".c_int00"].loadAddress = 0x8000000;
Program.sectMap[".c_int00"].runAddress = 0x8000000;

Program.sectMap[".biosheap"]= new Program.SectionSpec ();
Program.sectMap[".biosheap"].runSegment ="DDR2" 
Program.sectMap[".biosheap"].type ="空载";


它会生成 linker.cmd 段:

biosheap (NoLoad):{*(.biosheap)}> DDR2 


objdump 显示:

尺寸 VMA LMA 文件离开 Algn
.biosheap 01800000 80027040 80027040 00037040 2** 3.
ALloc
.bss 0002f748 81863930 81863930 0187392c 2**3.
分配

尺寸输出:
 文本        数据    BSS                  十进制                 十六进制
 231373  44892 25507656       25783921       1896e71


得到的二进制大小:25573676

看起来、段类型"NoLoad"被忽略。 将其更改为"DSECT"也不起作用。

有人可以帮助我解决这个问题吗?

提前感谢!

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    RTOS 团队已收到通知。 他们将在这里作出回应。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您似乎遇到了此处讨论的同一问题:
    e2e.ti.com/.../604616

    您可以尝试我的建议或 Robert (线程发起人)对该线程的变通办法。

    此致、
    Rahul
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    此帖子中的解决方案与.cfg 文件几乎相同、不同之处在于没有"NOINIT"堆段类型、而是有"NoLoad"。

    我明白、它应该在 gcc 上运行良好、但它不是。 解决方法也没有帮助。 它导致了堆栈段而不是专用堆段的扩展、并且这个大堆栈段不会被 objcopy 删除、 即使是使用 "-remove-section .stack"参数也是如此。

    在开始此线程之前、我还尝试使用 objcopy 以与此变通办法相同的方式删除.biosheap 段、但失败了。

    似乎有些东西阻止 objcopy 删除包含堆的段。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您能否尝试以下操作:

    Program.sectionsExclude =".stack"
    
    Program.sectionsExclude =".heap" 

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我找到了这种行为的原因和解决方案。 很难注意到、因为 在单个 objcopy 调用中、我 删除了堆段并将 elf 转换为二进制文件。

    当我将它拆分为2个步骤时、我注意到堆段已被删除。 objcopy 工作正常、但二进制大小仍然很大、因为 它 仍然包含 已删除的段。  

    cfg 文件中的段配置如下所示:

    Program.sectMap[".c_int00"]= new Program.SectionSpec ();
    Program.sectMap[".c_int00"].loadAddress = 0x80000000;
    Program.sectMap[".c_int00"].runAddress = 0x80000000;
    Program.sectMap[".nonCachedRAM"]= new Program.SectionSpec ();
    Program.sectMap[".nonCachedRAM"].loadSegment ="OCMC_SRAM";
    
    Program.sectMap[".xAltera"]= new Program.SectionSpec ();
    Program.sectMap[".xAltera"].loadSegment
    
    
    
    Program.sectMap[".stack"].loadSegment
    
    
    
    
    Program.sectMap[".neardata"]="Altera_MEM";Program.sectMap[".xAltera"].type ="NoLoad";Program.sectMap[".stack"]= new Program.SectionSpec (Program.sectMap[".rodata"]
    Program.sectMap[".neardata"].loadSegment);Program.sectMap[".rodata"].loadSegment ="New Program.SectionSpec (=);"Program.DDR2 == New Program.Edition"(= New Program.Program.Spec ();"DDR2 == New Program.Edition"()
    
    Program.sectMap[".biosheap"]= new Program.SectionSpec ();
    Program.sectMap[".biosheap"].loadSegment ="DDR2";
    Program.sectMap[".biosheap"].type ="NoLoad";
    
    
    Program.sectMap["ti.sysbios.family.arm.a8.mmuTableSection"]= new Program.SectionSpec ();
    Program.sectMap["ti.sysbios.family.arm.a8.mmuTableSection"].loadSegment ="SRAM_HI";
    Program.sectMap["ti.sysbios.family.arm.a8.mmuTableSection"].type ="NoLoad";
    

    
    

    这导致了以下 elf 段:

    IDX 名称 尺寸 VMA LMA Algn
    0 .c_int00文件 000000b4 80000000 80000000 00010000 2**2.
    内容、ALLOC、load、readonly、code
    1 .stack 00020000 800000b8 800000b8 000100b4 2**3.
    Alloc
    2.rodata 00006e39 800200b8 800200b8 000300b8 2**3.
    内容、ALLOC、load、readonly、data
    3 .vectors 00000040 80027000 80027000 00037000 2** 10.
    内容、ALLOC、load、readonly、data
    4 .biosheap 01800000 80027040 80027040 00037040 2** 3.
    Alloc
    5 ti.sysbios.family.arm.a8.mutableSection 00004000 402f4000 402f4000 00004000 2**14
    Alloc
    6 XDC.meta 000000e2 81827040 81827040 0187392c 2**2.
    内容、只读
    7 .text 00031898 81827130 81827130 01837130 2** 4.
    目录、ALLOC、load、readonly、code
    8 .arm.exidx 00000008 818589c8 818589c8 018689c8 2**2
    内容、ALLOC、load、readonly、data
    9 .data 0000af5c 818589d0 818589d0 018689d0 2**2
    内容、ALLOC、LOAD、DATA
    10 .bss 0002f748 81863930 81863930 0187392c 2**3.
    Alloc
    11注释 0000007f 00000000 00000000 01873a0e 2**0
    内容、readonly
    12 .arm.attributes 0000003b 00000000 00000000 01873a8d 2**0
    内容、只读
    

    您可以注意到、.text 段位于.c_int00开头的偏移量0x01827130处、该偏移量也是文本。 其中、.text 和.c_init00之间的所有空间未分配给某些段、都用0填充。 链接器脚本生成器将所有需要但未在.cfg 文件中定义的段放在.cfg 文件中定义的所有段之后。

    因此、解决方案是按照.cfg 文件中的正确顺序定义输出文件中出现的所有段:

    Program.sectMap[".c_int00"]= new Program.SectionSpec ();
    Program.sectMap[".c_int00"].loadAddress = 0x80000000;
    Program.sectMap[".c_int00"].runAddress = 0x80000000;
    
    Program.sectMap[".text"]= new Program.SectionSpec ();
    Program.sectMap[".text"].loadSegment ="DDR2";
    
    Program.sectMap[".nonCachedRAM"]= new Program.SectionSpec ();
    Program.sectMap[".nonCachedRAM"].loadSegment
    
    
    
    Program.sectMap[".xAltera"].type
    
    
    
    
    Program.sectMap[".neardata"]="OCMC_SRAM";Program.sectMap[".xAltera"]= new Program.SectionSpec ();Program.sectMap[".xAltera"].loadSegment ="Altera_MEM";Program.sectMap[".rodata"].loadSegment = new Program.SectionSpec (Program.sectMap[".rodata"]
    Program.sectMap[".neardata"].loadSegment);= New = New Program.SectionSpec ();"Load === New Program.SectionSpec ()
    
    Program.sectMap["ti.sysbios.family.arm.a8.mmuTableSection"]= new Program.SectionSpec ();
    Program.sectMap["ti.sysbios.family.arm.a8.mmuTableSection"].loadSegment ="SRAM_HI";
    Program.sectMap["ti.sysbios.family.arm.a8.mmuTableSection"].type ="NoLoad";
    
    Program.sectMap["xdc.meta"]= new Program.SectionSpec ();
    Program.sectMap["xdc.meta"].loadSegment ="DDR2";
    
    Program.sectMap[".ARM.exidx"]= new Program.SectionSpec ();
    Program.sectMap[".ARM.exidx"].loadSegment ="***";
    
    Program.sectMap[".data"]= new Program.SectionSpec ();
    Program.sectMap[".data"].loadSegment ="D2"
    
    ;Program.sectMap[".bss"]
    
    
    
    Program.sectMap[".biosheap"].runSegment = new Program.SectionSpec (Program.sectMap[".bss"].loadSegment
    Program.sectMap[".biosheap"].type = Program.sectMap[".biosheap"]);"DDR2 ="New Program.SectionSpec (="Load)"
    
    Program.sectMap[".stack"]= new Program.SectionSpec ();
    Program.sectMap[".stack"].loadSegment ="DDR2";
    Program.sectMap[".stack"].type ="NoLoad"; 

    生成的二进制文件大小为276616字节、ELF 段如下所示:
    IDX 名称 尺寸 VMA LMA Algn
    0 .c_int00文件 000000b4 80000000 80000000 00010000 2**2.
    内容、ALLOC、load、readonly、code
    1 .text 0003189c 800000c0 800000c0 000100c0 2**4
    内容、ALLOC、load、readonly、code
    2 .rodata 00006e39 80031960 80031960 00041960 2**3.
    内容、ALLOC、load、readonly、data
    3 .vectors 00000040 80038800 80038800 00048800 2**10
    目录、ALLOC、载入、只读、数据
    4 ti.sysbios.family.arm.a8.mutableSection 00004000 402f4000 402f4000 00004000 2**14
    Alloc
    5 XDC.meta 000000e2 80038840 80038840 00048840 2**2.
    内容、ALLOC、load、readonly、data
    6 .arm.exidx 00000008 80038924 80038924 00048924 2**2
    内容、ALLOC、load、readonly、data
    7 .data 0000af5c 8003892c 8003892c 0004892c 2**2.
    内容、ALLOC、LOAD、DATA
    8 .bss 0002f748 80043888 80043888 00053888 2**3.
    Alloc
    9 .biosheap 01800000 80072fd0 80072fd0 00053888 2**3
    ALloc
    10 .stack 00020000 81872fd0 81872fd0 00053888 2**3
    Alloc
    11注释 0000007f 00000000 00000000 00053888 2**0
    内容、readonly
    12 .arm.attributes 0000003b 00000000 00000000 00053907 2**0
    内容、只读
    

    感谢您的帮助、它引导我找到正确的解决方案。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    感谢您在此处发布解决方案。