eCos內存佈局文件詳細介紹

移植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部分這些宏定義的參數。

  1. The memory region in which the section will finally reside.
  2. 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
  3. 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: 未初始化數據段;

參考資料

» 文章出處: reille blog , 除非特別聲明,均爲原創作品,轉載請註明出處
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章