S3C2410X有两种启动方式:NOR flash启动和NAND flash启动。NOR flash启动:NOR flash可以象SDRAM那样随机读取,且读取速度快,不但可以存储程序,还可以运行程序。上电复位时,NOR flash被映射到地址0x0处,程序就可以从NOR flash中的第一条语句开始执行。程序即可以在NORflash运行,也可以复制到SDRAM中运行。NAND flash启动:NAND flash容量大、价格低,广泛应用于嵌入式系统中。S3C2410X集成了NAND flash控制器,可方便编程。但是,NAND flash随机读取速度慢,需专用I/O接口,只能存储程序,无法运行程序。为了能够从NAND flash启动,上电复位时,S3C2410X通过硬件逻辑把NAND flash的前4KB的内容复制到片内SRAM中,而片内SRAM被映射到地址0x0,这样就可以从地址0x0处取到有效指令。因此,采用NAND flash启动时,必须利用片内SRAM中的代码把NAND flash中的程序代码复制到SDRAM中去。
这里,笔者参考了引导装入程序(Bootloader)的方式,把代码分成两部分,第一部分作为引导代码,包括ARM所要求的连续8个字的中断向量表。它主要负责把NAND flash中的程序代码复制到SDRAM中,其代码远小于4KB。第二部分是应用程序。调试时可分别单独调试,互不影响。调试完成后,分别烧写,引导代码的RO_Base设置为0x0,烧写到NANDflash的第0块。第二部分应用程序的RO_Base设置为0x3000,0000,烧写到NAND flash第一块开始的地址空间。上电复位时,引导代码由硬件逻辑复制到片内SRAM中,于是,ARM所要求的连续8个字的中断向量表就位于0x0地址开始的连续空间内。接着从第一条指令开始执行,除了一些必要的初始化以及设置中断向量表,它把NAND flash中第一块开始的程序代码复制到起始地址为0x3000,0000的SDRAM中。地址0x3000,0000既是RO_Base的地址,也是SDRAM在整个地址空间的起始地址。复制完成后,引导代码也该结束退出了,退出之前需调整PC指针,为了简单起见,把PC指针直接调整到地址0x3000,0000,即从应用程序的启动代码开始执行。需要注意的是,引导代码把中断向量表复制到SDRAM中_ISR_StartAddress处即地址0x30ffffff,而应用程序的启动代码也把中断向量表复制到SDRAM中同一地址_ISR_StartAddress处。这样,当异常发生时,PC指针首先跳到地址0x0开始8个字的异常向量
表,这是在片内SRAM的引导代码里。接着,跳到SDRAM中的中断向量表,这是在应用程序里,然后转到中断处理程序,PC指针的跳转跨越了两部分程序。引导代码和应用程序在存储空间和NAND flash的分布情况如图所示。实现复制和PC指针调整的代码如下 :
IMPORT nand_read_ll ;引入外部C函数
ldr r0, =SDRAM_Base_Address ;r0指向SDRAM的基地址,即地址0x3000,0000
mov r1, =APP_Start_ Address ;r1指向NAND_flash中应用程序的开始地址;即第1块的开始地址
mov r2, =APP_End_ Address ;r2指向NAND_flash中应用程序的结束地址
bl nand_read_ll ;调用复制函数开始复制
ldr r12, =SDRAM_Base_Address
mov pc, r12 ;pc指向SDRAM的基地址;引导代码到此结束,接着从应用程序启动代码的第一条语句开始执行。
同样道理,NOR flash启动也可以采用这种方式,不同的是,引导代码在NOR flash中,它把NOR flash中的程序代码复制到SDRAM中,然后,也是跳到SDRAM中开始执行。