本文只是对该函数的注释,方便之后查阅,可能有误,请高手指正。

/*** nand_fill_oob - [INTERN] Transfer client buffer to oob* @mtd: MTD device structure* @oob: oob data buffer* @len: oob data write length* @ops: oob ops structure*/
static uint8_t *nand_fill_oob(struct mtd_info *mtd, uint8_t *oob, size_t len,struct mtd_oob_ops *ops)
{struct nand_chip *chip = mtd_to_nand(mtd);/** Initialise to all 0xFF, to avoid the possibility of left over OOB* data from a previous OOB read.*/memset(chip->oob_poi, 0xff, mtd->oobsize);switch (ops->mode) {case MTD_OPS_PLACE_OOB:case MTD_OPS_RAW:memcpy(chip->oob_poi + ops->ooboffs, oob, len);return oob + len;case MTD_OPS_AUTO_OOB: {struct nand_oobfree *free = chip->ecc.layout->oobfree;uint32_t boffs = 0, woffs = ops->ooboffs;size_t bytes = 0;for (; free->length && len; free++, len -= bytes) {/* Write request not from offset 0? */if (unlikely(woffs)) {if (woffs >= free->length) {woffs -= free->length;continue;}boffs = free->offset + woffs;bytes = min_t(size_t, len,(free->length - woffs));woffs = 0;} else {bytes = min_t(size_t, len, free->length);boffs = free->offset;}memcpy(chip->oob_poi + boffs, oob, bytes);oob += bytes;}return oob;}default:BUG();}return NULL;
}

这个函数不长。

1. 首先看一下三个宏的注释

/**
 * MTD operation modes
 *
 * @MTD_OPS_PLACE_OOB:    OOB data are placed at the given offset (default)

这个说是会把oob放置在指定的位置
 * @MTD_OPS_AUTO_OOB:    OOB data are automatically placed at the free areas
 *            which are defined by the internal ecclayout

这个说是把oob放置到空闲的位置,空闲位置由ecclayout指定
 * @MTD_OPS_RAW:    data are transferred as-is, with no error correction;
 *            this mode implies %MTD_OPS_PLACE_OOB
 *        这个说,数据和它本身一致,没有ecc
 * These modes can be passed to ioctl(MEMWRITE) and are also used internally.
 * See notes on "MTD file modes" for discussion on %MTD_OPS_RAW vs.
 * %MTD_FILE_MODE_RAW.
 */
enum {
    MTD_OPS_PLACE_OOB = 0,
    MTD_OPS_AUTO_OOB = 1,
    MTD_OPS_RAW = 2,
};

2. memset(chip->oob_poi, 0xff, mtd->oobsize);

对oob的数组填充0xff。mtd->oobsize指定缓存有多大。

3.case MTD_OPS_PLACE_OOB:
    case MTD_OPS_RAW:
        memcpy(chip->oob_poi + ops->ooboffs, oob, len);
        return oob + len;

对于以上两种情况,ops->ooboffs 指定偏移地址,oob指向存有ecc的缓存,len指定oob缓存中有的字节数。

就是,拷贝oob中的数据到chip->oob_poi这个数组中(注意下标被指定了ops->ooboffs,而可能是不为0的),拷贝的字节数为len

其中oob的值由参数传入,len的值由参数传入。

注意返回值为oob + len,是个地址值。

4. 对于自动放置的情况

case MTD_OPS_AUTO_OOB: {
        struct nand_oobfree *free = chip->ecc.layout->oobfree;   //oobfree 是指的空闲区的头指针,可能不止一个
        uint32_t boffs = 0, woffs = ops->ooboffs; //起始位置
        size_t bytes = 0;

//需要考虑的情况是一个空闲区域可能写不下,所以要for循环处理。

for (; free->length && len; free++, len -= bytes) {    //空闲区长度不为0,且要写的长度len不为0
            /* Write request not from offset 0? */
            if (unlikely(woffs)) {     //woffs 大于 0。 //woffs取0的可能性比较大
                if (woffs >= free->length) {   大于等于,写的偏移比空闲长度大。因为指定了偏移woffs,所以要把前面的位置空出来。
                    woffs -= free->length;    //减去
                    continue; 
                }
                boffs = free->offset + woffs;   //开始写的位置boffs,此时woffs可能还不为0,但是已经小于free->length,所以还要在偏移一点点woffs,但是这次已经落在free区间了。
                bytes = min_t(size_t, len,
                          (free->length - woffs));   //取出较小的值
                woffs = 0;   //偏移清零
            } else {   //woffs 等于0
                bytes = min_t(size_t, len, free->length);   //对len和free->length取个小的
                boffs = free->offset;  //起始位置,是free区域的起始偏移位置
            }
            memcpy(chip->oob_poi + boffs, oob, bytes);    //写入字节,最大长度为bytes
            oob += bytes;   //oob的指针向后移动。
        }  //end for
        return oob;

} //end case

分析到此结束。

应该来说还是比较简单。

