S3C2440启动代码中应用程序执行环境的初始化

一、基础知识
          我们编写的源文件(.c 或.s)经过ARM 编译器的编译生成ELF 格式的目标文件(后缀名为.o),目标文件经过ARM 连接器连接以后生成ELF 格式的映像文件(后缀名为.axf),此时的映像文件还包含一些调试信息,我们还需要通过fromelf 工具将其转换成适合在ROM 或RAM 中运行的二进制代码(后缀名为.bin),这时生成的二进制映像文件就可以被烧写入目标板的ROM 或FLASH 中,当目标板上电后可以通过各种方式在ROM 或RAM 中运行。
一个可执行程序的映像文件由一个或多个域组成,域分为两种:一种是映像文件在存储器中存放的地址,称为加载域;另一种是映像文件运行时的地址,称为运行域。每个域由一个或3 个输出段组成,每个输出段则由一个或多个输入段组成。输入段包含程序代码、已经初始化的数据、未经初始化的存储区、被初始化为0 的存储区,输入段据此可分为三种属性:RO(只读,包括代码和常量)、RW(可读可写,包括已经初始化的全局变量和静态变量)、ZI(未初始化的变量,需初始化为0), 连接器根据属性将输入段分组,组成不同的输出段。一个输出段是有具有相同属性的输入段组成的,输出段的属性与其中输入段的属性相同,因而输出段也分为三种。域由不同属性的输出段组成,输出段在域中的排列顺序为RO 输出段排在最前,然后是RW 输出段,RW 输出段和RO 输出段可以不连续,最后是ZI 输出段,ZI 输出段是紧接着RW 输出段的(加载域只包含RO、RW 输出段,原因见后述)。
可执行镜像一开始一般是存储在系统的ROM 或FLASH 中,RO 段是只读的,在运行的时候我们不能改变它,所以RO 段在运行的时候可以驻留在ROM 或FLASH 中,也可以拷贝到运行速度更快的RAM 中;RW 段在运行的时候,我们需要对其读写,在运行前这一段必须被拷贝至RAM 中;ZI 段为未初始化的全局变量段,只需要在程序运行之前建立ZI 并将其所在区域全部清零即可,因此镜像装载域不必包含ZI 输出段,但在运行域需要包含ZI,并且ZI 必须处于RAM。
通过以上说明,我们知道如果某个镜像只有RO 段的话,程序可以不必拷贝至RAM,但是如果程序包含RW 段的话,RW 段是必需要拷贝至RAM 中的,如果有必要的话还需在RAM 中创建ZI 段,并将其清零。为保证程序的正确执行,而进行必要的数据拷贝和清零,就是应用程序执行环境的初始化。

二、S3C2440启动的基本原理

Nand Flash启动
当S3C2440 开发板采用的是Nand Flash 启动,镜像一开始是存储在Nand Flash 中,而Nand Flash只能作为存储程序和数据之用,无法在其中运行程序,所以S3C2440 开发板启动代码中应用环境初始化这一步和上述步骤稍有不同。S3C2440 镜像文件加载和运行时的地址映射关系如下图所示:


S3C2440 没有上电之前映像文件存储在Nand Flash 中,Nand Flash 有专门的控制器控制,不占用存储器BANK。当开发板上电时,Nand Flash 的前4K 被复制到S3C2440 芯片内部的一块容量为4K 的SRAM(被称为“Steppingstone”),然后这块SRAM 被映射到地址0x00000000 处,程序从此处开始运行。因为Nand Flash 中不能运行程序,所以在这4K 的代码中必须包含一段代码将Nand Flash 中的程序拷贝至S3C2440 的SDRAM 中(0x30000000 开始)。应用环境初始化应该包含这段代码。
Nand Flash 中的映像文件被拷贝至从0x30000000 开始的SDRAM,这时候映像文件还没有真正被执行,此时是加载状态,加载域如上图所示,包括所有RO 属性的输出段和RW 属性的输出段,ZI 属性的输出段此时还不存在。在映像文件运行时,会生成3 个运行域,如上图所示,RO 和RW 属性的运行域的起始地址和加载时是相同的,所以在应用程序执行环境初始化中不需要对其进行拷贝,ZI 运行域则需要在映像开始被执行前建立并被初始化为0,所以应用程序执行环境初始化中也要包含这类代码。(注意:RO 和RW 属性的运行域的起始地址和加载时是相同的,即拷贝到SDRAM后就不用再移动了。ADS中设置的RO Base和RW Base决定了程序的链接地址)
Nor Flash启动
当S3C2440采用Nor Flash启动时,代码可以在上面直接运行。但为了运行的效率,还是把程序拷贝到SDRRAM中运行。加载时地址关系和运行时地址关系和Nand Flash的基本相似。Nand Flash启动时,会将RO段和RW段同时拷贝到SDRAM中,然后再建立ZI段。从Nor Flash启动时是先拷贝RO段,然后再拷贝RW段,最后建立ZI段。

