zoukankan      html  css  js  c++  java
  • 在 U-BOOT 对 Nand Flash 的支持

    1.1    U-BOOT 对从 Nand Flash 启动的支持

    1.1.1   Nand Flash 启动 U-BOOT 的基本原理

    1. 前 4K 的问题

    如果 S3C2410 被配置成从 Nand Flash 启动(配置由硬件工程师在电路板设置), S3C2410 的 Nand Flash 控制器 有一个特殊的功能, 在 S3C2410 上电后, Nand Flash 控制器会自动的把 Nand Flash 上的前 4K 数据搬移到 4K 内部 RAM 中, 并把 0x00000000 设置内部 RAM 的起始地址, CPU 从内部 RAM 的 0x00000000 位置开始启动。这个过 程不需要程序干涉。

    程序员需要完成的工作,是把最核心的启动程序放在 Nand Flash 的前 4K 中。

    2.  启动程序的安排

    由于 Nand Flash 控制器从 Nand Flash 中搬移到内部 RAM 的代码是有限的,所以, 在启动代码的前 4K 里,我 们必须完成 S3C2410 的核心配置以及把启动代码(UBOOT)剩余部分搬到 RAM 中运行。以 UBOOT 为例, 前 4K 完成的主要工作, 见第四部分的 2.2 节。

    1.1.2   支持 Nand Flash 启动代码说明

    首先在 include/configs/crane2410.h 中加入 CONFIG_S3C2410_NAND_BOOT, 如下:

    #define CONFIG_S3C2410_NAND_BOOT      1

    支持从 Nand Flash 中启动.

    1. 执行 Nand Flash 初始化 下面代码在 cpu/arm920t/start.S 中

    #ifdef CONFIG_S3C2410_NAND_BOOT

    copy_myself:

    mov r10, lr

    ldr sp, DW_STACK_START @安装栈的起始地址 mov fp, #0         @初始化帧指针寄存器

    bl nand_reset                                @跳到复位 C 函数去执行

    ...

    DW_STACK_START:

    .word       STACK_BASE+STACK_SIZE­4

    1. nand_reset C 代码 下面代码被加在/board/crane2410/crane2410.c 中 void nand_reset(void)

    {

    int i;

    /* 设置 Nand Flash 控制器 */ rNFCONF=(1<<15)|(1<<14)|(1<<13)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0);

    /* 给 Nand Flash 芯片发送复位命令 */ NF_nFCE_L();

    NF_CMD(0xFF);

    for(i=0; i<10; i++); NF_WAITRB();

    NF_nFCE_H();

    }

    1. 从 Nand Flash 中把 UBOOT 拷贝到 RAM

    @read U­BOOT from Nand Flash to RAM

    ldr r0, =UBOOT_RAM_BASE @ 设置第 1 个参数: UBOOT 在 RAM 中的起始地址 mov   r1, #0x0   @ 设置第 2 个参数:Nand Flash 的起始地址

    mov   r2, #0x20000                        @ 设置第 3 个参数: UBOOT 的长度(128KB)

    bl     nand_read_whole                     @ 调用 nand_read_whole(), 该函数在 board/crane2410/crane2410.c 中 tst  r0, #0x0       @ 如果函数的返回值为 0,表示执行成功.

    beq   ok_nand_read                       @ 执行内存比较

    1. 从 Nand Flash 中把数据读入到 RAM 中

    int nand_read_whole(unsigned char *buf, unsigned long start_addr, int size)

    {

    int i, j;

    /* 如果起始地址和长度不是 512 字节(1 页)的倍数, 则返回错误代码 */

    if ((start_addr & NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK)) { return ­1;

    }

    /* 激活 Nand Flash */ NF_nFCE_L();

    for(i=0; i<10; i++);

    i = start_addr;

    while(i < start_addr + size) {

    /* 读 A 区 */ rNFCMD = 0;

    /* 写入读取地址 */ rNFADDR = i & 0xff; rNFADDR = (i >> 9) & 0xff; rNFADDR = (i >> 17) & 0xff; rNFADDR = (i >> 25) & 0xff;

    NF_WAITRB();

    /* 读出一页(512 字节) */

    for(j=0; j < NAND_SECTOR_SIZE; j++, i++) {

    *buf = (rNFDATA & 0xff); buf++;

    }

    }

    /* 停止驱动 Nand Flash */ NF_nFCE_H();

    return 0;

    }

    5.  校查搬移后的数据

    把 RAM 中的前 4K 与内部中前 4K 进行比较, 如果完全相同, 则表示搬移成功. ok_nand_read:

    mov r0, #0x00000000                   @内部 RAM 的起始地址

    ldr r1, =UBOOT_RAM_BASE  @UBOOT 在 RAM 中的起始地址

    mov r2, #0x400                              @比较 1024 次, 每次 4 字节, 4 bytes * 1024 = 4K­bytes go_next: @ 比较 1024 次, 每次 4 个字节

    ldr   r3, [r0], #4

    ldr r4, [r1], #4 teq   r3, r4

    bne notmatch subs r2, r2, #4

    beq done_nand_read bne  go_next

    notmatch:

    1:b     1b done_nand_read:

    mov pc, r10

  • 相关阅读:
    scroller,,list里面滚动到最后,,再添加10条数据
    Egret ,dataGroup,,,tabBar,,,List的区别
    自我回答,问题3:Scroller的属性 scrollPolicyV怎么无效呢,,也就是 scrollPolicyV设置为on,但是并没有显示滚动条
    自我回答,问题2:比如有个历史记录,,然后左边有个按钮btnleft,,右边有个按钮btnright,点击对应按钮,,就会有对应历史记录推进,或者后退
    自我回答,问题1:八个按钮(btn0-btn8),,下面有加分8个bitmap(bitmap0-8),,点击按钮对应有bitmap的值+=1
    js生成 1-100 不重复随机数
    laravel 的passport Oauth 认证登录请求 的 oauth_token 重置
    phpunit 测试指定目录下的测试类
    [SymfonyComponentDebugExceptionFatalThrowableError] Class 'Dingo' not found
    laravel 观察器 模型绑定 方法的关系
  • 原文地址:https://www.cnblogs.com/fanweisheng/p/11106189.html
Copyright © 2011-2022 走看看