4.1 nand flash启动u-boot

  nand flash 启动的时候,CPU 需要将 nand flash 中前面 4KB 的内容复制到 SRAM 中执行,然后将 NAND Flash 中的所有内容拷贝到 SDRAM中。

  前4 KB 的拷贝 是硬件自动执行的。

4.1.1 地址空间

  原理图如下:

  四、NAND Flash

  nand flash 只有数据总线,并没有像 SDRAM 一样有地址总线。这样就有两种寻址方式就不同。

  SDRAM 或 网卡、片内4K内存 都是地址总线接到 2440 上,他们的地址都是 CPU可以看到的,都是CPU发出来的,这为 CPU 统一编址。

  nand flash 上页存在地址空间(0~256 M),nand flash 上的 0 地址 和 CPU 上的 0地址是不同的。

  nand flash 地址都是通过 数据总线来发送的。

  JZ2440板子上用的是大页的 nand flash,大页是指一个页里面有 2K 字节,小页只有 512 字节。结构如下图:

  四、NAND Flash

  一页分为 2K 字节 + 64字节的OOB,一块的大小为 128K + 4K byte,128/2 = 64 页组成一块。

  OOB 在大多数时候不参与编址。

4.1.2 nand flash 操作

  CPU 先发出命令给 nandflash 要寻址,然后发送地址,然后再发送 读或写命令,在读或写数据。

  nand flash  的命令如下图:

  四、NAND Flash

  nandflash 引脚功能

  四、NAND Flash

  • 从硬件上访问 NAND
    • 发出命令:CLE引脚,命令发送到数据总线上
    • 发出地址:ALE引脚,地址发送到数据总线上
    • 传输数据:R/W
  • 2440 控制
    • 发出命令,寄存器 NFCMMD 寄存器
    • 发出地址,寄存器 NFADDR 寄存器
    • 读写数据,NFDATA
    • 状态,NFSTAT  

  读流程如下:(其他流程见 nand flash  的芯片手册的第三章)

  四、NAND Flash

 4.1.3 代码

  nand.lds

1 SECTIONS { 
2     // head.o init.o nand.o 存放在地址 0x0000 0000 处
3   firtst      0x00000000 : { head.o init.o nand.o}
4     // main.o 存放在地址 0x3000 0000 处  SDRAM
5   second     0x30000000 : AT(4096) { main.o }
6 }

   head.S

 1 @******************************************************************************
 2 @ File:head.s
 3 @ 功能:设置SDRAM,将程序复制到SDRAM,然后跳到SDRAM继续执行
 4 @******************************************************************************       
 5   
 6 .text
 7 .global _start
 8 _start:
 9                                             @函数disable_watch_dog, memsetup, init_nand, nand_read_ll在init.c中定义
10             ldr     sp, =4096               @设置堆栈,栈指向SRAM顶端
11             bl      disable_watch_dog       @关WATCH DOG
12             bl      memsetup                @初始化SDRAM
13             bl      nand_init               @初始化NAND Flash
14 
15                                             @将NAND Flash中地址4096开始的1024字节代码(main.c编译得到)复制到SDRAM中
16                                             @nand_read_ll函数需要3个参数:
17             ldr     r0,     =0x30000000     @1. 目标地址=0x30000000,这是SDRAM的起始地址
18             mov     r1,     #4096           @2.  源地址   = 4096,连接的时候,main.c中的代码都存在NAND Flash地址4096开始处
19             mov     r2,     #2048           @3.  复制长度= 2048(bytes),对于本实验的main.c,这是足够了
20             bl      nand_read               @调用C函数nand_read
21 
22             ldr     sp, =0x34000000         @设置栈
23             ldr     lr, =halt_loop          @设置返回地址
24             ldr     pc, =main               @b指令和bl指令只能前后跳转32M的范围,所以这里使用向pc赋值的方法进行跳转
25 halt_loop:
26             b       halt_loop

  init.c

 1 /* WOTCH DOG register */
 2 #define     WTCON                (*(volatile unsigned long *)0x53000000)
 3 
 4 /* SDRAM regisers */
 5 #define     MEM_CTL_BASE        0x48000000
 6  
 7 void disable_watch_dog();
 8 void memsetup();
 9 
10 /*上电后,WATCH DOG默认是开着的,要把它关掉 */
11 void disable_watch_dog()
12 {
13     WTCON    = 0;
14 }
15 
16 /* 设置控制SDRAM的13个寄存器 */
17 void memsetup()
18 {
19     int     i = 0;
20     unsigned long *p = (unsigned long *)MEM_CTL_BASE;
21 
22     /* SDRAM 13个寄存器的值 */
23     unsigned long  const    mem_cfg_val[]={ 0x22011110,     //BWSCON,这里将所有的内存配置都设置了,我们关注SDRAM DW6 0010 即可,为16位
24                                             0x00000700,     //BANKCON0,
25                                             0x00000700,     //BANKCON1
26                                             0x00000700,     //BANKCON2
27                                             0x00000700,     //BANKCON3  
28                                             0x00000700,     //BANKCON4
29                                             0x00000700,     //BANKCON5
30                                             0x00018005,     //BANKCON6,SDRAM 的设置,对照寄存器查看参数
31                                             0x00018005,     //BANKCON7
32                                             0x008C07A3,     //REFRESH,刷新寄存器,使能,刷新模式为自刷新,RAS改变时间为2个时钟,
33                                                             //SDRAM Semi Row cycle time 为7个时钟
34                                                             //Refresh Counte 为 11 1010 0011 = 931,Refresh period = (211-refresh_count+1)/HCLK
35                                             0x000000B1,     //BANKSIZE,SDRAM 大小设置为 64M
36                                             0x00000030,     //MRSRB6,SDRAM 模式设置
37                                             0x00000030,     //MRSRB7
38                                     };
39 
40     for(; i < 13; i++)
41         p[i] = mem_cfg_val[i];  // 为每一个 内存控制器的寄存器设置参数
42 }
View Code

相关文章:

  • 2021-11-25
  • 2021-06-17
  • 2022-12-23
  • 2022-12-23
  • 2021-07-03
  • 2021-08-13
  • 2021-11-19
猜你喜欢
  • 2022-01-14
  • 2021-09-03
  • 2022-12-23
  • 2021-04-16
  • 2021-12-31
相关资源
相似解决方案