zoukankan      html  css  js  c++  java
  • (二)识别NAND Flash Nor Flash

    检测步骤:在启动的时候,将0x4000003c位置开始的四个字节清零,然后读取0x0000003c位置开始的四个字节。

            如果回读的结果为零,说明是Nand boot,否则就是Nor boot

     修改start.S

      第90 行左右添加一个Flash 启动标志,从Nand 启动时将其设置为0 ,从Nor 启动时将其设置为1

    1. .globl _bss_start  
    2. _bss_start:  
    3. .word __bss_start  
    4. .globl _bss_end  
    5. _bss_end:  
    6. .word _end  
    7. .globl bBootFrmNORFlash   声明一个全局变量
    8. bBootFrmNORFlash:  
    9. .word 0           给全局变量赋值0
    从第224 行左右开始,添加代码为:  
     判断当前代码位置,如果在内存,直接跳到stack_setup 
    1.  #ifndef CONFIG_SKIP_LOWLEVEL_INIT  
    2. bl cpu_init_crit  
    3. #endif  
    4. /***************** CHECK_CODE_POSITION***************************************/  
    5. adr r0, _start  /* r0 <- current position of code */           获得 _start 的实际运行所在的地址值
    6. ldr r1, _TEXT_BASE  /* test if we run from flash or RAM */      获得地址_TEXT_BASE中所存放的数据
    7. cmp r0, r1  /* don't reloc during debug */            比较是否相等
    8. beq stack_setup                                    如果相等就跳到堆栈
    9. /***************** CHECK_CODE_POSITION*************************************/ 

     如果代码当前位置不在内存中,就判断启动方为Nand Flash 或者Nor Flash

    1. /***************** CHECK_BOOT_FLASH ******************************************/  
    2. ldr r1, =( (4<<28)|(3<<4)|(3<<2) )  /* address of Internal SRAM 0x4000003C*/ 内部SRAM的地址
    3. mov  r0, #0  /* r0 = 0 */  
    4. str r0, [r1]             写0
    5. mov  r1, #0x3c  /* address of 0x0000003C*/  被映射后的地址
    6. ldr r0, [r1]  
    7. cmp r0, #0 /* 判断0x0000003C所指向的4个字节是否被清0*/  比较
    8. bne relocate /* 没有被清0,就是在Nor Flash中启动,则跳到Nor Flash的重定向代码处relocate*/  
    9. /* recovery */  
    10. ldr r0, =(0xdeadbeef) /* 被清0,就是在Nand Flash中启动*/   恢复数据
    11. ldr r1, =( (4<<28)|(3<<4)|(3<<2) ) /* 恢复0x4000003C指向的4字节的数据0xdeadbeef*/  
    12. str r0, [r1]  
    13. /***************** CHECK_BOOT_FLASH ******************************************/
      在Nand Flash 中启动的话,那么Nand Flash 搬移代码如下:
    定义u-boot在Nand flash中存放的长度为#define LENGTH_UBOOT 0x100000,可以方便修改
    u-boot因为裁剪和增添大小的改变而占的长度
    1. /***************** NAND_BOOT *************************************************/  
    2. #define LENGTH_UBOOT 0x100000  
    3. #define NAND_CTL_BASE 0x4E000000               NFCONF基地址
    4.   
    5. #ifdef CONFIG_S3C2440  
    6. /* Offset */  
    7. #define oNFCONF 0x00                              配置
    8. #define oNFCONT 0x04                              控制
    9. #define oNFCMD  0x08                              指令
    10. #define oNFSTAT 0x20                              运行状态
    11.   
    12.     @ reset NAND  
    13.     mov  r1, #NAND_CTL_BASE  
    14.     ldr r2, =( (7<<12)|(7<<8)|(7<<4)|(0<<0) )  CLE 和 ALE 持续值= HCLK × 3 TWRPH0 持续值= HCLK × ( 7 + 1 )
    15.     str r2, [r1, #oNFCONF]  TWRPH1 持续值= HCLK × ( 7 + 1 )  0:支持 256 字或 512 字节/页的 NAND Flash 存储器
    16.     ldr r2, [r1, #oNFCONF]  0=256 字/页     0=3 个地址周期     0=8 位总线

    17.     ldr r2, =( (1<<4)|(0<<1)|(1<<0) ) @ Active low CE Control  1:初始化 ECC 编码器/译码器
    18.     str r2, [r1, #oNFCONT]     0:强制 nFCE 为低(使能片选)  1:NAND Flash 控制器使能
    19.     ldr r2, [r1, #oNFCONT]  
    20.   
    21.     ldr r2, =(0x6)  @ RnB Clear 110 1:检测 RnB 传输    nCE 输出引脚的状态    0:NAND Flash 存储器忙 
    22.     str r2, [r1, #oNFSTAT]  
    23.     ldr r2, [r1, #oNFSTAT]  
    24.   
    25.     mov  r2, #0xff  @ RESET command   NAND Flash 存储器命令值  
    26.     strb r2, [r1, #oNFCMD]  
    27.       
    28.     mov  r3, #0  @ wait  
    29. nand1:  
    30.     add r3, r3, #0x1  
    31.     cmp r3, #0xa   循环10次
    32.     blt nand1     若上cmp结果为小于    跳转到nand1
    33.   
    34. nand2:  
    35.     ldr r2, [r1, #oNFSTAT] @ wait ready  无限循环等待,直到检测到NAND Flash变为繁忙状态
    36.     tst r2, #0x4     r2和100按位与
    37.     beq nand2       按位与的结果与0比较  若结果为0,跳转到nand2
    38.   
    39.     ldr r2, [r1, #oNFCONT]  
    40.     orr r2, r2, #0x2 @ Flash Memory Chip Disable  取消片选
    41.     str r2, [r1, #oNFCONT]  
    42.   
    43.     @ get read to call C functions (for nand_read())  
    44.     ldr sp, DW_STACK_START  @ setup stack pointer  //为C代码准备堆栈,DW_STACK_START定义在下面
    45.     mov  fp, #0  @ no previous frame, so fp=0  
    46.   
    47.     @ copy U-Boot to RAM  
    48.     ldr r0, =TEXT_BASE   //传递给C代码的第一个参数:u-boot在RAM中的起始地址
    49.     mov  r1, #0x0   //传递给C代码的第二个参数:Nand Flash的起始地址
    50.     mov  r2, #LENGTH_UBOOT   //传递给C代码的第三个参数:u-boot的长度大小(128k)
    51.     bl nand_read_ll   //此处调用C代码中读Nand的函数,现在还没有要自己编写实现
    52.     tst r0, #0x0                        测试r0是否为0
    53.     beq ok_nand_read                     如果r0=0, 开始测试是否搬移成功
    54.   
    55. bad_nand_read:  
    56. loop2:  
    57.     b  loop2  @ infinite loop     无限死循环
    58. ok_nand_read:  
    59.     @ verify      检查搬移后的数据,如果前4k完全相同,表示搬移成功
    60.     mov  r0, #0  
    61.     ldr r1, =TEXT_BASE  
    62.     mov  r2, #0x400 @ 4 bytes * 1024 = 4K-bytes  
    63. go_next:  
    64.     ldr r3, [r0], #4  
    65.     ldr r4, [r1], #4  
    66.     teq r3, r4  
    67.     bne notmatch       如果不相等,跳入死循环
    68.     subs  r2, r2, #4  
    69.     beq stack_setup    如果相等,跳入堆栈
    70.     bne go_next        如果不相等, 继续循环
    71.   
    72. notmatch:  
    73. loop3:  
    74.     b  loop3  @ infinite loop   无限死循环
    75. #endif  
    76. /***************** NAND_BOOT *************************************************/

       在Nor Flash 中启动的话,那么Nor Flash 搬移代码如下:

    1. /***************** NOR_BOOT *************************************************/  
    2. relocate: /* relocate U-Boot to RAM  */  
    3. /*********** CHECK_FOR_MAGIC_NUMBER***************/  
    4.     ldr r1, =(0xdeadbeef)  
    5.     cmp r0, r1  
    6.     bne loop3  
    7. /*********** CHECK_FOR_MAGIC_NUMBER***************/  
    8.     adr r0, _start  /* r0 <- current position of code */  
    9.     ldr r1, _TEXT_BASE  /* test if we run from flash or RAM */  
    10.     ldr r2, _armboot_start  
    11.     ldr r3, _bss_start  
    12.     sub r2, r3, r2  /* r2 <- size of armboot */  
    13.     add r2, r0, r2  /* r2 <- source end address */  
    14. copy_loop:  
    15.     ldmia  r0!, {r3-r10} /* copy from source address [r0] */  
    16.     stmia  r1!, {r3-r10} /* copy to target address [r1] */  
    17.     cmp r0, r2  /* until source end addreee [r2] */  
    18.     ble copy_loop  
    19. SetBootFlag:  
    20.     ldr r0, =bBootFrmNORFlash  
    21.     mov r1, #1 /*从Nor启动,将标志设置为1*/  
    22.     str r1, [r0]  
    23. /***************** NOR_BOOT *************************************************/  

      将下面的代码全部删掉:

    1. #ifndef CONFIG_SKIP_RELOCATE_UBOOT    删掉u-boot中nor Flash启动部分
    2. relocate: /* relocate U-Boot to RAM  */  
    3.     adr r0, _start  /* r0 <- current position of code */  
    4.     ldr r1, _TEXT_BASE  /* test if we run from flash or RAM */  
    5.     cmp r0, r1  /* don't reloc during debug */  
    6.     beq stack_setup  
    7.     ldr r2, _armboot_start  
    8.     ldr r3, _bss_start  
    9.     sub r2, r3, r2  /* r2 <- size of armboot */  
    10.     add r2, r0, r2  /* r2 <- source end address */  
    11. copy_loop:  
    12.     ldmia  r0!, {r3-r10} /* copy from source address [r0] */  
    13.     stmia  r1!, {r3-r10} /* copy to target address [r1] */  
    14.     cmp r0, r2  /* until source end addreee [r2] */  
    15.     ble copy_loop  
    16. #endif /* CONFIG_SKIP_RELOCATE_UBOOT *

      第378 行左右添加代码:

    1. _start_armboot: .word start_armboot  
    2. #define STACK_BASE 0x33f00000                                      定义栈的基地址和大小
    3. #define STACK_SIZE 0x10000  
    4. .align  2  
    5. DW_STACK_START: .word  STACK_BASE+STACK_SIZE-4 
  • 相关阅读:
    【python】10分钟教你用python打造贪吃蛇超详细教程
    盘点下那些年我们用过的编程工具IDE都有哪些
    帝国竞争算法(imperialist competitive algorithm, ICA )详解+Java代码实现
    10分钟教你使用Picgo+GitHub+ jsDelivr搭建CDN加速免费图床
    10分钟了解代码命名规范(Java、Python)
    什么是算法?从枚举到贪心再到启发式(下)-终于有人把邻域搜索讲清了!
    番茄路径优化系统介绍-专注于算法与路径优化VRP
    什么是算法?从枚举到贪心再到启发式(上)
    10分钟教你用Python打造学生成绩管理系统
    10分钟教你用Python中的Matplotlib绘制多图并合并展示
  • 原文地址:https://www.cnblogs.com/liuchengchuxiao/p/4210288.html
Copyright © 2011-2022 走看看