文档介绍:
启动部分的代码功能可以分成5部分来看,代码搬移与重定位、中断向量表及相关跳转设置、初始化硬件、初始化堆栈、C的main函数入口设定。以下就对这几个部分来分析
代码搬移与重定位
首先要搞明白编译链接的结果、RO,RW,ZI段、加载域、运行域。RO就是read only,RW就是read/write,ZI就是zero。程序在经过keil的编译后就成了二进制代码,每段代码的RO、RW、ZI属性在这时就已经由程序与编译器确定下来了,代码的链接由keil的分散加载文件来设置。在链接完成之后形成的bin文件称为映像文件,这是实际烧写到芯片中的文件,也就是加载域。所有的RO段都被放在了映像文件的最前端,RW端紧跟着RO段,ZI段紧跟着RW段。在实际运行的过程中,RO段应该重新定位在ROM,而需要反复读写的RW与ZI段应该放在RAM中,这才是芯片实际运行的程序结构,这就是运行域。在keil中已经由用户配置好了RO的起始地址与RW的起始地址,就是变量|Image$$RO$$Limit|、|Image$$RW$$Base|、|Image$$ZI$$Base|,这几个变量的计算值如下
|Image$$RO$$Limit|=程序代码起始地址+代码长度(编译器计算出来的)+1
|Image$$RW$$Base| = RW base 地址指定
|Image$$RW$$Limit| =|Image$$RW$$Base|+ RW Data(编译器计算出来的)
|Image$$ZI$$Base| = |Image$$RW$$Limit| + 1
|Image$$ZI$$Limit| = |Image$$ZI$$Base| + ZI Data(编译器计算出来的)
C中的指令以及常量被编译后视RO类型数据
C中的未被初始化或初始化为0的变量编译后是ZI类型数据
C中的已被初始化成非0值的变量编译后是RW类型数据
S3C2440有三种启动运行模式,一是从norflash启动,二是从nandflash启动,三是用仿真器直接从内存启动。
从norflash启动。Norflash是可以直接运行代码的,从norflash启动,S3C2440的bank0地址空间就映射到了norflash上,从0地址开始运行,,有一段代码(就是copy_proc_beg)的作用是把代码从norflash搬运到sdram,并进行重定位,这段代码运行结束后,PC指针就从norflash跳到了sdram中的同一个位置,实现了加载域到运行域的无缝连接。
0x30000000
RO
RW
ZI
RO
RW
ZI
0x40000000
0x00000000
copy_proc_beg
copy_proc_beg
PC
PC
重定位
搬运
norflash
sdram
从nandflash启动。Nandflash是不可以直接运行代码的,所以在arm上电之后,有一个4k大小的称之为steping stone的东西会把nandflash中的前4k代码复制过来,这部分工作是由硬件自动实现的,于是这4k代码开始运行,依旧是从0地址开始。这4k代码检测到时nandflash启动,就先由nand_boot_