norflash/nandflash 启动分析


S3C2440和S5PV210是很多嵌入式爱好者入门的arm处理器,网上的资料也很多。今天我们就来聊聊S3C2440和S5PV210的启动流程,上一篇博客我介绍了uboot在norflah上的启动流程(重要!这是基础)。今天,我们来聊聊uboot在nandflash上的启动流程。

一. nandflash 与 norflash

        同样,你现在肯定心里有疑问 何为norflash?何为nandflash? 他们之间有什么异同?

        norflash我上篇博客已经介绍了(再重复一下吧)

1.norflash

        norflash:norfalsh是非易失存储器(失去电源供电后norflash里存储的数据依然存在),NORflash带有SRAM接口,有足够的地址引脚来寻址,可以很容易地读取其内部的每一个字节(注意是读取!对于flash不是随意可以写入,一般写入NOR flash流程是:解保护->擦除->写入数据。由于flash特性只能从1翻转到0,无法从0翻转1。擦除过程就是将flash中的某一个扇区全写0xFFFFFFF,再写入数据),代码指令可以直接在norflash上运行。(重要! 上电后可以读取norfalsh中的数据 写操作无法直接进行 前面我已经说得很清楚了)

        多啰嗦几句,对于norflash来说,arm处理器上电后就可以直接读取里面的数据(NORflash带有SRAM接口,有足够的地址引脚来寻址,可以很容易地读取其内部的每一个字节),但是!注意但是!!不能直接写入数据!!!你可以把他看作一个只能<直接>读取的SRAM(只读SRAM)。

2.nandflash

       nandflash:其内部采用非线性宏单元模式,为固态大容量内存的实现提供了廉价有效的解决方案。Nand-flash存储器具有容量较大,改写速度快等优点,适用于大量数据的存储。然而NANDFlash的I/O接口并没有随机存取外部地  址总线,它必须以区块性的方式进行读取。

        现在总结一下:norflash带有SRAM接口,有足够的地址引脚来寻址,可以很容易地<读取>其内部的每一个字节。

        nandflash的I/O接口并没有随机存取外部地址总线,无法向SRAM随机访问地址上的数据。              

    (了解启动流程,有以上的概念就足够了!具体怎么去取nandflash中的数据,下一篇博客我单独讲解)

 

二. S3C2440 处理器启动流程

    本人英语也不太好,六级没过,说多了都是泪。想看芯片中文数据手册的朋友可以百度

     <S3C2440全套中文手册(1-27章).PDF>,翻译得挺不错! 赞一个!!

    (比S3C6410中文数据手册翻译得好太多,S3C6410中文数据根本就没法看)

     我从三星S3C2440处理器的数据手册中摘出了芯片的存储器映射表,如下图所示:


       从图中可以看出OM[1:0]在选择不同值时,地址映射关系是不同的。

       当OM[1:0]选择01 或 10时,在SROM(nGCS0)外接的一定是norflash。处理器上电后从0x00000000处取出第一条指令,将ARM处理器的SP(堆栈指针寄存器设置到0x40000FFF处)。norflashBootSRAM搭建的程序运行环境中完成时钟和DDR等初始化。

         (启动流程和我前一篇介绍的启动流程是一样的)  

当OM[1:0]选择00,S3C2440内置的SRAM缓冲器会将nandflash中的前4KB大小的程序自动拷贝到BootSRAM中。之后,处理器从0x00000000处开始执行程序。

          (数据手册上就是这么写的! 但是!!) 

     现在问题又来了:

      1. S3C2440内置的SRAM缓冲器到底是什么?

      2.为什么一定要有内置的SRAM缓冲器才能从nandflash中启动程序?

      

      每次用开发板的时候,人家就告诉你把拨码开关拨到01或10状态从norflash启动,把拨码开关拨到00状态从     nandflash启动。(但是你想过这上面的问题吗?)         

1.S3C2440内置的SRAM缓冲器到底是什么?

       S3C2440内置的SRAM缓冲器方框图 如下图所示:                                                                                                                                                                    

          S3C2440A 引导代码可以在外部 NAND Flash 存储器上执行。 为了支持 NAND Flash 的 BootLoader, S3C2440A配备了一个内置的 SRAM 缓冲器,叫做“Steppingstone” 。引导启动时,NAND Flash 存储器的开始 4K 字节将被加载到 Steppingstone 中并且执行加载到 Steppingstone 的引导代码。                                                          

      通常引导代码会复制 NAND Flash 的内容到 SDRAM 中。通过使用硬件 ECC,有效地检查 NAND Flash 数据。在复制完成的基础上,将在 SDRAM 中执行主程序。                                                                                                                                                                                                                                                                                                                                          

         当复位时,NAND Flash 控制器将通过引脚状态(NCON(先进闪存), GPG13(页大小),GPG14(地址周期),GPG15(总线宽度)—请参考引脚配置)来获取连接的 NAND Flash 的信息,在发生掉电或系统复位后,NAND Flash控制器自动加载 4K 字节的 BootLoader 代码。在加载完 BootLoader 代码后,Steppingstone 中的 BootLoader 代码已经执行了。

