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

 从Nand Flash启动U-BOOT的基本原理
-------------------------------------------
前4K的问题
    如果S3C2410被配置成从Nand Flash启动(配置由硬件工程师在电路板设置), S3C2410的Nand Flash控制器有一个特殊的功能,在S3C2410上电后,Nand Flash控制器会自动的把Nand Flash上的前4K数据搬移到4K内部RAM中,并把0x00000000设置内部RAM的起始地址,CPU从内部RAM的0x00000000位置开始启动。这个过程不需要程序干涉。
    程序员需要完成的工作,是把最核心的启动程序放在Nand Flash的前4K中。
启动程序的安排
    由于Nand Flash控制器从Nand Flash中搬移到内部RAM的代码是有限的,所以在启动代码的前4K里,我们必须完成S3C2410的核心配置以及把启动代码(U-BOOT)剩余部分搬到RAM中运行。


    u-boot源码不支持从nand flash启动,可是s3c2410支持从nand flash启动,开发板(sbc-2410x)加电后s3c2410将nand flash的前4k(保存有u-boot的部分功能--拷贝功能--把nand flash中的内容拷贝到SDRAM)拷贝到sram(s3c2410芯片内的sram)。这就需要修改u-boot源码,增加u-boot的功能: 使u-boot在得到执行权后能够将其自身拷贝到开发板上SDRAM中,以便处理器能够执行u-boot

 

.Nand Flash的命令、地址、数据都通过I/O口发送,管脚复用,这样做做的好处是,可以明显减少NAND FLASH的管脚数目,将来如果设计者想将NAND FLASH更换为更高密度、更大容量的,也不必改动电路板。

 NAND FLASH不能够执行程序,本人总结其原因如下 :

1. NAND FLASH本身是连接到了控制器上而不是系统总线上。CPU启动后是要取指令执行的,如果是SROM、NOR FLASH 等之类的,CPU 发个地址就可以取得指令并执行,NAND FLASH不行,因为NAND FLASH 是管脚复用,它有自己的一套时序,这样CPU无法取得可以执行的代码,也就不能初始化系统了。

 2. NAND FLASH是顺序存取设备,不能够被随机访问,程序就不能够分支或跳转,这样你如何去设计程序。

U-BOOT 支持ARM、 PowerPC等多种架构的处理器,也支持Linux、NetBSD和VxWorks等多种操作系统,主要用来开发嵌入式系统初始化代码 bootloader。bootloader是芯片复位后进入操作系统之前执行的一段代码,完成由硬件启动到操作系统启动的过渡,为运行操作系统提供基本的运行环境,如初始化CPU、堆栈、初始化存储器系统等,其功能类似于PC机的BIOS.

 

 

NAND闪存工作原理

       S3C2410开发板的NAND闪存由NAND闪存控制器(集成在S3C2410 CPU中)和NAND闪存芯片(K9F1208U0A)两大部分组成。当要访问NAND闪存芯片中的数据时,必须通过NAND闪存控制器发送命令才能完成。所以, NAND闪存相当于S3C2410的一个外设,而不位于它的内存地址区。

       NAND闪存(K9F1208U0A)的数据存储结构分层为:1设备(Device) = 4096 块(Block);1块= 32页/行(Page/row);1页= 528B = 数据块 (512B) + OOB块 (16B)
在每一页中,最后16个字节(又称OOB)在NAND闪存命令执行完毕后设置状态,剩余512个字节又分为前半部分和后半部分。可以通过NAND闪存命令00h/01h/50h分别对前半部、后半部、OOB进行定位,通过NAND闪存内置的指针指向各自的首地址。
NAND闪存的操作特点为:擦除操作的最小单位是块;NAND闪存芯片每一位只能从1变为0,而不能从0变为1,所以在对其进行写入操作之前一定要将相应块擦除;OOB部分的第6字节为坏快标志,即如果不是坏块该值为FF,否则为坏块;除OOB第6字节外,通常用OOB的前3个字节存放NAND闪存的硬件 ECC(校验寄存器)码;
  
