NAND FLASH
本身是连接到了控制器上而不是系统总线上。CPU
运行机制为:CPU
启动后是要取指令执行的,如果是SROM
、NOR FLASH
等之类的,CPU
通过地址线发个地址就可以取得指令并执行,NAND FLASH
不行,因为NAND FLASH
是管脚复用,它有自己的一套时序,这样CPU
无法取得可以执行的代码,也就不能初始化系统了。
NAND FLASH
是顺序存取设备,不能够被随机访问,程序就不能够分支或跳转,这样你如何去设计程序。
U-BOOT
支持ARM
、 PowerPC
等多种架构的处理器,也支持Linux
、NetBSD
和VxWorks
等多种操作系统,主要用来开发嵌入式系统初始化代码 bootloader
。bootloader
是芯片复位后进入操作系统之前执行的一段代码,完成由硬件启动到操作系统启动的过渡,为运行操作系统提供基本的运行环境,如初始化CPU、堆栈、初始化存储器系统等,其功能类似于PC机的BIOS。
椐了解 NOR FLASH
是容量小,速度快,稳定性好,适合做程序存储器。
NAND FLASH
总容量大,适合做数据存储器是不能从NAND FLASH
启动的,NAND FLASH
是的读写时序是不能直接有ARM
硬件产生的,要读写NAND FLASH
是要通过程序来实现的,很明显能看出来的就是NAND FLASH
只有8个数据、地址复用的数据地址接口。2410/2440
可以直接从NAND FLASH
启动的,因为它把NAND
前面的4K
映射到了RAM
的空间
Flash种类
NOR FLASH
地址线和数据线分开,来了地址和控制信号,数据就出来。NAND Flash
地址线和数据线在一起,需要用程序来控制,才能出数据。通俗的说,就是光给地址不行,要先命令,再给地址,才能读到NAND
的数据。而且都是在一个总线完成的。
结论是:ARM无法从NAND
直接启动。除非装载完程序,才能使用NAND Flash
,装载程序只能从mask rom
或者Nor flash
。
三星的2410
可以从NAND FLASH
启动程序,它会把第一块的前4KB
复制到内部SRAM
中然后从SRAM
执行,也就是说你需要编写一个长度小于4K
的引导程序,作用是将主程序拷贝到SDRAM
中运行(NAND FLASH
地址不是线性的,程序不能直接运行,必须拷贝到线性RAM中)
需要检测硬件启动方式,启动方式是由硬件OM0
管脚决定的,软件无法检测硬件电平状态,但可以根据CPU
的启动特性来检测。
如果配置为NAND FLASH
启动(启动模式选择开关拔到nand
端,此时OM0
管脚拉低)S3C2440
的NAND
控制器会自动把NAND FLASH
中的前4K
代码数据搬到内部SRAM
中(地址为0x40000000
),同时还把这块SRAM
地址映射到了0x00000000
地址。CPU
从0x00000000
位置开始运行程序。 (从NAND FLASH
启动CPU
时,CPU
会通过内部的硬件将NAND FLASH
开始的4KB
数据复制到称为“Steppingstone”
的4KB
的内部RAM
中(起始地址为0),然后跳到地址0开始执行)
如果配置为NOR FLASH
启动(启动模式选择开关拔到nor
端,此时OM0
管脚拉高),0x00000000
就是NOR FLASH
实际的起始地址,NOR FLASH
中的程序就从这里开始运行,不涉及到数据拷贝和地址映射。
NAND
启动时,地址0x00000000
为内部SRAM
映射的地址;NOR
启动时,地址0x00000000
为NOR FLASH
的实际起始地址。向NOR FLASH
中写数据需要特定的命令时序,而向内存中写数据可以直接向内存地址赋值。对于S3C2440
处理器 M[1:0]
选择01
或 10
时:norflash
基地址为0x00000000
,SRAM
顶端地址0x40000FFF
。上电后处理器直接从0x00000000
处取出指令,arm
处理器的SP
(堆栈指针寄存器)指向0x40000FFF
。
OM[1:0]
选择00
,S3C2440
会启用内部的SRAM
缓冲器会将nand flash
中的前4KB
大小的程序自动拷贝到SRAM
中。SRAM
基地址0x00000000
,顶端0x00000FFF
。上电后,arm
处理器从0x00000000
取出第一条指令,arm
处理器的SP
(堆栈指针寄存器)指向0x00000FFF
。
如果S3C2410
被配置成从Nand Flash
启动(配置由硬件工程师在电路板设置),S3C2410
的Nand Flash
控制器有一个特殊的功能,在S3C2410
上电后,Nand Flash
控制器会自动的把Nand Flash
上的前:4K
数据搬移到4K
内部RAM
中,并把0x00000000
设置内部RAM
的起始地址,CPU
从内部RAM
的0x00000000
位置开始启动。这个过程不需要程序干涉。程序员需要完成的工作,是把最核心的启动程序放在Nand Flash
的前4K
中。
那么当程序大于 4k
的时候,当我们以 nand flash
启动后,前面的4Kb
被拷贝到 片内SRAM
中去执行(自动完成)。我们在这前4K
的程序中初始化SDRAM
(SDRAM 使用前需要初始化) ,然后将剩下的程序拷贝到 SDRAM
中(不是只有4kb
被拷贝到片内SRAM
中执行了嘛)然后跳转到 SDRAM
中去执行剩下的程序。
那么也就是说 通常当程序大于 4kb
的 时候,我们就需要把程序拷贝到SDRAM
中去运行。(程序小于4KB
那么也就可以不用拷贝了,以nand flash
方式 启动后,程序全被拷贝到 片内4kb
的 SRAM
中去运行。)
那么,既然程序大于4kb
的时候需要从nand flash
中拷贝到 SDRAM
中去运行。自然可以想到 烧到nand flash
中的程序前面一部分代码应该 是初始化SDRAM
(程序最终需要拷贝到SDRAM
中去运行)和 将NAND flash
中的剩余的程序拷贝到SDRAM
中去(全考过去也行,方便点),然后跳转到SDRAM
中执行。
由于Nand Flash
控制器从Nand Flash
中搬移到内部SRAM
的代码是有限的,所以在启动代码的前4K
里,我们必须完成S3C2410
的核心配置以及把启动代码(U-BOOT)剩余部分搬到RAM
中运行。
u-boot
源码不支持从nand flash
启动,可是s3c2410
支持从nand flash
启动,开发板(sbc-2410x
)加电后s3c2410
将nand flash
的前4k
(保存有u-boot
的部分功能–拷贝功能–把nand flash
中的内容拷贝到SDRAM
)拷贝到sram
(s3c2410
芯片内的sram
)。这就需要修改u-boot
源码,增加u-boot
的功能,使u-boot
在得到执行权后能够将其自身拷贝到开发板上SDRAM
中,以便处理器能够执行u-boot
。
Nand Flash
的命令、地址、数据都通过I/O口发送,管脚复用,这样做的好处是,可以明显减少NAND FLASH
的管脚数目,将来如果设计者想将NAND FLASH
更换为更高密度、更大容量的,也不必改动电路板。
用NOR
启动时,片内的存储控制器的BANK0-BANK7
这8个BANK都对应了其他用途,所以设计者在BANK7
结束的地址0x40000000
的地方作为NOR FLASH
的启动地址,而NAND FLASH
启动的地址则是0x00000000
。
因为对于启动文件.S
来说,4K
的空间是足够存放,代码段、BSS…和堆栈段了,因为堆栈的SP
是从高地址往低地址移动的,所以要将堆栈的起始地址放在堆栈段的高地址。
也可以不用设置成4096
,但要保证堆栈的长度不能和下面其他段重叠,若重叠,就会出BUG
,保险值是4096
(4K,见上图),因为SRAM
就是4K
设计的。