2013年(15)
分类: 嵌入式
2013-10-15 15:11:49
原文地址:MQX心得之地址空间分布 作者:shaomengchao
地址空间分布对于一个实时性系统而言是非常重要的组成部分。对于Cortex M4系列,既可以从flash直接运行代码,也可以从ram中运行,但是作为估计我们编译好的可执行文件都是烧录在flash里的。所以在系统上电和系统运行之前就有一个flash的相应内容拷贝到内存的一个环节,而这个环节就称之为加载。MQX的初始状态的内存分布就和这个加载过程密切相关。
一个程序文本从文本状态到能够实际运行需要三个步骤:编译、链接和加载。编译时将文本文件编译成能被机器识别的指令代码,而链接是将这些零散的指令代码按照一定的顺序组合起来形成一个可执行的文件,最后的加载时负责将可执行文件中的一些内容拷贝到内存中,为程序的执行提供必要的准备环境。而之前我们提及的scatter文件就是控制链接和加载环节的。举个例子:
点击(此处)折叠或打开
这里LOAD_ROM包括了RO、RW和ZI三部分,这三个部分在可执行文件中是连续排布的,分别从0x0000一直排,此区域最大为0x8000。LOAD_ROM下面一级是加载时的排布,分为两个区域:EXEC_ROM、SRAM。其中RO是放在EXEC_ROM里分布在0x0000~0x8000上,RW和ZI是放在SRAM,分布在0x10000~0x16000上。
点击(此处)折叠或打开
我不知道这个量有什么作用,注释里说用来配置flash控制器的,那估计就是这样用的吧。之后是CODE区,包含main和lib的code、中断和调度汇编码的code、其他code和其他常量。具体里面有什么东西可以参考keil生产的map文件。接下来的是vectors_ram、nouser、rouser、rwuser这些我们程序都没有编译,就忽略不提了。之后的就是RW部分,那个是静态变量,目前放在flash里,加载的时候要拷贝到sram里去。
之前所的是程序固件的空间分布情况,但是固件一旦加载就会发生变化。像CODE区里的内容是不变的,原来在哪现在还在哪,但RW的内容就被拷贝到SRAM的开始部分,RW之后就是ZI。ZI是临时变量,由于没有初值,就不需要占用flash里的空间,只需要运行时划出一块内存拿来用就可以了。紧接着ZI后面的就是MQX系统最常用的一块区域kernel_data,这块区域由两部分组成:开头的是KERNEL_DATA_STRUCT,放的是MQX的全局性的变量。我不太清楚这样比起直接将变量定义为全局变量多了什么优点,但有一点是肯定的,这样比东一个西一个的零散式分布更方便于管理;后面的是MEM_POOL部分,它承担着动态分配内存的作用,具体内存我之后会提及。kernel_data一直持续到0x2000FFF0,留了16字节以防过界。
这样MQX的地址空间分布我就大致介绍完了,相对于裸奔的松散分布的程序,这样紧凑的分布大大的提高了资源的利用率,很有借鉴的价值。