define symbol __ram_vector_table_size__ = isdefinedsymbol(__ram_vector_table__) ? 0x00000400 : 0;
define symbol __ram_vector_table_offset__ = isdefinedsymbol(__ram_vector_table__) ? 0x000003FF : 0;
define symbol m_interrupts_start = 0x30002000;
define symbol m_interrupts_end = 0x300023FF;
define symbol m_text_start = 0x30002400;
if (isdefinedsymbol(__use_flash64MB__)) {
define symbol m_text_end = 0x33FFFFFF;
} else{
define symbol m_text_end = 0x30FFFFFF;
define symbol m_interrupts_ram_start = 0x20000000;
define symbol m_interrupts_ram_end = 0x20000000 + __ram_vector_table_offset__;
define symbol m_data_start = m_interrupts_ram_start + __ram_vector_table_size__;
define symbol m_data_end = 0x2003FFFF;
define symbol m_data2_start = 0x202C0000;
define symbol m_data2_end = 0x2033FFFF;
define symbol m_data3_start = 0x80000000;
define symbol m_data3_end = 0x82FFFFFF;
define symbol m_ncache_start = 0x83000000;
define symbol m_ncache_end = 0x83FFFFFF;
define exported symbol __NCACHE_REGION_START = m_ncache_start;
define exported symbol __NCACHE_REGION_SIZE = m_ncache_end - m_ncache_start + 1;
define symbol m_qacode_start = 0x00000000;
define symbol m_qacode_end = 0x0003FFFF;
这一段中出现了两个ICF语法:
(1)isdefinedsymbol(name)
:当name
被定义了返回1,否则返回0
(2)define symbol
:定义一个变量
- 语法:
define [ exported ] symbol name = expr;
- 参数:
name
为变量名,expr
为变量的值,exported
可省略,若定义则可以在程序中使用extern来获取此变量的值
现在来分析一下上面的链接文件:
(1)__ram_vector_table__
在其它地方没有定义,即__ram_vector_table_size__
和__ram_vector_table_offset__
的值都为0。所以,m_interrupts_ram_start
和m_interrupts_ram_end
都为0x20000000。
实际上,由于程序是运行在NOR Flash中的,程序镜像起始处的中断向量表也映射到了NOR Flash中,而不是保存在RAM中。所以实际上上面的这几个变量并没有被使用到,可以直接忽略。
真正使用的向量表变量是m_interrupts_start
(0x30002000
)和m_interrupts_end
(0x300023FF
),长度为0x3FF+1=0x400
,可以去启动的.s
数一下,程序最开始的向量长度确实是填充到了0x400处。
- 至于为什么向量表从NOR Flash的0x2000偏移处开始,这是因为I.MX系列单片机都需要一个IVT头供芯片固有的ROM BootLoader进行引导,这个头在使用NOR Flash XIP时,长度为0x2000。这里不用过多纠结。
(2)m_text_start
(0x30002400
)和m_text_end
(0x30FFFFFF
)紧跟着向量表,就是后续的代码段链接的位置了,大小为16MB。
(3)m_data_start
和m_data_end
;m_data2_start
和m_data2_end
;m_data3_start
和m_data3_end
;m_ncache_start
和m_ncache_end
;m_qacode_start
和m_qacode_end
这三个变量分别定义了DTCM
、OC2
、SDRAM
(可缓存部分)、SDRAM
(不可缓存部分)和ITCM
的内存起始和结束地址。
(4)__NCACHE_REGION_START
和__NCACHE_REGION_SIZE
:定义了不可缓存内存的起始和结束地址,这个部分用了export
,这是因为不可缓存部分需要在程序的MPU代码中进行配置。
接着往下分析: