`
coolerbaosi
  • 浏览: 726441 次
文章分类
社区版块
存档分类
最新评论

uboot 的nand驱动

 
阅读更多

s3c2410移植nand支持到uboot, 使用nand.c ,linux mtd 架构 【2】

u-boot-1.1.6与1.1.4相比,两者有较大的不同,1.1.6 更像是复制了 kernel 的方法来实现。

下面对nand flash的初始化代码nand_init()进行分析:


1.如果定义(CONFIG_COMMANDS & CFG_CMD_NAND)没定义(CFG_NAND_LEGACY) 则start_armboot()调用driver/nand/nand.c中的nand_init(),否则如果定义(CONFIG_COMMANDS & CFG_CMD_NAND)并且有定义了CFG_NAND_LEGACY,则调用自己定义的nand_init()。现在使用 driver/nand/nand.c中的nand_init()。
2.nand_init()调用本文件中的nand_init_chip()对nand进行初始化。
3.nand_init_chip()首先调用board_nand_init()。
4.board_nand_init()是需要自己添加的函数,这个函数的主要功能是对struct nand_chip结构体的函数指针赋值,让它们指向自己为nand驱动编写的一些函数,对未赋值的指针,uboot会在后面为其赋上通用nand驱动函数指针。此函数可放到自己板子目录的文件下。
5.nand_init_chip()接着调用nand_scan().
6.nand_scan()定义在drivers/nand/nand_base.c文件中。它首先对struct nand_chip结构体中在board_nand_init()函数中未赋值的指针赋上通用nand驱动函数指针。
7.nand_scan()->select_chip = nand_select_chip;

此函数用于打开或关闭nand芯片,0为打开,1为关闭。在这个函数中会调用nand_chip结构体中的 hwcontrol函数指针。 hwcontrol在board_nand_init()函数中被赋值。主要作用是向 nand flash发送一些nand flash开启与关闭命令。
8.nand_scan()剩余部分初始化nand_chip和mtd_info结构体。
9.nand_scan()最后在返回时调用drivers/nand/nand_bbt.c文件中的nand_default_bbt()。
nand_default_bbt()选择一个坏块描述表,返回时调用本文件中的nand_scan_bbt()(寻找建立一个坏块描述表)
10.最后返回到nand_init(),这样nand驱动的初始化完成了。

通过上述步骤我们可以知道,移植nand主要按如下步骤:

1、在board/xxx下建立c文件

2、在此文件上添加函数board_nand_init(),实现nand_chip的初始化功能

3、添加初始化的函数

4、在include/configs/xxx.h中定义相关宏,比如#define CFG_MAX_CHIPS

完成上述移植后,实际上启动后的uboot中的nand命令是通过include/nand.h实现的,例如nand erase调用了:

static inline int nand_erase(nand_info_t *info, ulong off, ulong size)

看看人家怎么做的:

//----------------------------------------------------------------------------------------------------

为了让uboot支持自己QT板子的nand flash而进行修改的部分<wbr></wbr>
1.前面的移植请参考我写的一篇《U-Boot的编译与移植到QT-S3C44B0X开发板上》,现在在board/51EDA/QT/目录下建立nand.c文件。
2.在nand.c中添加自己的board_nand_init()函数。设定nand_chip结构中的hwcontrol和dev_ready指针指向自己的函数QT_hwcontrol和QT_device_ready。并建立自己的QT_hwcontrol和QT_device_ready函数。
3.由于自己板子的nand flash的命令发送方式与uboot提供的通用nand flash命令发送方式不同,所以在nand.c文件中建立自己的命令发送函数QT_nand_command(),并在 board_nand_init()函数中将nand_chip结构中的cmdfunc指针指向QT_nand_command()函数,使其使用自己定义的发送命令函数。
4.在include/configs/QT.h中定义CFG_NAND_BASE用于指定自己板子nand flash的I/O地址。
5.在CONFIG_COMMANDS中打开CFG_CMD_NAND选项。
6.在include/configs/QT.h中定义NAND_MAX_CHIPS指定自己板子的nand flash芯片数。
7.在include/configs/QT.h中定义CFG_MAX_NAND_DEVICE指定想要支持的nand flash设备数。

//这是比较深入的分析:

//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

U-BOOT Nand命令支持
u-boot1.1.6 nand_legacy驱动提供了u-boot对nand相关命令的一个轻量级的实现,但好象可扩展性不足。本文主要分析u-boot 1.16/drivers/nand文档夹下的源程式。
一.关键数据结构
1.struct mtd_info
该结构在include\linux\mtd\Mtd.h中定义,字段比较多,有很多还是函数指针,他是MTD设备操作的通用接口,这个结构中有一个比较重要的成员 void *priv,priv被声明成void指针,在下文的分析中会知道priv实际上指向了nand_chip结构。
2.struct nand_chip
<wbr><wbr>该结构在include\linux\mtd\Nand.h中定义,从名字上看就知道u-boot用他来描述Nand Flash芯片的结构,比如他定义了页地址的偏移,页地址的位掩码等。struct nand_chip不用我们手动的初始化,而是由另外一个结构,struct nand_flash_dev在程式中动态的初始化。<br style="line-height:22px"> 3.struct nand_flash_dev<br style="line-height:22px"><wbr><wbr> 该结构的定义有两处地方分别是<br style="line-height:22px"> ①include/linux/mtd/nand_legacy.h 由nand_legacy模块使用<br style="line-height:22px"> ②include/linux/mtd/nand.h<wbr><wbr><wbr><wbr> 由u-boot通用nand架构使用<br style="line-height:22px"> 特别是在移植的时候要小心把两者混淆。我们先来看看改结构的定义<br style="line-height:22px"> struct nand_flash_dev {<br style="line-height:22px"><wbr><wbr><wbr><wbr> char *name;<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><br style="line-height:22px"><wbr><wbr><wbr><wbr> int id;<br style="line-height:22px"><wbr><wbr><wbr><wbr> unsigned long pagesize;<br style="line-height:22px"><wbr><wbr><wbr><wbr> unsigned long chipsize;<br style="line-height:22px"><wbr><wbr><wbr><wbr> unsigned long erasesize;<br style="line-height:22px"><wbr><wbr><wbr><wbr> unsigned long options;<br style="line-height:22px"> };<br style="line-height:22px"> name : Nand Flash名称<br style="line-height:22px"> id : u-boot内部id编号???<br style="line-height:22px"> chipsize : 以MB为单位的芯片大小,比如64(M)<br style="line-height:22px"> erasesize : 擦除块的大小,比如0x4000(16K)<br style="line-height:22px"> options : 一些选项,比较重要的是Flash的数据位宽,假如您的Nand Flash是16位宽的,则必须包含NAND_BUSWIDTH_16选项。我们必须根据所使用的Nand Flash来填充里面的字段。<br style="line-height:22px"> 4.关键数据结构在程式中的使用<br style="line-height:22px"> struct nand_info_t nand_info[ CFG_MAX_NAND_DEVICE ];<br style="line-height:22px"> 在 drivers\nand\nand.c中定义。CFG_MAX_NAND_DEVICE是板子的Nand Flash芯片的数量必须在板子的配置文档中定义(比如 include\configs\smdk2410.h)。<br style="line-height:22px"><br style="line-height:22px"> static struct nand_chip nand_chip[CFG_MAX_NAND_DEVICE];<br style="line-height:22px"> 在drivers\nand\nand.c中定义。CFG_MAX_NAND_DEVICE的定义同上。<br style="line-height:22px"><br style="line-height:22px"> struct nand_flash_dev nand_flash_ids[] = { … };<br style="line-height:22px"> 在drivers\nand\nand_ids.c中定义。这里要注意一点,在include\linux\mtd\nand_ids.h里面也 nand_flash_ids[]的定义,那是由nand legacy驱动模块使用的。两者不能混淆!!!。在nand_flash_ids的定义中我找到了适合我的Nand Flash的结构描述:<br style="line-height:22px"> {"NAND 64MiB 3,3V 8-bit",<wbr><wbr><wbr><wbr><wbr><wbr>0x76, 512, 64, 0x4000, 0}<br style="line-height:22px"> 设备ID为0x76,页大小为512Byte,总的容量为64M,擦除块为0x4000(16K),数据位宽8Bit。假如您的Nand Flash没有合适的描述,需要自己在该数组中添加相应的定义。<br style="line-height:22px"><br style="line-height:22px"> 二.Nand Flash初始化<br style="line-height:22px"><br style="line-height:22px"> 1.nand_init( drivers\nand\nand.c )<br style="line-height:22px"> nand_init函数在lib_xxx/Board.c的start_armboot中调用。是u-boot Nand的主函数。nand_init的主要功能是对CFG_MAX_NAND_DEVICE个Nand设备进行初始化(调用 nand_init_chip),累加Nand Flash的总大小。在nand_init结束时,能够配置是否执行board_nand_select_device,选择Nand芯片。<br style="line-height:22px"> 2.nand_init_chip( drivers\nand\nand.c )<br style="line-height:22px"> static void nand_init_chip( struct mtd_info *mtd, struct nand_chip *nand, ulong base_addr )调用各个研发板提供的 board_nand_init 函数( board\\.c )让研发板获得初始化Nand Flash芯片的机会。调用 nand_scan。<br style="line-height:22px"> 3.nand_scan ( drivers\nand\nand_base.c )<br style="line-height:22px"> int nand_scan( struct mtd_info *mtd, int maxchips )<br style="line-height:22px"> 这是u-boot初始化nand设备的核心函数。他主要完成以下工作<br style="line-height:22px"><br style="line-height:22px"> 1)初始化nand_chip的函数指针,这些函数一般在 board\\.c中定义。<br style="line-height:22px"> …<br style="line-height:22px"> struct nand_chip *this = mtd-&gt;priv<br style="line-height:22px"> ....<br style="line-height:22px"> if( this-&gt; cmdfunc == NULL )<br style="line-height:22px"><wbr><wbr><wbr><wbr> this-&gt;cmdfunc = nand_command;<br style="line-height:22px"> …<br style="line-height:22px"> 上面是初始化nand_chip中cmdfunc指针的代码,假如在board_init_nand中研发板没有提供自己的nand_command函数,u-boot 将使用默认的nand_command函数(我觉得u-boot提供的这些默认的函数都不适合特定的硬件,所以很多都要自己重新写)。<br style="line-height:22px"><br style="line-height:22px"> 2)使用上面注册的函数指针,读取Nand Flash的设备,并且在上文提到的nand_flash_ids[]中找是否有匹配项,若找到匹配的项,则初始化 nand_chip 和 mtd_info,他们的初始化代码老长的一段,一般没什么问题。<br style="line-height:22px"><br style="line-height:22px"> 三. Nand Flash 操作<br style="line-height:22px"> 1. Read<br style="line-height:22px"> 函数调用层次:(如下图)。<span><wbr></wbr></span><br style="line-height:22px"><img title="[转载]s3c2410移植nand支持到uboot, 使用nand.c ,linux mtd 架构 【2】 - lanmanck的专栏 - CSDN博客 - deshunfan - 电子屋" border="0" alt="[转载]s3c2410移植nand支持到uboot, 使用nand.c ,linux mtd 架构 【2】 - lanmanck的专栏 - CSDN博客 - deshunfan - 电子屋" src="http://blogimg.chinaunix.net/blog/upfile/070908103517.gif" width="519" height="312" style="line-height:22px; border-right-width:0px; max-width:100%; border-top-width:0px; border-bottom-width:0px; border-left-width:0px"><span><wbr></wbr></span><br style="line-height:22px"> 以common/env_nand.c里面读取Nand Flash中的环境变量为例<br style="line-height:22px"> common/env_nand.c<br style="line-height:22px"> ret = nand_read( &amp;nand_info[0], CFG_ENV_OFFSET, &amp;total, (u_char*)env_ptr );<br style="line-height:22px"><br style="line-height:22px"> nand_info[]就是我们在1.4讲到的nand_info_t(mtd_info的别名)数组。此处的nand_read是个inline函数,下面是他的实现:<br style="line-height:22px"><br style="line-height:22px"> include/nand.h<br style="line-height:22px"> static inline int nand_read(nand_info_t *info, ulong ofs, ulong *len, u_char *buf)<br style="line-height:22px"> {<br style="line-height:22px"><wbr><wbr><wbr><wbr> return info-&gt;read(info, ofs, *len, (size_t*)len, buf);<br style="line-height:22px"> }<br style="line-height:22px"><br style="line-height:22px"> 能够看出nand_read实际上调用的是nand_info的read方法。nand_info的read方法是在2.3中讲到的nand_scan中初始化<br style="line-height:22px"> drivers/nand/nand_base.c<br style="line-height:22px"> int nand_scan(struct mtd_info *mtd, int machips)<br style="line-height:22px"> {<br style="line-height:22px"><wbr><wbr><wbr><wbr> …<br style="line-height:22px"><wbr><wbr><wbr><wbr> mtd-&gt;read = nand_read;<br style="line-height:22px"><wbr><wbr><wbr><wbr> …<br style="line-height:22px"> }<br style="line-height:22px"> 此处又一个nand_read!!!<br style="line-height:22px"><br style="line-height:22px"> drivers/nand/nand_base.c<br style="line-height:22px"> static int nand_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)<br style="line-height:22px"> {<br style="line-height:22px"><wbr><wbr><wbr><wbr> return nand_read_ecc( mtd, from, len, retlen, buf, NULL, NULL );<br style="line-height:22px"> }<br style="line-height:22px"><br style="line-height:22px"> 又一层包装!!!<br style="line-height:22px"><br style="line-height:22px"> drivers/nand/nand_base.c<br style="line-height:22px"> static int nand_read_ecc(…)<br style="line-height:22px"> {<br style="line-height:22px"><wbr><wbr><wbr><wbr> …<br style="line-height:22px"> }<br style="line-height:22px"> 终于到达最后一层了,nand_read_ecc通过调用nand_chip里面提供的函数对nand flash完成读的操作。具体能够看看代码,老长的一段。</wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>

分享到:
评论

相关推荐

    uboot nand驱动_completely1no_s3c2440_NAND_nandflash驱动程序_

    这是 s3c2440开发板 的 nandflash程序 可供学习和移植

    lpc24xx下uboot-1.1.6nandflash驱动

    lpc24xx平台下uboot-1.1.6 nandflash的驱动

    uboot移植内核学习方法

    二,移植支持Nand flash驱动的uboot 加入Nand flash驱动的支持,可以在uboot命令行下操作Nand flash.但还未能从Nand flash启动,只能在Nor flash内运行. 三,移植可以从Nor flash启动的uboot 可以烧录在Nand flash,并...

    NAND Flash的驱动程序设计

    设计了NAND Flash与S3C2410的接口电路,介绍了NAND Flash在ARM嵌入式系统中的设计与实现方法,并在UBoot上进行了验证。所设计的驱动易于移植,可简化嵌入式系统开发。

    驱动程序编程uBoot初始化

    大家一起来,,学习共享!!u-Boot的初始化过程,,。

    lpc24xx下uboot-1.1.6norflash驱动

    lpc24xx平台下uboot-1.1.6nandflash的驱动

    linux nand flash驱动编写

    对于linux嵌入式来说,开始uboot的加载是硬件完成的,中期的kernel加载是由uboot中的nand flash驱动完成的,而后期的rootfs加载,这就要靠kernel自己来完成了。当然,这次还是以三星s3c芯片为例进行说明。 1、nand ...

    uboot1.1.6 ARM9 2440 移植文档

    自己写的关于TQ2440的uboot移植文档, 增加了NAND读写驱动,DM9000驱动,并支持NAND和NOR FLASH两种启动方式。

    在Linux运行期间升级Linux系统(Uboot+kernel+Rootfs) v1.0

    介绍了如何实现在线升级linux系统,即uboot,kernel,rootfs, 以及相关的前提知识和准备工作 目录 1. 正文之前 3 1.1. 此文目的 3 1.2. 一点说明 3 2. 嵌入式系统中,如何在Linux运行的时候去升级Linux系统 4 2.1. ...

    用DNW通过USB烧uboot到nand

     我们这时把USB线插到主板和主机,如果是次使用,则会弹出对话框提示安装驱动,安装完驱动后会提示如下图:  我们配置一下要到内存的位置,选择菜单  Configuration Options 如下图:  在Download...

    tiny210-uboot.bin

    6添加Nand Flash驱动,开启所有nand cmd,支持NAND Flash读写 7添加yaffs文件系统烧写支持 8 uboot引导linux内核 9 添加NAND启动功能 10 添加启动自动识别功能,能自动从NAND或MMC/SD中启动 修改在SD/MMC启动及NAND...

    EDA/PLD中的用DNW通过USB烧uboot到nand

     我们这时把USB线插到主板和主机,如果是第一次使用,则会弹出对话框提示安装驱动,安装完驱动后会提示如下图:  我们配置一下要下载到内存的位置,选择菜单  Configuration Options 如下图:  在...

    韦东山Linux视频第1期_裸板_UBoot_文件系统_驱动初步

    第5课 NAND FLASH控制器 第6课 中断控制器 第7课 系统时钟和UART实验 第8课 LCD实验 第9课第1节 u-boot分析之编译体验 第9课第2节 u-boot分析之Makefile结构分析 第9课第3节 u-boot分析之源码第1阶段 第9课第...

    uboot1.1.6完全注释

    1:nand flash初始化及部分驱动 2:nor flash初始化及部分函数 3:dm9000初始化及驱动 4:init_sequence数组所有函数 5:环境变量的初始化 6:main_loop循环以及命令的解析执行 10分资源只赚不亏。

    【正点原子】I.MX6U嵌入式Linux驱动开发指南V1.3.pdf

    4、修改 30.4.8 小节,删除 uboot 中更新 NAND 版的 u-boot.imx,并加以说明。 5、修改第五章 ,添加对于 I.MX6U-Mini 开发 板的支持,调整了第五章的章节顺序。 6、修改 64.6 小节,修改编译内核自带 FT5X06 驱动...

    uboot20106 mini2440 norflash

    本代码是从NORFLASH 启动的,移植的驱动包括nandFlash(256MB,8bit),以及网络部分代码(DM9000,已经调试通过)。参考了网上的部分资料,并且在mini2440开发板上调试。Linux镜像使用tftp下载到内存中运行,注意:...

    s3c6410简易版uboot

    所完成的驱动有: 1、DDR 2、NAND 3、串口 4、按键(测试时直接按键即可输出按键被按下还是抬起) 5、LED 本裸机代码CPU时钟可选(533/667/800),经过试验800MHz也可正常运行,不过发热量稍大,不建议使用800MHz。...

    史上最强的嵌入式底层驱动开发课程 Linux系统开发+Linux高级程序+主板开发+ARM等

    │ ├66 - 驱动开发板资源7.mp4 │ ├67 - bootloader概述1.mp4 │ ├68 - bootloader概述2 .avi │ ├69 - bootloader概述3.avi │ ├70 - bootloader概述4.mp4 │ ├71 - bootloader概述5.mp4 │ ├72 - C5工程...

Global site tag (gtag.js) - Google Analytics