您尚未登录。

楼主 # 2021-07-26 23:10:39

flex-A
会员
注册时间: 2019-08-27
已发帖子: 51
积分: 151.5

[提问帖]关于arm-gcc链接脚本指定ENTRY的问题

小弟在.ld文件中使用ENTY命令指定起始地址为Reset_Handler,但是链接出的.elf文件对应地址上的函数却不是Reset_Handler。
各文件详情:
-->.ld文件,文件中指定了ENTRY(Reset_Handler),并且.text段的起始地址设定为0x80002000

/* Entry Point */
ENTRY(Reset_Handler)

HEAP_SIZE   = DEFINED(__heap_size__)           ? __heap_size__          : 0x0400;
ISTACK_SIZE = DEFINED(__irq_stack_size__)      ? __irq_stack_size__     : 0x0400;
CSTACK_SIZE = DEFINED(__stack_size__)          ? __stack_size__         : 0x0400;
RSTACK_SIZE = DEFINED(__resume_stack_size__)   ? __resume_stack_size__  : 0x0400;

/* Specify the memory areas */
*/
MEMORY
{
  m_ocram               (RWX)  : ORIGIN = 0x00900000, LENGTH = 0x00020000
  m_interrupts          (RX)   : ORIGIN = 0x803FFFC0, LENGTH = 0x00000040
  m_text                (RX)   : ORIGIN = 0x80002000, LENGTH = 0x003FDFC0
  m_data                (RW)   : ORIGIN = 0x80400000, LENGTH = 0x00400000
}

