首页 > 代码库 > Uboot(二)支持NAND Flash和NOR Flash
Uboot(二)支持NAND Flash和NOR Flash
四、自动识别从NAND Flash启动还是从Nor flash启动
原理:在启动的时候,用程序将0x40000000~0x40001000中的某些位置清零,然后回读0x00000000~0x00001000中的相应位置,
为零说明是NAND boot,如果是原来的数据就是Nor boot。
判断完后如果是NAND boot,还要恢复被改动的数据,再进入自拷贝阶段。
选择了在start.S文件开头,全局中断向量之后第57行的变量:.balignl 16,0xdeadbeef 。
理由如下:
(1)他是非零数,而且数据是确定的:0xdeadbeef
(2)他的位置是固定的:0x0000003c(0x4000003c)
(3)他在检测程序之前,不会影响程序的向下运行
(4)他不属于程序,他是一个程序中的魔数(Magic Number),用魔数来检测也比较合理
所以最后的检测步骤是:在启动的时候,将0x4000003c位置开始的四个字节清零,然后读取0x0000003c位置开始的四个字节。如果回读的结果为零,说明是Nand boot,否则就是Nor boot。如果是Nand boot,必须要复原清零的数据。原因是:在Nand boot过后,会核对内部SRAM中的4K程序,和从Nand中拷贝到SDRAM的前4K程序是否一致,如果不一致会进入死循。
1、 第90行左右添加一个Flash启动标志,从Nand启动时将其设置为0,从Nor启动时将其设置为1
- .globl _bss_start
- _bss_start:
- .word __bss_start
- .globl _bss_end
- _bss_end:
- .word _end
- .globl bBootFrmNORFlash
- bBootFrmNORFlash:
- .word 0
2、判断当前代码位置,如果在内存,直接跳到stack_setup 第224行左右
- #ifndef CONFIG_SKIP_LOWLEVEL_INIT
- bl cpu_init_crit
- #endif
- /***************** CHECK_CODE_POSITION***************************************/
- adr r0, _start /* r0 <- current position of code */
- 11
- ldr r1, _TEXT_BASE /* test if we run from flash or RAM */
- cmp r0, r1 /* don‘t reloc during debug */
- beq stack_setup
- /***************** CHECK_CODE_POSITION*************************************/
3、如果代码当前位置不在内存中,就判断启动方式为Nand Flash或者Nor Flash
- /***************** CHECK_BOOT_FLASH ******************************************/
- ldr r1, =( (4<<28)|(3<<4)|(3<<2) ) /* address of Internal SRAM 0x4000003C*/
- mov r0, #0 /* r0 = 0 */
- str r0, [r1]
- mov r1, #0x3c /* address of 0x0000003C*/
- ldr r0, [r1]
- cmp r0, #0 /*判断0x0000003C所指向的4个字节是否被清0*/
- bne relocate /*没有被清0,就是在Nor Flash中启动,则跳到Nor Flash的重定向代码处relocate*/
- /* recovery */
- ldr r0, =(0xdeadbeef) /*被清0,就是在Nand Flash中启动*/
- ldr r1, =( (4<<28)|(3<<4)|(3<<2) ) /*恢复0x4000003C指向的4字节的数据0xdeadbeef*/
- str r0, [r1]
- /***************** CHECK_BOOT_FLASH ******************************************/
4、在Nand Flash中启动的话,那么Nand Flash搬移代码如下:
定义u-boot在Nand flash中存放的长度为#define LENGTH_UBOOT 0x100000,可以方便修改u-boot因为裁剪和增添大小的改变而占的长度。
- /***************** NAND_BOOT *************************************************/
- #define LENGTH_UBOOT 0x100000
- #define NAND_CTL_BASE 0x4E000000
- #ifdef CONFIG_S3C2440
- /* Offset */
- #define oNFCONF 0x00
- #define oNFCONT 0x04
- #define oNFCMD 0x08
- #define oNFSTAT 0x20
- @ reset NAND
- mov r1, #NAND_CTL_BASE
- ldr r2, =( (7<<12)|(7<<8)|(7<<4)|(0<<0) )
- str r2, [r1, #oNFCONF]
- ldr r2, [r1, #oNFCONF]
- ldr r2, =( (1<<4)|(0<<1)|(1<<0) ) @ Active low CE Control
- str r2, [r1, #oNFCONT]
- ldr r2, [r1, #oNFCONT]
- ldr r2, =(0x6) @ RnB Clear
- str r2, [r1, #oNFSTAT]
- ldr r2, [r1, #oNFSTAT]
- mov r2, #0xff @ RESET command
- strb r2, [r1, #oNFCMD]
- mov r3, #0 @ wait
- nand1:
- add r3, r3, #0x1
- cmp r3, #0xa
- blt nand1
- nand2:
- ldr r2, [r1, #oNFSTAT] @ wait ready
- tst r2, #0x4
- beq nand2
- ldr r2, [r1, #oNFCONT]
- orr r2, r2, #0x2 @ Flash Memory Chip Disable
- str r2, [r1, #oNFCONT]
- @ get read to call C functions (for nand_read())
- ldr sp, DW_STACK_START @ setup stack pointer
- mov fp, #0 @ no previous frame, so fp=0
- @ copy U-Boot to RAM
- ldr r0, =TEXT_BASE
- mov r1, #0x0
- mov r2, #LENGTH_UBOOT
- bl nand_read_ll
- tst r0, #0x0
- beq ok_nand_read
- bad_nand_read:
- loop2:
- b loop2 @ infinite loop
- ok_nand_read:
- @ verify
- mov r0, #0
- ldr r1, =TEXT_BASE
- mov r2, #0x400 @ 4 bytes * 1024 = 4K-bytes
- go_next:
- ldr r3, [r0], #4
- ldr r4, [r1], #4
- teq r3, r4
- bne notmatch
- subs r2, r2, #4
- beq stack_setup
- bne go_next
- notmatch:
- loop3:
- b loop3 @ infinite loop
- #endif
- /***************** NAND_BOOT *************************************************/
5、在Nor Flash中启动的话,那么Nor Flash搬移代码如下:
- /***************** NOR_BOOT *************************************************/
- relocate: /* relocate U-Boot to RAM */
- /*********** CHECK_FOR_MAGIC_NUMBER***************/
- ldr r1, =(0xdeadbeef)
- cmp r0, r1
- bne loop3
- /*********** CHECK_FOR_MAGIC_NUMBER***************/
- adr r0, _start /* r0 <- current position of code */
- ldr r1, _TEXT_BASE /* test if we run from flash or RAM */
- ldr r2, _armboot_start
- ldr r3, _bss_start
- sub r2, r3, r2 /* r2 <- size of armboot */
- add r2, r0, r2 /* r2 <- source end address */
- copy_loop:
- ldmia r0!, {r3-r10} /* copy from source address [r0] */
- stmia r1!, {r3-r10} /* copy to target address [r1] */
- cmp r0, r2 /* until source end addreee [r2] */
- ble copy_loop
- SetBootFlag:
- ldr r0, =bBootFrmNORFlash
- mov r1, #1 /*从Nor启动,将标志设置为1*/
- str r1, [r0]
- /***************** NOR_BOOT *************************************************/
6、将下面的代码全部删掉:
- #ifndef CONFIG_SKIP_RELOCATE_UBOOT
- relocate: /* relocate U-Boot to RAM */
- adr r0, _start /* r0 <- current position of code */
- ldr r1, _TEXT_BASE /* test if we run from flash or RAM */
- cmp r0, r1 /* don‘t reloc during debug */
- beq stack_setup
- ldr r2, _armboot_start
- ldr r3, _bss_start
- sub r2, r3, r2 /* r2 <- size of armboot */
- add r2, r0, r2 /* r2 <- source end address */
- copy_loop:
- 15
- ldmia r0!, {r3-r10} /* copy from source address [r0] */
- stmia r1!, {r3-r10} /* copy to target address [r1] */
- cmp r0, r2 /* until source end addreee [r2] */
- ble copy_loop
- #endif /* CONFIG_SKIP_RELOCATE_UBOOT *
7、第378行左右添加代码:
- _start_armboot: .word start_armboot
- #define STACK_BASE 0x33f00000
- #define STACK_SIZE 0x10000
- .align 2
- DW_STACK_START: .word STACK_BASE+STACK_SIZE-4
Uboot(二)支持NAND Flash和NOR Flash
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。