uboot2021.10-nandflash-1.nand_fill_oob相关推荐

  1. uboot 2021.10源码分析(启动流程)

    uboot版本:2021.10 平台:armv8  rk3399  eMMC 16G  LPDDR4 4G 本文主要基于uboot的执行流程进行分析而忽略了相关细节,从uboot的基本框架结构着手,新 ...

  2. U-Boot 之一 零基础编译 U-Boot 过程详解 及 编译后的使用说明

      在之前的博文 Linux 之八 完整嵌入式 Linux 环境介绍及搭建过程详解 中我们说了要一步步搭建整个嵌入式 Linux 运行环境,今天就开始编译 U-Boot.我所使用的硬件平台及整个要搭建 ...

  3. Flash(NandFlashNorFlash)基本原理

    本文中最主要的资料来源于开源组织对NandFlash的结构定义以及电气规范.测试规范定义的文档:<Open Nand Flash Interface> 一.Flash基本原理及分类 1.1 ...

  4. 【技术三千问】之《FLASH问题难点解析》,干货汇总!

    技术三千问: [技术三千问]之<玩转ART-Pi>,看这篇就够了!干货汇总 [技术三千问]之<AT组件问题汇总与解析>,干货汇总! [技术三千问]之<UART串口问题解析 ...

  5. U-Boot 之一 零基础编译 U-Boot 过程详解、Image 镜像介绍及使用说明、DTB 文件使用说明

      最近,工作重心要从裸机开发转移到嵌入式 Linux 系统开发,在之前的博文 Linux 之八 完整嵌入式 Linux 环境.(交叉)编译工具链.CPU 体系架构.嵌入式系统构建工具 中详细介绍了嵌 ...

  6. H3CNE最新版官网考试模拟题库

    以下工作于OSI 参考模型数据链路层的设备是__A____.(选择一项或多项) A. 广域网交换机 B. 路由器 C. 中继器 D. 集线器 A 数据链路层传输的是帧,交换机是基于帧转发的:B 路由器 ...

  7. MTD NANDFLASH驱动相关知识介绍

    转:http://blog.csdn.net/zhouzhuan2008/article/details/11053877 目录 MTD总概述 MTD数据结构 MTD相关层实现 MTD,Memory ...

  8. NandFlash详述【转】

    NandFlash详述 转自:http://wenku.baidu.com/view/04d9330bb52acfc789ebc92f.html?re=view 1. 硬件特性: [Flash的硬件实 ...

  9. WinCE开机Logo的实现(USB下载图片到nandflash)

    WinCE开机启动Logo使用Eboot读取NandFlash中的图片数据,然后显示的方式.对于开机logo的方式网友http://jazka.blog.51cto.com/809003/664131 ...

  10. Nandflash 驱动移植

    前段时间,研究了一下4G的Nandflash驱动.手头上只有飞凌6410BSP自带的Nandflash驱动,该驱动不支持K9GAG08U0D(2G)和K9LBG08U0D(4G)的Nandflash. ...

最新文章

  1. 【树莓派】【转载】基于树莓派,制作家庭媒体中心+下载机
  2. 阿里要未来,百度要利益?
  3. 深入浅出理解 Variable used in lambda expression should be final or effectively final
  4. redis开启redis_Redis聚类
  5. leetcode852. 山脉数组的峰顶索引(二分法)
  6. 去空白符的大文本字符统计(洛谷P5015题题解,Java语言描述)
  7. 大数据之-Hadoop3.x_MapReduce_WordCount案例集群运行---大数据之hadoop3.x工作笔记0093
  8. html基础技术笔记
  9. saltstack return数据实时返回收集
  10. 网络流 poj 2195
  11. j2me模拟器linux,J2ME HELLOWORLD 小试牛刀(转)
  12. git 小乌龟 配置_git 小乌龟安装教程
  13. 支付宝支付即时到账接口在ThinkPHP商城中的应用(转载)
  14. Shiro集成Cas单点登录
  15. windows 域介绍
  16. java 最新手机号校验
  17. js中怎样把ASCII码中的字符与十进制的数相互转换-学习笔记
  18. 深度解析大数据在公安领域的应用
  19. eWebEditor在线编辑器
  20. Java代码审计前置知识——SpringBoot基础

热门文章

  1. 以太网没有有效的IP配置
  2. CAD二次开发(C#) 第二节
  3. TensorFlow Ranking框架在海外推荐业务中的实践与应用
  4. Apache Shiro 1.2.4 反序列化漏洞(CVE-2016-4437 )
  5. WebMagic爬取小说网站所有小说
  6. SRS:连麦和多个视频号联播
  7. python爬虫微信刷票_Python爬虫教程:你还在苦苦拉票吗?刷票小程序案例原理剖析!...
  8. java version什么意思_输入java -version命令后提示结果如下,是什么意思??哪位能看懂,在线等。。。。...
  9. 天线越大越好吗_路由器的天线是不是越多越好?告知你真实答案,很多人都买错了...
  10. 这篇文章应该在《新闻联播》连续报道一个月--武汉大学毕业生的反思