Chinaunix首页 | 论坛 | 博客
  • 博客访问: 182478
  • 博文数量: 20
  • 博客积分: 125
  • 博客等级: 入伍新兵
  • 技术积分: 985
  • 用 户 组: 普通用户
  • 注册时间: 2011-11-08 13:48
个人简介

热爱开源,喜欢分析操作系统架构

文章分类

全部博文(20)

文章存档

2013年(17)

2012年(3)

分类: 嵌入式

2013-04-21 19:53:01

地址空间分布对于一个实时性系统而言是非常重要的组成部分。对于Cortex M4系列,既可以从flash直接运行代码,也可以从ram中运行,但是作为估计我们编译好的可执行文件都是烧录在flash里的。所以在系统上电和系统运行之前就有一个flash的相应内容拷贝到内存的一个环节,而这个环节就称之为加载。MQX的初始状态的内存分布就和这个加载过程密切相关。

一个程序文本从文本状态到能够实际运行需要三个步骤:编译、链接和加载。编译时将文本文件编译成能被机器识别的指令代码,而链接是将这些零散的指令代码按照一定的顺序组合起来形成一个可执行的文件,最后的加载时负责将可执行文件中的一些内容拷贝到内存中,为程序的执行提供必要的准备环境。而之前我们提及的scatter文件就是控制链接和加载环节的。举个例子:

点击(此处)折叠或打开

  1. LOAD_ROM 0x0000 0x8000 ; Name of load region (LOAD_ROM),
  2. ; Start address for load region (0x0000),
  3. ; Maximum size of load region (0x8000)
  4. {
  5.     EXEC_ROM 0x0000 0x8000 ; Name of first exec region (EXEC_ROM),
  6.                            ; Start address for exec region (0x0000),
  7.                            ; Maximum size of first exec region (0x8000)
  8.     {
  9.         * (+RO) ; Place all code and RO data into
  10.                 ; this exec region
  11.     }
  12.     SRAM 0x10000 0x6000 ; Name of second exec region (RAM),
  13.                                 ; Start address of second exec region (0x10000),
  14.                                 ; Maximum size of second exec region (0x6000)
  15.     {
  16.         * (+RW, +ZI) ; Place all RW and ZI data into
  17.                      ; this exec region
  18.     }
  19. }

这里LOAD_ROM包括了RO、RW和ZI三部分,这三个部分在可执行文件中是连续排布的,分别从0x0000一直排,此区域最大为0x8000。LOAD_ROM下面一级是加载时的排布,分为两个区域:EXEC_ROM、SRAM。其中RO是放在EXEC_ROM里分布在0x0000~0x8000上,RW和ZI是放在SRAM,分布在0x10000~0x16000上。


对于MQX的加载,基本上和这个差不多,对照scatter文件,我给出了相应的分布图。

K60芯片的flash地址是从0开始的,内部sram是从0x1FFF0000~0x2000FFFF的128K地址。对于程序固件,自然是老老实实的放在flash里的。其中vectors_rom是中断向量表,它放在最前是cortex m4的需要。而cfmconfig是vectors.c里定义的四个莫名其妙的常量

点击(此处)折叠或打开

  1. __attribute__((section(".cfmconfig"))) const uint_32 _cfm[4] __attribute__((used)) = {
  2.             CONFIG_1,
  3.             CONFIG_2,
  4.             CONFIG_3,
  5.             CONFIG_4
  6.     }
  7.     
  8. /* Configuration values for flash controller */
  9. #define CONFIG_1 (uint_32)0xffffffff
  10. #define CONFIG_2 (uint_32)0xffffffff
  11. #define CONFIG_3 (uint_32)0xffffffff
  12. #define CONFIG_4 (uint_32)0xfffffffe

我不知道这个量有什么作用,注释里说用来配置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的地址空间分布我就大致介绍完了,相对于裸奔的松散分布的程序,这样紧凑的分布大大的提高了资源的利用率,很有借鉴的价值。



阅读(3005) | 评论(2) | 转发(1) |
给主人留下些什么吧!~~

shaomengchao2013-10-28 15:35:00

lt6210925:#define CONFIG_1 (uint_32)0xffffffff
#define CONFIG_2 (uint_32)0xffffffff
#define CONFIG_3 (uint_32)0xffffffff
#define CONFIG_4 (uint_32)0xfffffffe
这段,是芯片flash配置那段,主要负责芯片加密以及一些区域的读取的信息,芯片开始时,flash控制器会加载这一部分

原来如此,谢谢指教

回复 | 举报

lt62109252013-09-02 21:04:46

#define CONFIG_1 (uint_32)0xffffffff
#define CONFIG_2 (uint_32)0xffffffff
#define CONFIG_3 (uint_32)0xffffffff
#define CONFIG_4 (uint_32)0xfffffffe
这段,是芯片flash配置那段,主要负责芯片加密以及一些区域的读取的信息,芯片开始时,flash控制器会加载这一部分