一、嵌入式系统中的存储映射
在ARM体系结构中,系统复位后将跳转到地址0x00x处执行,该处存放的是复位异常中断的中断向量。对于嵌入式系统来说,在系统复位时RAM中是不存在代码和数据的。因此在系统复位时,地址0x00处应为ROM,即系统复位后应该首先从ROM开始执行。这时,根据系统在其后运行过程中地址0x00处存储器的类型,有下面两种情况。
1、地址0x00处为ROM
这里说的地址0x00为ROM,是指在系统运行过程中,地址0x00为ROM。对于嵌入式系统来说,在系统复位时地址0x00处总为ROM。这种情况非常简单,在地址0x00存存放着复位异常中断向量,根据此中断向量,程序跳转到相应的位置开始进行系统初始化等操作。
这种情况有种缺点,通常相对于RAM来说,ROM的数据宽度较小,速度较慢,这会使系统响应异常中断的速度较慢。而且如果异常中断向量表放在ROM中,则中断向量表内容不能修改。
2、地址0x00处为RAM
<script type="text/javascript"> </script> <script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"></script>
同样,这里说的地址是指系统运行时地址为0x00,而嵌入式系统在系统复位时的地址0x00处总为ROM。因此,对于运行时地址处0x00为RAM的系统,为了保证系统复位后从ROM中开始执行,在系统复位时,系统中的映射机构将ROM映射到地址0x00处,然后在程序运行最初几条指令中,系统中的存储机构进行地址重映射(remap)重新将RAM映射到地址0x00处。
相对于ROM来说,RAM的数据宽度较大,速度较快,这会使系统响应异常中断的速度更快。而且如果异常中断向量表放在RAM中,程序在运行中可以修改中断向量表内容,使系统更为灵活。
如果系统正常运行过程中,地址0x00处为RAM,则在系统复位时需要执行下面操作序列。
1、系统复位时,ROM被映射到地址0x00处,程序从这里获得复位异常中断向量。
2、执行复位异常中断向量。如:LDR PC,=0x0f000004
3、设置地址重映射寄存器REMAP=1,重新将RAM映射到地址0x00开始的空间。
4、完成其他的初始化代码。
二、系统初始化
系统的初始化部分包括两个级别的操作:
系统运行环境初始化。
应用程序初始化。
A、系统运行环境初始化
对于嵌入式应用系统和具有操作系统支持的应用系统来说,相同运行环境初始化部分的工作时不同的。对于有操作系统支持的应用系统来说,在操作系统启动时将会初始化系统的工作环境。操作系统在加载应用程序后,将控制权转交到应用程序的main()函数。然后,C运行时库的_main()初始化应用程序。而对于嵌入式应用系统来说,由于没有操作系统的支持,存放在ROM的代码必须进行所有的初始化工作。
系统运行环境的初始化工作主要包括一下的内容:
1、设置初始入口点。
初始入口点是映象文件运行时的入口点,每个映像文件只有一个唯一的初始入口点,它保存在ELF头文件中。如果映像文件是被操作系统加载的,操作系统正是通过跳转到该初始入口点处执行来加载该映像文件的。初始入口点必须满足下面两个条件:
a、初始入口点必须位于映像文件的可执行区域。
b、包含初始入口点的可执行域不能被覆盖,它的加载时地址和运行时地址必须是相同的。(这种域称为固定域root region)
<script type="text/javascript"> </script> <script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"></script>
2、设置中断向量表
如果系统运行时,地址0x00处为ROM,则相同的异常中断向量表是固定的,程序在运行过程中不能修改异常中断向量表。
如果系统运行时,地址0x00处为RAM,则系统初始化时必须重建异常中断向量表。
3、初始化存储系统
4、初始化数据栈指针
5、初始化关键的IO设备
指那些必须在使能IRQ和IFQ之前进行初始化的IO设备。
6、设置中断昔日需要的RAM变量
7、使能异常中断
通过清楚CPSR寄存器的中断禁止位实现。
8、切换处理器模式
直到目前为止,系统还处于特权模式。如果下面要运行的应用程序是在用户模式下运行,就需要将处理器切换到用户模式。
9、切换程序状态
所有的RAM内核都是从ARM状态开始执行的。
B、应用程序初始化
1、将已经初始化的数据搬运到可写的数据区。
<script type="text/javascript"> </script> <script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"></script>
在嵌入式系统中,已经初始化的数据在映像文件运行之前通常保存在ROM中,在程序运行过程中这些数据可能需要被修改。因而,在映像文件运行之前需要将这些数据搬运到可写的数据区。这部分数据就是映像文件中的RW属性的数据。
2、在可写存储区建立ZI属性的可写数据区。
通常在映像文件运行之前,也就是保存在ROM时,映像文件中没有包含ZI属性的数据。在运行映像文件时,在系统的可写的数据区建立ZI属性的数据区。
如果应用程序中包含了函数main(),编译器在编译该函数时,将引言符号_main。这样,连接器在连接时将包含C运行时库中的相应内容。_main可以完成这部分应用程序的初始化。
如果应用程序中没有包含函数main(),应用程序中需要包括进行这部分应用程序的初始化。