从NAND闪存启动U-BOOT的设计思路

       如果S3C2410被配置成从NAND闪存启动,上电后,S3C2410的NAND闪存控制器会自动把NAND闪存中的前4K数据搬移到内部RAM中, 并把0x00000000设置为内部RAM的起始地址, CPU从内部RAM的0x00000000位置开始启动。因此要把最核心的启动程序放在NAND闪存的前4K中。

       由于NAND闪存控制器从NAND闪存中搬移到内部RAM的代码是有限的,所以, 在启动代码的前4K里,必须完成S3C2410的核心配置,并把启动代码的剩余部分搬到RAM中运行。在U-BOOT中, 前4K完成的主要工作就是U-BOOT启动的第一个阶段(stage1)。
根据U-BOOT的执行流程图,可知要实现从NAND闪存中启动U-BOOT,首先需要初始化NAND闪存,并从NAND闪存中把U-BOOT搬移到RAM中,最后需要让U-BOOT支持NAND闪存的命令操作。
  
开发环境

       本设计中目标板硬件环境如下:CPU为S3C2410,SDRAM为HY57V561620,NAND闪存为64MB的K9F1208U0A。

       主机软件环境为Redhat9.0、 u-boot-1.1.3、gcc 2.95.3。修改U-BOOT的Makefile,加入:
wch2410_config : unconfig
@./mkconfig $(@:_config=) arm arm920t wch2410 NULL s3c24x0

       即将开发板起名为wch2410,接下来依次进行如下操作:
mkdir board/wch2410
cp board/smdk2410 board/wch2410
mv smdk2410.c wch2410.c
cp include/configs/smdk2410.h include/configs/wch2410.h
export PATH=/usr/local/arm/2.95.3/bin:$PATH

       最后执行:
make wch2410_config
make all ARCH=arm
生成u-boot.bin,即通过了测试编译。
具体设计

支持NAND闪存的启动程序设计
       因为U-BOOT的入口程序是/cpu/arm920t/start.S,故需在该程序中添加NAND闪存的复位程序,以及实现从NAND闪存中把U-BOOT搬移到RAM中的功能程序。

       首先在/include/configs/wch2410.h中加入CONFIG_S3C2410_NAND_BOOT, 如下:
#define CONFIG_S3C2410_NAND_BOOT 1      @支持从NAND 闪存中启动
然后在/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函数去执行,执行NAND闪存复位
.......
/*从NAND闪存中把U-BOOT拷贝到RAM*/
ldr r0, =UBOOT_RAM_BASE        @ 设置第1个参数: UBOOT在RAM中的起始地址
mov r1, #0x0                   @ 设置第2个参数:NAND闪存的起始地址
mov r2, #0x20000               @ 设置第3个参数: U-BOOT的长度(128KB)
bl nand_read_whole             @ 调用nand_read_whole(),把NAND闪存中的数据读入到RAM中
tst r0, #0x0                   @ 如果函数的返回值为0,表示执行成功
beq ok_nand_read                @ 执行内存比较,把RAM中的前4K内容与NAND闪存中的前4K内容进行比较, 如果完全相同, 则表示搬移成功

       其中,nand_reset (),nand_read_whole()被加在/board/wch2410/wch2410.c中。

支持U-BOOT命令设计
       在U-BOOT下对nand闪存的支持主要是在命令行下实现对nand闪存的操作。对nand闪存实现的命令为:nand info(打印nand Flash信息)、nand device(显示某个nand闪存设备)、nand read(读取nand闪存)、nand write(写nand闪存)、nand erease(擦除nand闪存)、nand bad(显示坏块)等。

       用到的主要数据结构有:struct nand_flash_dev、struct nand_chip。前者包括主要的芯片型号、存储容量、设备ID、I/O总线宽度等信息;后者是具体对NAND闪存进行操作时用到的信息。

a. 设置配置选项
       修改/include/configs/wch2410.h,主要是在CONFIG_COMMANDS中打开CFG_CMD_NAND选项。定义NAND闪存控制器在SFR区中的起始寄存器地址、页面大小,定义NAND闪存命令层的底层接口函数等。

b. 加入NAND闪存芯片型号
       在/include/linux/mtd/ nand_ids.h中对如下结构体赋值进行修改:
