移植eCos时,对其内存布局文件内容比较疑惑,特别不理解其中“SECTIONS”部分的含义。为理解eCos内存布局文件中的内容,特此研究了一翻,这里我以eCos中stm3210e评估板ROM启动方式对应的内存布局文件为例进行说明。
eCos的内存布局(the Memory Layout)文件,由ldi文件及其头文件组成,描述了目标板的存储器设计和定义了链接器脚本输出段(section)。一般情况 下,针对每种启动方式(startup type),eCos中的模板都提供了对应的内存布局文件。当建立自己的模板时,需要在CDL文件中为每种启动方式匹配对应的内存布局文件。
stm3210e评估板ROM启动方式对应的内存布局文件
内存布局文件在此目录下:ecos/packages/hal/cortexm/stm32/stm3210e_eval/current/include/pkgconf,由ldi和h两文件组成。
mlt_cortexm_stm3210e_eval_rom.h文件的代码如下:
// eCos memory layout #ifndef __ASSEMBLER__ #include <cyg/infra/cyg_type.h> #include <stddef.h> #endif #define CYGMEM_REGION_sram (0x20000000) #define CYGMEM_REGION_sram_SIZE (0x00010000-CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE) #define CYGMEM_REGION_sram_ATTR (CYGMEM_REGION_ATTR_R | CYGMEM_REGION_ATTR_W) #define CYGMEM_REGION_flash (0x08000000) #define CYGMEM_REGION_flash_SIZE (0x00080000) #define CYGMEM_REGION_flash_ATTR (CYGMEM_REGION_ATTR_R | CYGMEM_REGION_ATTR_W) #define CYGMEM_REGION_ram (0x68000000) #define CYGMEM_REGION_ram_SIZE (0x00100000) #define CYGMEM_REGION_ram_ATTR (CYGMEM_REGION_ATTR_R | CYGMEM_REGION_ATTR_W) #define CYGMEM_REGION_rom (0x64000000) #define CYGMEM_REGION_rom_SIZE (0x01000000) #define CYGMEM_REGION_rom_ATTR (CYGMEM_REGION_ATTR_R) #ifndef __ASSEMBLER__ extern char CYG_LABEL_NAME (__heap1) []; #endif #define CYGMEM_SECTION_heap1 (CYG_LABEL_NAME (__heap1)) #define CYGMEM_SECTION_heap1_SIZE (CYGMEM_REGION_ram+CYGMEM_REGION_ram_SIZE - (size_t) CYG_LABEL_NAME (__heap1))
这是内存布局文件的头文件,主要是定义了相关存储器的地址及其大小,供其它源文件包含。
mlt_cortexm_stm3210e_eval_rom.ldi文件的代码如下:
// eCos memory layout #include <pkgconf/hal.h> #include <cyg/infra/cyg_type.inc> MEMORY { sram : ORIGIN = 0x20000000, LENGTH = 0x00010000-CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE flash : ORIGIN = 0x08000000, LENGTH = 0x00080000 rom : ORIGIN = 0x64000000, LENGTH = 0x01000000 ram : ORIGIN = 0x68000000, LENGTH = 0x00100000 } SECTIONS { SECTIONS_BEGIN SECTION_rom_vectors (flash, 0x08000000, LMA_EQ_VMA) SECTION_RELOCS (flash, ALIGN (0x8), LMA_EQ_VMA) SECTION_text (flash, ALIGN (0x8), LMA_EQ_VMA) SECTION_fini (flash, ALIGN (0x8), LMA_EQ_VMA) SECTION_rodata (flash, ALIGN (0x8), LMA_EQ_VMA) SECTION_rodata1 (flash, ALIGN (0x8), LMA_EQ_VMA) SECTION_fixup (flash, ALIGN (0x8), LMA_EQ_VMA) SECTION_gcc_except_table (flash, ALIGN (0x8), LMA_EQ_VMA) SECTION_eh_frame (flash, ALIGN (0x8), LMA_EQ_VMA) SECTION_got (flash, ALIGN (0x8), LMA_EQ_VMA) SECTION_sram (sram, 0x20000400, FOLLOWING (.got)) SECTION_data (ram, 0x68000000, FOLLOWING (.sram)) SECTION_bss (ram, ALIGN (0x8), LMA_EQ_VMA) CYG_LABEL_DEFN(__heap1) = ALIGN (0x8); SECTIONS_END } hal_vsr_table = 0x20000000; hal_virtual_vector_table = hal_vsr_table + 128*4; hal_startup_stack = 0x20000000 + 1024*64;
这是内存布局文件的ldi文件,由2部分组成:MEMORY和SECTIONS。 MEMORY部分定义了目标板上存储器的配置(存储区的地址和大小),这部分应该不难理解,难理解的是第2部分。
理解SECTIONS部分
SECTIONS部分,描述了链接器脚本输出段(section)的定义,大括号里面的语句都是一些宏调用。这些宏定义于:ecos/packages/hal/cortexm/arch/current/src/cortexm.ld文件中。由于不同架构的处理器有不同的链接器输出段(section),因此每种架构处理器对有对应的*.ld文件,如ARM处理器则有arm.ld文件。这ld文件是链接器的脚本文件,当编译eCos时,最终会生成target.ld(还记得在哪里吗?),作为应用程序的链接脚本。
cortexm.ld文件,是链接脚本,由链接器命令语言组成。关于链接器命令语言,我们可以只需有所了解,如:它里面定义的程序入口:ENTRY(reset_vector)。可从本博下载从网络上收集的链接器脚本文档知识,下载地址:http://velep.com/downloads?did=9
这里介绍下SECTIONS部分这些宏定义的参数。
- The memory region in which the section will finally reside.
- The final address ( VMA ) of the section. This is expressed using one of the following forms:
- n
- at the absolute address specified by the unsigned integer n
- ALIGN (n)
- following the final location of the previous section with alignment to the next n-byte boundary
- The initial address (LMA) of the section. This is expressed using one of the following forms:
- LMA_EQ_VMA
- the LMA equals the VMA (no relocation)
- AT (n)
- at the absolute address specified by the unsigned integer n
- FOLLOWING (.name)
- following the initial location of section name
上面是引用eCos英文手册中的解释,之所以不翻译,是因为我觉得英文更能正确表达这些宏参数的意思。
关于段(section)
正如上面所说,不同架构的处理器其链接器脚本中的段(section)名称和定义有所不同。这里列出我对其中一些段的理解(具体参考处理器对应的GCC手册):
- SECTION_text:放置程序代码的段;
- SECTION_data:初始化数据段;
- SECTION_bss: 未初始化数据段;
参考资料
- http://ecos.sourceware.org/docs-3.0/user-guide/modifying-the-memory-layout.html
- http://sourceware.org/ml/ecos-discuss/2006-09/msg00081.html
- http://blog.21ic.com/user1/1575/archives/2005/4090.html