zoukankan      html  css  js  c++  java
  • ARM 链接脚本分析

    分析连接脚本的语法规则

    /* ----------------------------------------------------------------------------
     * Memory linker description
     * ------------------------------------------------------------------------- */
    MEMORY
    {
      /* ROM区,只读, 起始地址0x00000000, 长度4K */
      ROM  (r) : ORIGIN = 0x00000000, LENGTH = 4K
      /* FLASH区, 读,写,可执行, 起始地址0x00100000, 长度380K*/
      FLASH (xrw) : ORIGIN = 0x00100000, LENGTH = 380K
      /* PRAM , 32K */
      PRAM (xrw) : ORIGIN = 0x00200000, LENGTH = 32K
    
      DRAM (xrw) : ORIGIN = 0x20000000, LENGTH = 24K
      DRAM_DSP (xrw) : ORIGIN = 0x20006000, LENGTH = 48K
      DRAM_BB (xrw) : ORIGIN = 0x20012000, LENGTH = 16K
    }
    
    /* ----------------------------------------------------------------------------
     * Stack related defines and provided variables
     * ------------------------------------------------------------------------- */
    /* 计算stack的地址 */
    __stack = ORIGIN(DRAM) + LENGTH(DRAM);
    /* 全局变量__stack, c语言可以应用 */
    PROVIDE ( __stack = __stack ) ;
    
    /*
     * Default stack sizes.
     * These are used by the startup in order to allocate stacks
     * for the different modes.
     */
    
    __Main_Stack_Size = 1024 ;
    PROVIDE ( _Main_Stack_Size = __Main_Stack_Size ) ;
    
    __Main_Stack_Limit = __stack  - __Main_Stack_Size ;
    PROVIDE ( _Main_Stack_Limit = __Main_Stack_Limit ) ;
    
    /* ----------------------------------------------------------------------------
     * Heap related defines and provided variables
     * ------------------------------------------------------------------------- */
    PROVIDE ( __Heap_Begin__ = __noinit_end__ ) ;
    PROVIDE ( __Heap_Limit__ = __stack - __Main_Stack_Size ) ;
    
    /*
     * The entry point is informative, for debuggers and simulators,
     * since the Cortex-M vector points to it anyway.
     */
    /* 指定可执行文件的起始代码段是Reset_Handler */
    ENTRY(Reset_Handler)
    
    /* 
     * As is the VTOR register, we refer to it in startup documentation
     */
    __VTOR = 0xE000ED08;
    
    /* ----------------------------------------------------------------------------
     * Section definitions
     * ------------------------------------------------------------------------- */
    SECTIONS
    {
        /*
         * For Cortex-M devices, the beginning of the startup code is stored in
         * the .interrupt_vector section, which goes to FLASH
         */
    	 /* DEFINED判断括号内的__app_rom_start,是否在全局符号表内,并且定义了,是就返回1,否返回0
    	  * 再根据DEFINED结果进行判断__rom_start的值,是__app_rom_start,还是ORIGIN(FLASH)
    	  */
        __rom_start = DEFINED(__app_rom_start) ? __app_rom_start : ORIGIN(FLASH);
        /* 计算image的大小 */
    	__image_size = __data_init__ + SIZEOF(.data) - __rom_start;
    	/* .text代码段, 保存在FLASH中,FLASH起始地址0x0010000*/
        .text __rom_start :
        {
    	    /* 四字节对齐 */
            . = ALIGN(4);
    		/* 强制链接器保留一些特定的section */
            KEEP(*(.interrupt_vector))
    
            /*
             * This section is here to store the startup code immediately after
             * the interrupt vectors, as required by the program ROM.
             */
    		/* 所有文件的reset段,都放在interrupt_vector段后面 */
            *(.reset)
            
            /*
             * FOTA BootLoader descriptor
             */
            *(.rodata.fota.image-size)
            KEEP(*(.rodata.fota.build-id))
            
            /*
             * FOTA version descriptor
             */
    		 /* 所有的.rodata.boot.version section 放到.text section里面*/
            *(.rodata.boot.version)
    
            /* Pre-initialization Code */
            . = ALIGN(4); 
            PROVIDE_HIDDEN (__preinit_array_start__ = .);
    
            /* System initialization and the platform initialization (if present)
             * should be first */
            KEEP(*(.preinit_array_sysinit .preinit_array_sysinit.*))
            KEEP(*(.preinit_array_platform .preinit_array_platform.*))
    
            /* Pre-initialization functions (to be executed before C++
             * constructors are run) */
            KEEP(*(.preinit_array .preinit_array.*))
    
            PROVIDE_HIDDEN (__preinit_array_end__ = .);
    
            /* Initialization Code */
            . = ALIGN(4);
            PROVIDE_HIDDEN (__init_array_start__ = .);
    
            KEEP(*(SORT(.init_array.*)))
            KEEP(*(.init_array))
    
            PROVIDE_HIDDEN (__init_array_end__ = .);
    
            /*
             * The program code is stored in the .text section,
             * which goes to FLASH.
             */
            . = ALIGN(4);
    		/* 所有的文件的.text section*/
            *(.text .text.*)            /* all remaining code */
    		/* 所有文件的.rodata section */
            *(.rodata .rodata.*)        /* read-only data (constants) */
    
            . = ALIGN(4);
            __dsp_start__ = . ;
            KEEP(*(.dsp .dsp.*))        /* all remaining DSP code */
            __dsp_end__ = . ;
    		/* 四字节对齐 */
            . = ALIGN(4);
    	/* .text全部链接到FLASH里面,Flash是前面MEMORY里面定义的,起始地址是0x00100000 */
        } >FLASH
    
        /*
         * This address is used by the startup code to
         * initialize the .data section.
         */
        . = ALIGN(4);
    	/* 将定位符号'.'的值赋给__data_init */
    	/* 也就是说__data_init__放在.text段的后面 */
        __data_init__ = .;
    
        /* Place the SystemClock variable needed for CMSIS in a place that is
         * compatible with the ROM's placement of this variable so that the
         * variable can be used by CMSIS and the ROM's flash write libary */
        .systemclock (NOLOAD) :
        {
            . = ALIGN(4);
            KEEP(*(.systemclock))
    		/* 保存到DRAM中 */
        } > DRAM
    
        /*
         * The initialized data section.
         * The program executes knowing that the data is in the RAM
         * but the loader puts the initial values in the FLASH (inidata).
         * It is one task of the startup to copy the initial values from
         * FLASH to RAM.
         */
    	 /* 查看__app_ram_start是否定义,并给__ram_start赋值 */
        __ram_start = DEFINED(__app_ram_start) ? __app_ram_start : .;
    	/* .data数据段 */
    	/* AT表示加载地址或者存储地址,指程序编译之后存放的地址,一般在ROM或者FLASH中  */
    	/* 运行的时候,从AT指定的地址__data_init__中赋值到_ram_start中运行 */
    	/* 从FLASH中复制到RAM里面运行 */
        .data __ram_start : AT ( __data_init__ )
        {
            . = ALIGN(4);
    
            /* This is used by the startup code to initialize the .data section */
            __data_start__ = . ;
            *(.data_begin .data_begin.*)
            *(.data .data.*)
            *(.data_end .data_end.*)
            . = ALIGN(4);
    
            /* This is used by the startup code to initialize the .data section */
            __data_end__ = . ;
        } >DRAM
    
        /*
         * The uninitialized data section. NOLOAD is used to avoid
         * the "section `.bss' type changed to PROGBITS" warning
         */
    	 /* .bss未初始化的数据段, 存放在DRAM中 */
        .bss (NOLOAD) :
        {
            . = ALIGN(4);
            __bss_start__ = .;		// 把__bss_start_段赋值当前位置,bss段的起始位置
            *(.bss_begin .bss_begin.*)	// 所有的bss_begin和bss_begin.*段放到bss里面
    
            *(.bss .bss.*)		// 所有文件的.bss和.bss.*段放在bss_begin,bss_begin.*后面
            *(COMMON)			// COMMON放在.bss,.bss.*后面
    
            *(.bss_end .bss_end.*)	// 所有文件的.bss_end, .bss_end.* 放在COMMON后面
            . = ALIGN(4);
            __bss_end__ = .;		// 把__bss_end__段赋值为当前位置,结束位置
        } >DRAM
    
        .noinit (NOLOAD) :
        {
            . = ALIGN(4);
            __noinit_start__ = .;
    
            *(.noinit .noinit.*)
    
             . = ALIGN(4) ;
            __noinit_end__ = .;
        } > DRAM
        
        /* Check if there is enough space to allocate the main stack */
        ._stack (NOLOAD) :
        {
            . = ALIGN(4);
            
            . = . + __Main_Stack_Size ;	// 计算栈的大小放到DRAM中
            
            . = ALIGN(4);
        } >DRAM
    }
    
  • 相关阅读:
    Nginx URL后面不加斜杠301重定向
    Jenkins 配置 Node.js 项目
    在 Linux 上搭建IntelliJ IDEA license server服务器
    Vue 使用细节收集
    sinopia 搭建记录
    cli 开发记录
    Cgroup(一)简介
    Kubernetes (一)POD驱逐
    RabbitMQ(五)镜像队列
    RabbitMQ(四)队列结构
  • 原文地址:https://www.cnblogs.com/helloworldtoyou/p/11358292.html
Copyright © 2011-2022 走看看