/* Define output sections */
SECTIONS
{
  /* The startup code goes first into DDR RAM */
  .interrupts :
  {
    __VECTOR_TABLE = .;
    . = ALIGN(4);
    KEEP(*(.isr_vector))     /* Startup code */
    . = ALIGN(4);
  } > m_interrupts

  /* The program code and other data goes into DDR RAM */
  .text :
  {
    . = ALIGN(4);
    *(.text)                 /* .text sections (code) */
    *(.text*)                /* .text* sections (code) */
    *(.rodata)               /* .rodata sections (constants, strings, etc.) */
    *(.rodata*)              /* .rodata* sections (constants, strings, etc.) */
    *(.glue_7)               /* glue arm to thumb code */
    *(.glue_7t)              /* glue thumb to arm code */
    *(.eh_frame)
    KEEP (*(.init))
    KEEP (*(.fini))
    . = ALIGN(4);
  } > m_text

  .ARM.extab :
  {
    *(.ARM.extab* .gnu.linkonce.armextab.*)
  } > m_text

--> startup.s,该文件中定义了Reset_Handler函数,并且指定它在.text段

   .text
    .arm

/* Reset Handler */

    .arm
    .align 2
    .globl   Reset_Handler
    .weak    Reset_Handler
    .type    Reset_Handler, %function
Reset_Handler:
    cpsid   i               /* Mask interrupts */

    /* Reset SCTlr Settings */
    mrc     p15, 0, r0, c1, c0, 0     /* Read CP15 System Control register                  */
    bic     r0,  r0, #(0x1 << 12)     /* Clear I bit 12 to disable I Cache                  */
    bic     r0,  r0, #(0x1 <<  2)     /* Clear C bit  2 to disable D Cache                  */
    bic     r0,  r0, #0x2             /* Clear A bit  1 to disable strict alignment         */
    bic     r0,  r0, #(0x1 << 11)     /* Clear Z bit 11 to disable branch prediction        */
    bic     r0,  r0, #0x1             /* Clear M bit  0 to disable MMU                      */
    mcr     p15, 0, r0, c1, c0, 0     /* Write value back to CP15 System Control register   */

-->最终反编译出的结果

Disassembly of section .text:

80002000 <__do_global_dtors_aux>:
80002000:	b510      	push	{r4, lr}
80002002:	f240 046c 	movw	r4, #108	; 0x6c
80002006:	f2c8 0440 	movt	r4, #32832	; 0x8040
8000200a:	7823      	ldrb	r3, [r4, #0]

发现0x80002000地址上的函数却不是Reset_Handler,有熟悉链接脚本的大佬可以指点下小弟吗。
完整工程文件:imx6_template.zip
这是一个imx6ull的裸机工程,目前是使用NXP官方SDK来设置C语言环境,进入main点灯。

最近编辑记录 flex-A (2021-07-26 23:49:44)

离线

#1 2021-07-26 23:32:22

哇酷小二
管理员
所在地: 你猜
注册时间: 2020-04-22
已发帖子: 3,387
积分: 1902
个人网站

Re: [提问帖]关于arm-gcc链接脚本指定ENTRY的问题

楼主方便发一个完整的压缩包吗?





离线

楼主 #2 2021-07-26 23:50:24

flex-A
会员
注册时间: 2019-08-27
已发帖子: 51
积分: 151.5

Re: [提问帖]关于arm-gcc链接脚本指定ENTRY的问题

哇酷小二 说:

楼主方便发一个完整的压缩包吗?

工程文件已经上传了:D

离线

#3 2021-07-27 23:17:00

jhb
会员
注册时间: 2020-01-06
已发帖子: 1
积分: 0.5

Re: [提问帖]关于arm-gcc链接脚本指定ENTRY的问题

entry可能有优先级关系
可以在链接脚本中指定前面的文件中    KEEP(*(startup)) 用类似描述把入口代码放在前面

离线

楼主 #4 2021-07-28 22:37:00

flex-A
会员
注册时间: 2019-08-27
已发帖子: 51
积分: 151.5

Re: [提问帖]关于arm-gcc链接脚本指定ENTRY的问题

通过下图的方法明确指定文件链接的顺序是可以在期望的地址得到正确的函数的
tempsnip.jpg

离线

#5 2021-07-30 09:45:39

海石生风
会员
所在地: 深圳
注册时间: 2019-07-02
已发帖子: 650
积分: 783
个人网站

Re: [提问帖]关于arm-gcc链接脚本指定ENTRY的问题

Reset_Handler函数虽然是在 .text段,但并不一定会排在段首,所以就不是.text段的首地址。
解决办法是跟中断向量表的做法一样,在“MEMORY”域声明首地址为0x80002000的地址空间,指定这个空间包含的段(section),并且将Reset_Handler声明到这个section。

声明地址空间:(链接脚本)

MEMORY
{
  m_ocram               (RWX)  : ORIGIN = 0x00900000, LENGTH = 0x00020000
  m_interrupts          (RX)   : ORIGIN = 0x803FFFC0, LENGTH = 0x00000040
  m_entry              (RX)   : ORIGIN = 0x80002000, LENGTH = 0x00000040
  m_text                (RX)   : ORIGIN = 0x80002040, LENGTH = 0x003FDF80
  m_data                (RW)   : ORIGIN = 0x80400000, LENGTH = 0x00400000
}

指定段:(链接脚本)

  .entry :
  {
    __VECTOR_TABLE = .;
    . = ALIGN(4);
    KEEP(*(.entry)) 
    . = ALIGN(4);
  } > m_entry

函数声明section:(汇编源码)

  .section  .entry
  .type  Reset_Handler, %function
Reset_Handler:

最近编辑记录 海石生风 (2021-07-30 09:56:24)

离线

楼主 #6 2021-07-30 11:22:04

flex-A
会员
注册时间: 2019-08-27
已发帖子: 51
积分: 151.5

Re: [提问帖]关于arm-gcc链接脚本指定ENTRY的问题

@海石生风
多谢老哥,又多了一种解决方法

离线

#7 2021-07-30 17:50:27

海石生风
会员
所在地: 深圳
注册时间: 2019-07-02
已发帖子: 650
积分: 783
个人网站

Re: [提问帖]关于arm-gcc链接脚本指定ENTRY的问题

发现有点画蛇添足了;直接将Reset_Handler所属的section放在.text段首就可以了:

链接脚本:

  .text :
  {
    . = ALIGN(4);
    KEEP(*(.entry)) 
    *(.text)                 /* .text sections (code) */
    *(.text*)                /* .text* sections (code) */
    *(.rodata)               /* .rodata sections (constants, strings, etc.) */
    *(.rodata*)              /* .rodata* sections (constants, strings, etc.) */
    *(.glue_7)               /* glue arm to thumb code */
    *(.glue_7t)              /* glue thumb to arm code */
    *(.eh_frame)
    KEEP (*(.init))
    KEEP (*(.fini))
    . = ALIGN(4);
  } > m_text

源码:

  .section  .entry
  .type  Reset_Handler, %function
Reset_Handler:

最近编辑记录 海石生风 (2021-07-30 17:52:10)

离线

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn