S32DS for ARM 2018.R1 链接文件(linker file)学习笔记

S32DS for ARM 2018.R1 链接文件(linker file)学习笔记

在S32DS for ARM 2018.R1自带的例程中有两个链接文件,分别为S32K1xx_flash.ld和S32K1xx_ram.ld,前者针对的是程序在flash中运行的链接文件,后者是在ram中运行程序所需要的链接文件。以下以S32K144的flash.ld文件为例,进行简单的分析

/* Entry Point */
ENTRY(Reset_Handler)/* 关键词ENTRY()指定应用程序入口函数,即复位中断服务函数,是MCU复位后执行的第一个函数 */

HEAP_SIZE  = DEFINED(__heap_size__)  ? __heap_size__  : 0x00000400;/* 指定应用程序堆(heap)的大小,用于动态分配内存的RAM区域,heap的空间是用户手动申请和释放的 :C语言中的malloc(size), calloc(num, size)函数分配heap,释放使用free(*heap)函数。如果用户没有定义__heap_size__,则应用程序堆大小为默认的1024字节 */
STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x00000400;/* 指定应用程序栈(stack)的大小,栈被用于函数调用/中断服务函数调用时的CPU内核寄存器和上下文(Context)的保存、函数形参的传递和局部变量存储,其遵循先压栈后出栈(FILO—First In Last Out),原则,运行时有CPU内核自动控制。如果用户没有定义__stack_size__则应用程序栈大小为默认的1024字节 */

/* If symbol __flash_vector_table__=1 is defined at link time
 * the interrupt vector will not be copied to RAM.
 * Warning: Using the interrupt vector from Flash will not allow
 * INT_SYS_InstallHandler because the section is Read Only.
 */
M_VECTOR_RAM_SIZE = DEFINED(__flash_vector_table__) ? 0x0 : 0x0400;/* 如果定义了__flash_vector_table__,M_VECTOR_RAM_SIZE就等于0,从而导致__VECTOR_RAM等于__VECTOR_TABLE,在startup.c文件根据此条件中断向量表就不会拷贝到RAM中,此时就没法在程序中调用INT_SYS_InstallHandler进行中断处理函数的安装 */

/* Specify the memory areas */
MEMORY
{
  /* Flash */
  m_interrupts          (RX)  : ORIGIN = 0x00000000, LENGTH = 0x00000400/* 中断向量表/启动代码,起始地址为0x000,长度0x400 */
  m_flash_config        (RX)  : ORIGIN = 0x00000400, LENGTH = 0x00000010/* flash配置信息存放位置,起始地址为0x400,长度为0x10 */
  m_text                (RX)  : ORIGIN = 0x00000410, LENGTH = 0x0007FBF0/* 主要代码/数据存储区,起始地址为0x410,长度为512K-0x410;除此而外,S32K144还有64KFleNVM,可用作P-Flash或D-Flash,即FlexNVM可用于程序或数据存储。如果用作P-Flash,由于FlexNVM不可缓存;因此,可能会出现性能下降。 */

  /* SRAM_L */
  m_data                (RW)  : ORIGIN = 0x1FFF8000, LENGTH = 0x00008000/* SRAM_L包含.interrupts_ram段.data段和.code段,起始地址为0x1FFF8000,长度为32K;S32K的SRAM具有ECC功能,用户在启动函数start()中,最开始对SRAM进行写值(将内核通用寄存器值写入SRAM)操作,初始化ECC。所有带硬件ECC功能的系统存储器读取前都必须先对其进行写值/擦除(对Flash和EEPROM)操作,产生初始的ECC,否则读取时将产生ECC错误 */

  /* SRAM_U */
  m_data_2              (RW)  : ORIGIN = 0x20000000, LENGTH = 0x00007000/* SRAM_U包含.customSectionBlock段.bss段.heap段和.stack段,起始地址为0x20000000,长度为28K;S32K144总共64KRAM,还有4KRAM是flexRAM,可用于传统的SRAM,但它不像主SRAM那样具有ECC,并且以flash的时钟速度运行 */
}

