关于arm启动代码的启动流程(转载)
本文非原创,侵删,原文链接:http://m.blog.csdn.net/blog/yc550370460/8659752#
首先,申明主要阐述针对使用scatter文件的启动代码的执行流程,若有纰漏,还请斧正!
MCU是怎么知道首先从启动代码开始执行的呢?又怎么知道从启动代码那一句开始执行呢?
解释如下:
首先打开scatter文件,举例如下:
LR_ROM1 0x00000000 0x00200000 { ; load region size_region
ER_ROM1 0x00000000 0x00200000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
}
RW_RAM1 0x30000000 0x10000000 { ; RW data
.ANY (+RW +ZI)
}
RW_IRAM1 0x40000000 0x00001000 {
.ANY (+RW +ZI)
}
}
上面的那一句 *.o (RESET, +First)就表明了启动代码的首次执行地址。具体来说就是表明了RO执行域名称为ER_ROM1 ,
开始地址为0x00000000 ,长度为0x00200000,首次执行的地址为RESET标号所表示的地址。
更详细的请参看:how does startup code work。
当然,第一条语句执行之后,后面的工作请参看网上的资料,这类资料一大堆。
另外一个关于启动代码的执行域和加载域的问题。
现在流行的开发板都包括有nandflash和norflash启动两种,那么各自的启动方式所对应的加载域和执行域是怎样的?
以mini2440为例。
norflash启动:
首先表明,norflash一般当成传统的ROM使用,从norflash启动时,norflash被映射到0x0地址,大小为2M。
此时的加载域为从0x0开始依次为RO,RW,但是由于norflash由于速度原因不能用作RAM,所以,程序执行的时候,
RW区需要搬运到SDRAM中,RO区域不能进行搬运,原因见下。具体的搬运过程请参考各版本的启动代码。
而具体搬运到哪,看scatter文件,以上为例(上例中RO未进行搬运)。
LR_ROM1 0x00000000 0x00200000 { ; load region size_region
ER_ROM1 0x00000000 0x00200000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
}
RW_RAM1 0x30000000 0x10000000 { ; RW data
.ANY (+RW +ZI)
}
RW_IRAM1 0x40000000 0x00001000 {
.ANY (+RW +ZI)
}
}
可知,RO未进行搬运,因为加载域和执行域的起始地址相同,但是RW区已经发生了改变,执行域的RW区起始地址为0x30000000 。
RO在启动代码实现中可以进行搬运到SDRAM,便于取指迅速,RW根据上述设定,必须搬运到SDRAM中。
注意:The symbols Image$$RW$$Base, Image$$RW$$Limit , Image$$RO$$Base, Image$$RO$$Limit,
Image$$ZI$$Base, and Image$$ZI$$Limit are not defined when a scatter-loading description file is used.
那么什么时候能用呢,当然是scatter文件不用的时候,如果不用scatter文件,那么执行域的RO和RW起始地址和加载域的RO
和RW在哪里指定呢?
如下图所示:
RO和RW的load region是参考ROM1来进行设置的,猜测应该是紧邻。
而RW和ZI以及RO的执行域是参照ROM1和RAM1来进行设置的,RW和ZI会进行数据拷贝,从ROM到RAM中,而由于RO用作固定域
所以不能进行移动,继续留在ROM中(ROM右侧选中了startup选项),所以我猜测《ARM处理器裸机开发实战》中关于ADS中设置
入口点为0x30000000是值得商榷的,个人觉得应该为__ENTRY,因为一个文件中只能存在一个ENTRY。而关于入口点也就自然,是
从ROM的RO中的域的ENTRY了。(注意:如果源文件中存在多个ENTRY,编译器会报错!)。
说明:关于加载域的起始地址和长度限定值等,个人猜测,IDE会根据ROM和RAM的位置进行自动设置。
nandflash启动:
由nandflash启动的话,硬件会自动将4K代码拷贝到SDRAM中,然后在启动代码中将NANDFLASH所有代码拷贝到SDRAM中,同时根据
scatter文件,或者不用scatter文件设置ROM和RAM,如上图,进行加载域到执行域的拷贝(包括RO,RW,ZI),当然是在SDRAM内部进
行的,所以NANDFLASH启动的加载域和执行域均在SDRAM中。具体详见各启动代码详解。但是固定域一定在SRAM中,只是系统已经启
动,再也用不着了。