移植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
推薦閱讀相關文章:
- stm32移植ecos #11,使用自己的模板(Template)
- stm32移植ecos #10,移植ecos併成功運行helloworld程序,燒寫到內部flash直接運行helloworld程序
- stm32移植ecos #9,移植ecos併成功運行helloworld程序,使用redboot引導運行內存中的helloworld程序
- stm32移植ecos #8,移植ecos併成功運行helloworld程序,編譯鏈接生成helloworld程序
- stm32移植ecos #7,移植ecos併成功運行helloworld程序,配置編譯生成靜態鏈接庫文件
- stm32移植ecos #6,redboot的疑問和問題,redboot是必需的嗎?
- stm32移植ecos #5,移植redboot(ROM啓動方式)下篇
- stm32移植ecos #4,移植redboot(ROM啓動方式)上篇