static struct nand_flash_dev nand_flash_ids[] = {
......
{"Samsung K9F1208U0A", NAND_MFR_SAMSUNG, 0x76, 26, 0, 3, 0x4000, 0},
.......
                                                 }
这样对于该款NAND闪存芯片的操作才能正确执行。
c. 编写NAND闪存初始化函数
在/board/wch2410/wch2410.c中加入nand_init()函数。
void nand_init(void)
{
/* 初始化NAND闪存控制器, 以及NAND闪存芯片 */
nand_reset();
/* 调用nand_probe()来检测芯片类型 */
printf ("%4lu MB/n", nand_probe(CFG_NAND_BASE) >> 20);
}

该函数在启动时被start_armboot()调用。
   
       最后重新编译U-BOOT并将生成的u-boot.bin烧入NAND闪存中,目标板上电后从串口输出如下信息:
U-Boot 1.1.3 (Nov 14 2006 - 11:29:50)
U-Boot code: 33F80000 -> 33F9C9E4     BSS: -> 33FA0B28
RAM Configuration:
Bank #0: 30000000 64 MB
## Unknown Flash on Bank 0: ID 0xffff, Size = 0x00000000 = 0 MB
Flash:     0 kB
NAND:     64 MB
In:       serial
Out:      serial
Err:      serial
Hit any key to stop autoboot:     0
wch2410 #

结语

       以往将U-BOOT移植到ARM9平台中的解决方案主要针对的是ARM9中的NOR闪存,因为NOR闪存的结构特点致使应用程序可以直接在其内部运行,不用把代码读到RAM中,移植过程相对简单。从NAND闪存中启动U-BOOT的设计难点在于NAND闪存需要把U-BOOT的代码搬移到RAM中,并要让 U-BOOT支持NAND闪存的命令操作。本文介绍了实现这一设计的思路及具体程序。移植后,U-BOOT在嵌入式系统中运行良好。

参考文献