三、相关启动代码分析

;一个arm 程序是由R0,RW,ZI 三个段组成。其中R0 为代码段,RW 是已经初始化的全局变量,ZI 是未
;初始化的全局变量,启动代码要将RO段和RW段复制到RAM 中并将ZI 段清零。编译器使用下列变量
;来记录各段的起始地址和结束地址。这些标号的值是通过编译器的设定来确定的如ADS中对ro-base 和
;rw-base 的设定。
IMPORT  |Image$RO$Base|	; Base of ROM code
IMPORT  |Image$RO$Limit|  ; End of ROM code (=start of ROM data)
IMPORT  |Image$RW$Base|   ; Base of RAM to initialise
IMPORT  |Image$ZI$Base|   ; Base and limit of area
IMPORT  |Image$ZI$Limit|  ; to zero initialise


;===========================================================
	
	ldr	r0, =BWSCON
	ldr	r0, [r0]
	ands	r0, r0, #6	;通过判断OM[1:0] != 0, 得知是NOR FLash boot
	bne	copy_proc_beg	;不用读取 nand flash
	adr	r0, ResetEntry	;OM[1:0] == 0, 从NAND FLash 启动
	cmp	r0, #0		;再比较入口是否为0地址处,如果不是则用了仿真器
	bne	copy_proc_beg	;用仿真器的情况也不要用 nand flash启动
	;nop
;===========================================================
nand_boot_beg  ;这一段代码完成从NAND读代码到RAM
	[ {TRUE}
		bl RdNF2SDRAM
	]


	ldr	pc, =copy_proc_beg  ;此时的PC已经在0x30000000以后,是copy_proc_beg连接时的地址
;这个标号下面的代码完成的功能就是把nor flash 的内容拷贝到ram 当中。
;===========================================================
copy_proc_beg
	adr	r0, ResetEntry 		 ;装载地址,ResetEntry值->r0
	ldr	r2, BaseOfROM 		 ;BaseOfROM值
	cmp	r0, r2  			 ;比较RO,R2
	ldreq	r0, TopOfROM 	 ;如果相等的话(说明在内存中运行),TopOfROM->r0   当从Nand Flash中启动时r0=r2,当从Nor Flash启动时则不相等
	beq	InitRam        			 ;同时跳到InitRam	
;下面这个是针对代码在NOR FLASH时的拷贝方法
;功能为把从ResetEntry起,TopOfROM-BaseOfROM大小的数据拷到BaseOfROM
;TopOfROM和BaseOfROM为|Image$RO$Limit|和|Image$RO$Base|
;|Image$RO$Limit|和|Image$RO$Base|由连接器生成为生成的代码的代码段运行时的起启和终止地址
;BaseOfBSS和BaseOfZero为|Image$RW$Base|和|Image$ZI$Base|
;|Image$RW$Base|和|Image$ZI$Base|也是由连接器生成,两者之间就是初始化数据的存放地放
	ldr r3, TopOfROM
0	
	ldmia	r0!, {r4-r7}
	stmia	r2!, {r4-r7}
	cmp	r2, r3
	bcc	%B0
	
	sub	r2, r2, r3  ;这两句代码是修正字非对齐的情况,因为是按4个字节拷贝的,但RO段大小不一定是4个字节对齐的
	sub	r0, r0, r2				
		
InitRam	
	ldr	r2, BaseOfBSS
	ldr	r3, BaseOfZero	
0
	cmp	r2, r3
	ldrcc	r1, [r0], #4
	strcc	r1, [r2], #4
	bcc	%B0	;这一段是对ResetEntry 里面定义好的数据拷贝到RW 段。


	mov	r0,	#0
	ldr	r3,	EndOfBSS
