深入理解uboot 2016 - 基础篇(S3C2410 与S5PV210处理器启动流程分析)

 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处理器的数据手册中摘出了芯片的存储器映射表,如下图所示:

深入理解uboot 2016 - 基础篇(S3C2410 与S5PV210处理器启动流程分析)

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

       当OM[1:0]选择01 或 10时,在SROM(nGCS0)外接的一定是norflash。处理器上电后从0x00000000处取出第一条指令,将ARM处理器的SP(堆栈指针寄存器设置到0x40000FFF处)。在norflash和BootSRAM搭建的程序运行环境中完成时钟和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缓冲器方框图 如下图所示:         

深入理解uboot 2016 - 基础篇(S3C2410 与S5PV210处理器启动流程分析)                                                                                                                                                           

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

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

深入理解uboot 2016 - 基础篇(S3C2410 与S5PV210处理器启动流程分析)                                                                                                                                                                                           

         当复位时,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直接就可以读取,搬运

   过程就类似:

     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 等  这个才是与处理器架构密切相关   后面的博客我会一段一段的分析)