一、分散加载文件的原理和MDK上的配置
ARM的连接器提供了一种分散加载机制,在连接时可以根据分散加载文件(.scf文件)中指定的存储器分配方案,将可执行镜像文件分成指定的分区并定位于指定的存储器物理地址。这样,当嵌入式系统在复位或重新上电时,在对CPU相应寄存器进行初始化后,首先执行ROM存储器的Bootloader代码,根据连接时的存储器分配方案,将相应代码和数据由加载地址拷贝到运行地址,这样,定位在RAM存储器的代码和数据就在RAM存储器中运行,而不再从ROM存储器中取数据或取指令,从而大大提高了CPU的运行速率和效率。
在Keil中Linker选项中,可以设置R/O Base来设置RO区域的加载和执行地址,R/W Basel来设置RW区域的执行地址,勾选Use Memory Layout from Target Dialog,那么加载文件就是从你定义irom和iram等地址得到的,如果不勾选的话就是通过你自己指定的加载文件来加载。
二、Scatter文件结构和代码分析
装载区:当系统启动或加载时应用程序的存放区。
执行区:系统启动后,应用程序进行执行和数据访问的存储器区域,系统在实时运行时可以有一个或多个执行块。
分散加载文件的格式
分散加载描述文件是一个文本文件,它向链接器描述目标系统的存储器映射。如果通过命令行使用链接器,则描述文件的扩展名并不重要。分散加载文件指定:
① 每个加载区的加载地址和最大尺寸;
② 每个加载区的属性;
③ 从每个加载区派生的执行区;
④ 每个执行区的执行地址和最大尺寸;
⑤ 每个执行区的输入节。
从描述文件的格式就可以看出加载区、执行区和输入节的层次关系。
这里列举了程序加载到RAM运行的Scatter文件,上代码具体分析:
LR_ROM1 0x30000000 { ; load region
ER_ROM1 0x30000000 0x0800000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
}
RW_RAM1 0x30800000 0x0800000 { ; RW data
.ANY (+RW +ZI)
}
}
LR_ROM1 0x3000000 ;初始化程序,拷贝代码等,从ROM的地址0x3000000开始。
ER_ROM1 0x3000000 0x0800000 ;加载域运行的时域,从0x30000000地址开始,大小为0x0800000.
*.o (RESET,+First) ;IAP第一阶段还是在FLASH中运行
*(InRoot$$Sections) ;复制代码
.ANY (+RO) ;除了RO以外的数据
RW_RAM1 0x30800000 0x0800000 ;把可读写的数据和初始化为0的数据放在内存
.ANY(+RW +ZI) ;除了RW,ZI以外的数据
注释:+RO表示只读代码或者只读数据,一般用来表示代码,+RW表示可读可写的数据,+ZI表示初始化为0的数据。大括号里面的为运行域(execution region),一个加载域可以包含几个运行域,.ANY表示除了上面用到的代码之外的代码。