(当自动引导启动期间,ECC 不会去检测,所以,NAND Flash 的开始 4KB 不应当包含位相关的错误。)

       看完上面一大段我摘取自数据手册的资料(maybe  你可能依然思路不是很清晰)

       我来总结一下:对于norflash带有sram的接口,上电后处理器可以从0x00000000处读取出需要执行的指令。但是,换成nandflash处理器上电后无法直接读取里面的指令(nandflash根本没有在处理器地址空间上映射的地址,只能通过nandflash控制器去读取)。S3C2440的解决方案就是:内置一个SRAM 缓冲器(Steppingstone),上电后SRAM缓冲器自动去将nandflash中的前4KB大小的数据给拷贝到芯片内置的BootSram中(注意!! 芯片设计时,内部硬件实现,与我后面提到的bootrom无关)。之后,处理器从BootSram中取出指令。

2. 为什么一定要有内置的SRAM缓冲器才能从nandflash中启动程序?

         所以,当OM[1:0]选择00,S3C2440会启用内部的SRAM缓冲器会将nandflash中的前4KB大小的程序自动拷贝到BootSRAM中。之后,处理器从0x00000000(BootSRAM的起始地址)处开始执行程序。

       当OM[1:0]选择01 或 10时,在SROM(nGCS0)外接的一定是norflash。处理器上电后从0x00000000处取出第一条指令(norflash 可以直接读取里面的数据 也就不需要使用SRAM缓冲器)  。

        这里我想多说几句!

         对于S3C2440处理器 M[1:0]选择01 或 10时:norflash基地址为0x00000000 ,SRAM顶端地址0x40000FFF。上电后处理器直接从0x00000000处取出指令,arm处理器的SP(堆栈指针寄存器)指向0x40000FFF。

          OM[1:0]选择00,S3C2440会启用内部的SRAM缓冲器会将nandflash中的前4KB大小的程序自动拷贝到BootSRAM中。BootSRAM基地址0x00000000,顶端0x00000FFF。上电后,arm处理器从0x00000000取出第一条指令,arm处理器的SP(堆栈指针寄存器)指向0x00000FFF

最终,都是需要将uboot的镜像给搬运到SDRAM的顶端去运行。对于norflash直接就可以读取,搬运

   过程就类似:


  1. <strong>    int i;  
  2.     volatile char * norflash_base_addr = 0x000000000;  
  3.         volatile char * ddr_base_addr = 0x300000000;  
  4.         for (i = 0 ; i < length ; i++)  
  5.         {  
  6.             *(ddr_base_addr + i) = *(norflash_base_addr + i);  
  7.         }</strong>   
 	int i;
 	volatile char * norflash_base_addr = 0x000000000;
      	volatile char * ddr_base_addr = 0x300000000;
        for (i = 0 ; i < length ; i++)
        {
        	*(ddr_base_addr + i) = *(norflash_base_addr + i);
        } 


        uboot里面搬运过程就如上面所写,只不过它是用汇编写的。

       但是,对于nandflash这样做可以吗?

       绝对是不可以的(nandflash根本就没有地址总线与arm相连,arm处理器上压根就没有地址可以去访问,只能通过nandflash控制器去访问),所以对于从nandflash启动,在做uboot移植时,需要去编写nandflash读取的函数。控制nandflash控制器去将nandflash中的uboot镜像给搬运到ddr中。一上电SRAM缓冲器自动将nandflash中4KB大小的数据搬运到BootSRAM中(硬件完成)。之后,当需要将uboot镜像从nandflash搬运到ddr中,只能你自己在移植时用代码实现(代码完成)。(理清楚思路,两次搬运的原因以及实现方式)                             

        你是否明白了呢?  就如同我之前说过的,了解处理器的启动流程和处理器的架构无关,主要是了解各种存储器的特性以及详细阅读芯片数据手册。

(重要!  启动代码  比如设置arm处理器异常向量表  关闭看门狗  关闭开启I/D  cache 等  这个才是与处理器架构密切相关   后面的博客我会一段一段的分析)

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页