1 杜春雷 . ARM 体系结构与编程 [M]. 北京 : 清华大学出版社, 2003
2 S3C2410 User's Mannual[Z].Samsung


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/lan120576664/archive/2009/10/13/4664301.aspx

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1 Nand flash 工作原理 .......................................................................................................................... 2 1.1 Nand flash 芯片工作原理 ...................................................................................................... 2 1.1.1 芯片内部存储布局及存储操作特点 ........................................................................ 2 1.1.2 重要芯片引脚功能 ..................................................................................................... 3 1.1.3 寻址方式 ...................................................................................................................... 3 1.1.4 Nand flash 主要内设命令详细介绍 ........................................................................... 4 1.2 Nand Flash 控制器工作原理 ................................................................................................. 4 1.2.1 Nand Flash 控制器特性 ............................................................................................... 5 1.2.2 Nand Flash 控制器工作原理 ....................................................................................... 5 1.3 Nand flash 控制器中特殊功能寄存器详细介绍 ................................................................. 5 1.4 Nand Flash 控制器中的硬件 ECC 介绍............................................................................... 6 1.4.1 ECC 产生方法................................................................................................................ 6 1.4.2 ECC 生成器工作过程 ................................................................................................... 6 1.4.3 ECC 的运用 ................................................................................................................... 6 2 在ADS 下 flash 烧写程序................................................................................................................ 7 2.1 ADS 下flash 烧写程序原理及结构....................................................................................... 7 2.2 第三层实现说明 ..................................................................................................................... 7 2.2.1 特殊功能寄存器定义 ................................................................................................. 7 2.2.2 操作的函数实现 ......................................................................................................... 7 2.3 第二层实现说明 ..................................................................................................................... 8 2.3.1 Nand Flash 初始化....................................................................................................... 8 2.3.2 Nand flash 复位 ............................................................................................................ 8 2.3.3 获取 Nand flash ID ...................................................................................................... 9 2.3.4 Nand flash 写入 ........................................................................................................... 9 2.3.5 Nand flash 读取 ..........................................................................................................10 2.3.6 Nand flash 标记坏块 ..................................................................................................12 2.3.7 Nand Flash 检查坏块 .................................................................................................13 2.3.8 擦除指定块中数据 ...................................................................................................13 2.4 第一层的实现 .....................................................................................................................14 2.4.1 NandFlash 烧写主函数说明 .....................................................................................14 3 在 U-BOOTNand Flash 的支持 ................................................................................................16 3.1 U-BOOT 对从Nand Flash 启动的支持 ................................................................................16 3.1.1 从Nand Flash 启动 U-BOOT基本原理 ..............................................................16 3.1.2 支持 Nand Flash 启动代码说明..............................................................................16 3.2 U-BOOTNand Flash 命令的支持 ...................................................................................18 3.2.1 主要数据结构介绍 ...................................................................................................19 3.2.2 支持的命令函数说明 ............................................................................................... 20 3.2.3 U-BOOT 支持 Nand Flash 命令移植说明 ................................................................ 20 4 在 Linux 对Nand Flash 的支持 .....................................................................................................22 4.1 Linux 下Nand Flash 调用关系 ............................................................................................22 4.1.1 Nand Flash 设备添加时数据结构包含关系 ............................................................22 4.1.2 Nand Flash 设备注册时数据结构包含关系 ............................................................22 4.1.3 当发生系统调用时数据结构调用关系 .................................................................23 4.2 Linux 下Nand Flash 驱动主要数据结构说明 ...................................................................23 4.2.1 s3c2410 专有数据结构 ..............................................................................................23 4.2.2 Linux 通用数据结构说明 .........................................................................................24 4.3 Linux 下Nand Flash 驱动说明 ............................................................................................29 4.3.1 注册driver_register ..................................................................................................29 4.3.2 探测设备probe .........................................................................................................30 4.3.3 初始化 Nand Flash 控制器 ......................................................................................30 4.3.4 移除设备 ....................................................................................................................30 4.3.5 Nand Flash 芯片初始化 .............................................................................................31 4.3.6 读Nand Flash ........................................................................................................31 4.3.7 写 Nand Flash ...........................................................................................................31
所有资料来源网上,与朋友分享 u-boot-1.1.6之cpu/arm920t/start.s分析 2 u-boot中.lds连接脚本文件的分析 12 分享一篇我总结的uboot学习笔记(转) 15 U-BOOT内存布局及启动过程浅析 22 u-boot中的命令实现 25 U-BOOT环境变量实现 28 1.相关文件 28 2.数据结构 28 3.ENV 的初始化 30 3.1env_init 30 3.2 env_relocate 30 3.3*env_relocate_spec 31 4. ENV 的保存 31 U-Boot环境变量 32 u-boot代码链接的问题 35 ldr和adr在使用标号表达式作为操作数的区别 40 start_armboot浅析 42 1.全局数据结构的初始化 42 2.调用通用初始化函数 43 3.初始化具体设备 44 4.初始化环境变量 44 5.进入主循环 44 u-boot编译过程 44 mkconfig文件的分析 47 从NAND闪存中启动U-BOOT的设计 50 引言 50 NAND闪存工作原理 51 从NAND闪存启动U-BOOT的设计思路 51 具体设计 51 支持NAND闪存的启动程序设计 51 支持U-BOOT命令设计 52 结语 53 参考文献 53 U-boot给kernel传参数和kernel读取参数—struct tag (以及补充) 53 1 、u-boot 给kernel 传RAM 参数 54 2 、Kernel 读取U-boot 传递的相关参数 56 3 、关于U-boot 中的bd 和gd 59 U-BOOT源码分析及移植 60 一、u-boot工程的总体结构: 61 1、源代码组织 61 2.makefile简要分析 61 3、u-boot的通用目录是怎么做到与平台无关的? 63 4、smkd2410其余重要的文件 : 63 二、u-boot的流程、主要的数据结构、内存分配 64 1、u-boot启动流程: 64 2、u-boot主要的数据结构 66 3、u-boot重定位后的内存分布: 68 三、u-boot的重要细节 。 68 关于U-boot中命令相关的编程 : 73 四、U-boot在ST2410的移植,基于NOR FLASHNAND FLASH启动。 76 1、从smdk2410到ST2410: 76 2、移植过程: 76 3、移植要考虑的问题: 77 4、SST39VF1601: 77 5、我实现的flash.c主要部分: 78 6、增加从Nand 启动的代码 : 82 7、添加网络命令。 87

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值