在 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 中启动.
- 执行 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_SIZE4
- 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();
}
- 从 Nand Flash 中把
UBOOT 拷贝到 RAM
@read UBOOT 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 @ 执行内存比较
- 从
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 = 4Kbytes 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
在 U-BOOT 对 Nand Flash 的支持的更多相关文章
- openwrt 加入nand flash的支持
参考链接 : https://blog.csdn.net/wwx0715/article/details/77189456?locationNum=9&fps=1
- U-BOOT 对 Nand Flash 命令的支持
U-BOOT 对 Nand Flash 命令的支持 在 UBOOT 下对 Nand Flash 的支持主要是在命令行下实现对 nand flash 的操作.对 nand flash 实现的命令 为: ...
- NAND Flash【转】
转自:http://www.cnblogs.com/lifan3a/articles/4958224.html 以Micron公司的MT29F2G08为例介绍NAND Flash原理和使用. 1. 概 ...
- NAND FLASH
NAND Flash 以Micron公司的MT29F2G08为例介绍NAND Flash原理和使用. 1. 概述 MT29F2G08使用一个高度复用的8-bit总线(I/O[7:0])来数据传输.地址 ...
- Denali NAND FLASH控制器的验证
NAND FLASH的结构如图所示: Denali NAND FLASH控制器模块提供了从AHB总线到外部NAND FLASH存储器芯片IO管脚的访问功能.主要技术特性包括: 1.标准32位AHB总线 ...
- S5PV210 NAND Flash
NAND Flash 关于NAND FlashS5PV210的NAND Flash控制器有如下特点:1) 支持512byte,2k,4k,8k的页大小2) 通过各种软件模式来进行NAND Flash的 ...
- nand flash详解及驱动编写
https://www.crifan.com/files/doc/docbook/linux_nand_driver/release/html/linux_nand_driver.html#nand_ ...
- u-boot分析(九)----nand flash初始化|nand flash读写分析
u-boot分析(九) 上篇博文我们按照210的启动流程,分析到了初始化串口,由于接下来的取消存储保护不是很重要,所以我们今天按照u-boot的启动流程对nand flash初始化进行分析. 今天我们 ...
- NAND Flash memory in embedded systems
参考:http://www.design-reuse.com/articles/24503/nand-flash-memory-embedded-systems.html Abstract : Thi ...
随机推荐
- delphi 压缩
DELPHI 通过ZLib来压缩文件夹 unit Unit1; interface uses ZLib, Windows, Messages, SysUtils, Variants, Classes, ...
- thinkphp 原生分页
paginate() 是有三个参数: 第一个参数是 $listRows [int],也就是当前的页数 第二个参数是 $simple [boolean], 是否简洁模式或者总记录数 第三个参数是 $co ...
- BZOJ 3626: [LNOI2014]LCA(树剖+差分+线段树)
传送门 解题思路 比较有意思的一道题.首先要把求\(\sum\limits_{i=l}^r dep[lca(i,z)]\)这个公式变一下.就是考虑每一个点的贡献,做出贡献的点一定在\(z\)到根节点的 ...
- Win7+Ubuntu11.10(EasyBCD硬盘安装)----转载
Win7+Ubuntu11.10(EasyBCD硬盘安装) ubuntu 下载地址:http://mirrors.163.com/ubuntu-releases/12.04/ 1)首先还是分区,在计算 ...
- 7-MySQL高级-主从-1
1. 主从同步的定义 主从同步使得数据可以从一个数据库服务器复制到其他服务器上,在复制数据时,一个服务器充当主服务器(master),其余的服务器充当从服务器(slave). 因为复制是异步进行的,所 ...
- sql 特殊时间值 第一天或最后一天 无计算错误
DECLARE @dt datetimeSET @dt=GETDATE() DECLARE @number intSET @number=3 --1.指定日期该年的第一天或最后一天--A. 年的第一天 ...
- mysql分区partition详解
分区管理 论坛 1. RANGE和LIST分区的管理 针对非整形字段进行RANG\LIST分区建议使用COLUMNS分区. RANGE COLUMNS是RANGE分区的一种特殊类型,它与RANGE ...
- x25, PF_X25 - ITU-T X.25 / ISO-8208 协议接口。
总览 #include <sys/socket.h> #include <linux/x25.h> x25_socket = socket(PF_X25, SOCK_SEQPA ...
- 3、docker 容器管理
Docker容器相对于OpenStack的云主机实例,虽然他们本质上不同.我们需要基于镜像来创建容器.容器是独立运行的一个或一组应用,以及它们的运行环境.对应的,虚拟机可以理解为模拟运行的一整套操作系 ...
- HttpServlet中service方法的源码解读
前言 最近在看<Head First Servlet & JSP>这本书, 对servlet有了更加深入的理解.今天就来写一篇博客,谈一谈Servlet中一个重要的方法-- ...