1	
	cmp	r2,	r3
	strcc	r0, [r2], #4
	bcc	%B1    ;初始化ZI段
	
	ldr	pc, =%F2		;goto compiler address
2
	
;	[ CLKDIV_VAL>1 		; means Fclk:Hclk is not 1:1.
;	bl	MMU_SetAsyncBusMode
;	|
;	bl MMU_SetFastBusMode	; default value.
;	]


    [ :LNOT:THUMBCODE
 		bl	Main	;不要用main()因为main()是ADS默认入口,编译器会添加其他代码
 		b	.      ;跳转到Main不成功则挂起
    ]


    [ THUMBCODE	 ;for start-up code for Thumb mode
 		orr	lr,pc,#1
 		bx	lr
 		CODE16
 		bl	Main	;Do not use main() because ......
 		b	.
		CODE32
    ]


BaseOfROM	DCD	|Image$RO$Base|
TopOfROM	DCD	|Image$RO$Limit|
BaseOfBSS	DCD	|Image$RW$Base|
BaseOfZero	DCD	|Image$ZI$Base|
EndOfBSS	DCD	|Image$ZI$Limit|



mini2440的nor flash与nand flash启动过程区别

一、调试经验

1.一位老电脑科学家的提示:当你遇到怪问题时,重启是一种最简单的解决办法之一。因为操作系统本身有不完善之处,不管是微软视窗还是苹果电脑。

2.USB转口线出现乱码问题:说明串口线的功能和性能不稳定。可购买性能好的代替之。

二、问答

1.什么是nand,什么是nor?nand启动与nor启动的区别及联系。(收集整理)

答:1)在NOR FLASH里面可以直接执行代码,而在NAND FLASH里面不可以,在2410里面,如果选择NAND启动方式的话,NAND里的代码是被拷贝到RAM里面去执行的。

2)NAND FLASH每次取数据前要写入好像是0X55,0XAA才行,而NOR FLASH直接取到数据。

3)NOR FLASH地址线和数据线分开,来了地址和控制信号,数据就出来。NAND Flash地址线和数据线在一起,需要用程序来控制,才能出数据。

2.如何开机进入BIOS模式?

答:将S2跳转开关打至nor flash端即可。

3.使用supervivi作为bootloader.而有些开发板使用uboot

4.SEC s3c241x什么意思?

三、ARM的nor flash与nand flash启动过程区别

s3c2440启动过程详解
1:地址空间的分配
2:开发板上一般都用SDRAM做内存flash(nor、nand)来当做ROM。其中nand flash没有地址线,一次至少要读一页(512B).其他两个有地址线
3:nandflash不用来运行代码,只用来存储代码,NORflash,SDRAM可以直接运行代码)
4:s3c2440总共有8个内存banks
  6个内存bank可以当作ROM或者SRAM来使用
  留下的2个bank除了当作ROM 或者SRAM,还可以用SDRAM(各种内存的读写方式不一样)
  7个bank的起始地址是固定的
  还有一个灵活的bank的内存地址,并且bank大小也可以改变
5:s3c2440支持两种启动模式:NAND和非NAND(这里是nor flash)。
具体采用的方式取决于OM0、OM1两个引脚
OM[1:0]所决定的启动方式
OM[1:0]=00时,处理器从NAND Flash启动
OM[1:0]=01时,处理器从16位宽度的ROM启动
OM[1:0]=10时,处理器从32位宽度的ROM启动。
OM[1:0]=11时,处理器从Test Mode启动。

6.开发板出厂时已经在nand flash,nor flash烧入了相同的BIOS。


当从NAND启动时

    cpu会自动从NAND flash中读取前4KB的数据放置在片内SRAM里(s3c2440是soc),同时把这段片内SRAM映射到nGCS0片选的空间(即0x00000000)。cpu是从0x00000000开始执行,也就是NAND flash里的前4KB内容。因为NAND FLASH连地址线都没有,不能直接把NAND映射到0x00000000,只好使用片内SRAM做一个载体。通过这个载体把nandflash中大代码复制到RAM(一般是SDRAM)中去执行


当从非NAND flash启动时

    nor flash被映射到0x00000000地址(就是nGCS0,这里就不需要片内SRAM来辅助了,所以片内SRAM的起始地址还是0x40000000). 然后cpu从0x00000000开始执行(也就是在Norfalsh中执行)。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值