分析鏈接腳本的語法規則app
/* ---------------------------------------------------------------------------- * 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 }