/* Define output sections */
SECTIONS
{
  /* The startup code goes first into internal flash */
  .interrupts :/* 启动段 */
  {
    __VECTOR_TABLE = .;/* 标记向量表开始地址,"."表示当前地址 */
    __interrupts_start__ = .;/* 标记驱动段开始地址 */
    . = ALIGN(4);/* 使用关键词ALIGN() 将其4字节对齐 */
    KEEP(*(.isr_vector))     /* Startup code 使用关键词KEEP,将.isr_vector段始终保持在此段内 */
    __interrupts_end__ = .;/* 标记驱动段结束地址 */
    . = ALIGN(4);
  } > m_interrupts/* 链接到m_interrupts分区 */

  .flash_config :/* flash配置信息存放区域 */
  {
    . = ALIGN(4);
    KEEP(*(.FlashConfig))    /* Flash Configuration Field (FCF) */
    . = ALIGN(4);
  } > m_flash_config

  /* The program code and other data goes into internal flash */
  .text :/* 主要代码和数据存储区 */
  {
    . = ALIGN(4);
    *(.text)                 /* .text sections (code) 所有文件中的.text段 */
    *(.text*)                /* .text* sections (code) 所有文件中以.text开始的段 */
    *(.rodata)               /* .rodata sections (constants, strings, etc.)只读数据段,由于存储const修饰的常量 */
    *(.rodata*)              /* .rodata* sections (constants, strings, etc.) */
    *(.init)                 /* section used in crti.o files 在crti.o文件中使用此段 */
    *(.fini)                 /* section used in crti.o files */
    *(.eh_frame)             /* section used in crtbegin.o files */
    . = ALIGN(4);
  } > m_text

  /* Section used by the libgcc.a library for fvp4 用于存放ARM的FVP4信息 */
  .ARM :
  {
    __exidx_start = .;
    *(.ARM.exidx*)
    __exidx_end = .;
  } > m_text

  __etext = .;    /* Define a global symbol at end of code. */
  __DATA_ROM = .; /* Symbol is used by startup for data initialization.启动过程中初始化.data段需要引用此符号 */

  .interrupts_ram :/* ram中的中断向量段 */
  {
    . = ALIGN(4);
    __VECTOR_RAM__ = .;
    __RAM_START = .;
    __interrupts_ram_start__ = .; /* Create a global symbol at data start. */
    *(.m_interrupts_ram)          /* This is a user defined section. */
    . += M_VECTOR_RAM_SIZE;
    . = ALIGN(4);
    __interrupts_ram_end__ = .;   /* Define a global symbol at data end. */
  } > m_data

  __VECTOR_RAM = DEFINED(__flash_vector_table__) ? ORIGIN(m_interrupts) : __VECTOR_RAM__ ;
  __RAM_VECTOR_TABLE_SIZE = DEFINED(__flash_vector_table__) ? 0x0 : (__interrupts_ram_end__ - __interrupts_ram_start__) ;

  .data : AT(__DATA_ROM)/* .data段(存放初始化值不为0的全局变量)  关键词AT(),将其存储并从__DTA_ROM分区加载 */
  {
    . = ALIGN(4);
    __DATA_RAM = .;
    __data_start__ = .;      /* Create a global symbol at data start. */
    *(.data)                 /* .data sections */
    *(.data*)                /* .data* sections */
    . = ALIGN(4);
    __data_end__ = .;        /* Define a global symbol at data end. */
  } > m_data

  __DATA_END = __DATA_ROM + (__data_end__ - __data_start__);
  __CODE_ROM = __DATA_END; /* Symbol is used by code initialization. */

  .code : AT(__CODE_ROM)/* .code段,通过__attribute__((section (".code_ram")))将需要重映射的代码/函数指定到RAM中的.code_ram段运行 */
  {
    . = ALIGN(4);
    __CODE_RAM = .;
    __code_start__ = .;      /* Create a global symbol at code start. */
    __code_ram_start__ = .;
    *(.code_ram)             /* Custom section for storing code in RAM */
    . = ALIGN(4);
    __code_end__ = .;        /* Define a global symbol at code end. */
    __code_ram_end__ = .;
  } > m_data

  __CODE_END = __CODE_ROM + (__code_end__ - __code_start__);
  __CUSTOM_ROM = __CODE_END;

  /* Custom Section Block that can be used to place data at absolute address. */
  /* Use __attribute__((section (".customSection"))) to place data here. 使用__attribute__((section (".customSection")))将需要固定地址的函数从0x20000000开始安放,具体可以查看map文件中需要固定地址的函数,注意不要用static修饰,不然在map文件中只能看到文件名,看不到具体的函数名以及地址 */
  .customSectionBlock  ORIGIN(m_data_2) : AT(__CUSTOM_ROM)
  {
    __customSection_start__ = .;
    KEEP(*(.customSection))  /* Keep section even if not referenced. */
    __customSection_end__ = .;
  } > m_data_2
  __CUSTOM_END = __CUSTOM_ROM + (__customSection_end__ - __customSection_start__);

  /* Uninitialized data section. */
  .bss :/* .bss段,存放未初始化或初始化值为0的全局变量 */
  {
    /* This is used by the startup in order to initialize the .bss section. */
    . = ALIGN(4);
    __BSS_START = .;
    __bss_start__ = .;
    *(.bss)
    *(.bss*)
    *(COMMON)
    . = ALIGN(4);
    __bss_end__ = .;
    __BSS_END = .;
  } > m_data_2

   /* Put heap section after the program data */
  .heap :/* 堆区 */
  {
    . = ALIGN(8);
    __end__ = .;
    __heap_start__ = .;
    PROVIDE(end = .);
    PROVIDE(_end = .);
    PROVIDE(__end = .);
    __HeapBase = .;
    . += HEAP_SIZE;
    __HeapLimit = .;
    __heap_limit = .;
    __heap_end__ = .;
  } > m_data_2

  /* Initializes stack on the end of block */
  __StackTop   = ORIGIN(m_data_2) + LENGTH(m_data_2);
  __StackLimit = __StackTop - STACK_SIZE;
  PROVIDE(__stack = __StackTop);
  __RAM_END = __StackTop;

  .stack __StackLimit :/* 栈区 */
  {
    . = ALIGN(8);
    __stack_start__ = .;
    . += STACK_SIZE;
    __stack_end__ = .;
  } > m_data_2

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

  ASSERT(__StackLimit >= __HeapLimit, "region m_data_2 overflowed with stack and heap")/* 断言函数,判断m_data_2是否越界 */
}
发布了8 篇原创文章 · 获赞 6 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/bjxdbz/article/details/105082646