[ Linux Busybox ] flash_eraseall 命令解析

文章目录

    • 相关结构体
    • flash_eraseall 函数实现
    • flash_eraseall 实现流程图


文件路径:busybox-1.20.2/miscutils/flash_eraseall.c

相关结构体

MTD 相关信息结构体

struct mtd_info_user {__u8 type;              // MTD 设备类型__u32 flags;            // MTD设备属性标志__u32 size;             // mtd设备的大小__u32 erasesize;        // MTD设备的擦除单元大小,对于 NandFlash来说就是 Block的大小__u32 writesize;        // MTD设备的读写单元大小,对于 NandFlash来说就是page 的大小__u32 oobsize;          // oob区域大小__u64 padding;          // 有效的oob区域大小
};

flash_eraseall 函数实现

假如内核位于第二个分区,即mtd2,在擦除该分区时使用的命令是:./flash_eraseall /dev/mtd2

int flash_eraseall_main(int argc UNUSED_PARAM, char **argv)
{struct jffs2_unknown_node cleanmarker;mtd_info_t meminfo;int fd, clmpos, clmlen;erase_info_t erase;struct stat st;unsigned int flags;char *mtd_name;opt_complementary = "=1";flags = BBTEST | getopt32(argv, "jq");    // 获取命令行中参数mtd_name = argv[optind];fd = xopen(mtd_name, O_RDWR);        // 打开设备/dev/mtd2fstat(fd, &st);        if (!S_ISCHR(st.st_mode))            // 判断设备/dev/mtd2 是否为字符设备bb_error_msg_and_die("%s: not a char device", mtd_name);xioctl(fd, MEMGETINFO, &meminfo);        // 获取内存信息,参看结构体1erase.length = meminfo.erasesize;if (meminfo.type == MTD_NANDFLASH)flags |= IS_NAND;clmpos = 0;clmlen = 8;if (flags & OPTION_J) {                // jffs2格式化分区uint32_t *crc32_table;crc32_table = crc32_filltable(NULL, 0);cleanmarker.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);cleanmarker.nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER);if (!(flags & IS_NAND))cleanmarker.totlen = cpu_to_je32(sizeof(struct jffs2_unknown_node));else {struct nand_oobinfo oobinfo;xioctl(fd, MEMGETOOBSEL, &oobinfo);/* Check for autoplacement */if (oobinfo.useecc == MTD_NANDECC_AUTOPLACE) {/* Get the position of the free bytes */clmpos = oobinfo.oobfree[0][0];clmlen = oobinfo.oobfree[0][1];if (clmlen > 8)clmlen = 8;if (clmlen == 0)bb_error_msg_and_die("autoplacement selected and no empty space in oob");} else {/* Legacy mode */switch (meminfo.oobsize) {case 8:clmpos = 6;clmlen = 2;break;case 16:clmpos = 8;/*clmlen = 8;*/break;case 64:clmpos = 16;/*clmlen = 8;*/break;}}cleanmarker.totlen = cpu_to_je32(8);}cleanmarker.hdr_crc = cpu_to_je32(crc32_block_endian0(0, &cleanmarker, sizeof(struct jffs2_unknown_node) - 4, crc32_table));}/* Don't want to destroy progress indicator by bb_error_msg's */applet_name = xasprintf("\n%s: %s", applet_name, mtd_name);for (erase.start = 0; erase.start < meminfo.size;    // 循环擦除flash芯片,按块大小擦除 meminfo.erasesizeerase.start += meminfo.erasesize) {if (flags & BBTEST) {int ret;loff_t offset = erase.start;ret = ioctl(fd, MEMGETBADBLOCK, &offset);        //通过offset,判定该偏移处是否是坏块if (ret > 0) {if (!(flags & OPTION_Q))                    //  判断是否为静默模式(不打印信息)bb_info_msg("\nSkipping bad block at 0x%08x", erase.start);continue;}if (ret < 0) {            // block块表是不可用的某些flash类型,如NOR/* Black block table is not available on certain flash* types e.g. NOR*/if (errno == EOPNOTSUPP) {flags &= ~BBTEST;if (flags & IS_NAND)bb_error_msg_and_die("bad block check not available");} else {bb_perror_msg_and_die("MEMGETBADBLOCK error");}}}//更新擦除进度条if (!(flags & OPTION_Q))show_progress(&meminfo, &erase);// 块擦除操作xioctl(fd, MEMERASE, &erase);/* format for JFFS2 ? */if (!(flags & OPTION_J))continue;/* write cleanmarker */if (flags & IS_NAND) {struct mtd_oob_buf oob;oob.ptr = (unsigned char *) &cleanmarker;oob.start = erase.start + clmpos;oob.length = clmlen;xioctl(fd, MEMWRITEOOB, &oob);} else {xlseek(fd, erase.start, SEEK_SET);/* if (lseek(fd, erase.start, SEEK_SET) < 0) {bb_perror_msg("MTD %s failure", "seek");continue;} */xwrite(fd, &cleanmarker, sizeof(cleanmarker));/* if (write(fd, &cleanmarker, sizeof(cleanmarker)) != sizeof(cleanmarker)) {bb_perror_msg("MTD %s failure", "write");continue;} */}if (!(flags & OPTION_Q))printf(" Cleanmarker written at %x.", erase.start);}if (!(flags & OPTION_Q)) {show_progress(&meminfo, &erase);bb_putchar('\n');}if (ENABLE_FEATURE_CLEAN_UP)close(fd);return EXIT_SUCCESS;
}

注:
cleanmarker是用于标记一个块是否完整地被擦除的。 在Flash存储器中,只有在块完整地擦除后才能进行写入操作。这是因为在某些特殊情况下,比如系统在擦除周期末尾重启,可能导致Flash中的位不稳定,即读出的值可能在不同时间点不一致。为了解决这个问题,引入了cleanmarker来标记块是否真正完整地擦除。

在制作jffs2文件系统时,由于文件系统会对块进行管理,因此不再需要使用cleanmarker标记。 在制作文件系统时,可以使用-n或–no-cleanmarker选项来表示不使用cleanmarker。这意味着在第一次挂载文件系统时,cleanmarker并不重要。而在使用mtd工具flash_eraseall对Flash进行格式化时,应该使用 -j 参数来带上cleanmarker标记。这样,在擦除完Flash后,会在oob(out-of-band)区域设置相应的cleanmark位,表示该块已经完整擦除。这样,在以后对该块进行操作时,jffs2文件系统可以发现该块已经被擦除,从而避免浪费时间重新擦除已经是0xff的块。


flash_eraseall 实现流程图

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/163652.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

VSCode修改主题为Eclipse 绿色护眼模式

前言 从参加开发以来&#xff0c;一直使用eclipse进行开发&#xff0c;基本官方出新版本&#xff0c;我都会更新。后来出来很多其他的IDE工具&#xff0c;我也尝试了&#xff0c;但他们的主题都把我劝退了&#xff0c;黑色主题是谁想出来&#xff1f;&#x1f602; 字体小的时…

docker安装达梦数据库镜像并初始化实例设置数据库大小写不敏感

全文参考文章Docker - 通过容器安装部署达梦数据库教程 以及docker安装达梦V8数据库 UTF-8及大小写敏感问题 一、安装部署达梦数据库 下载完成之后使用FileZilla上传到服务器上面 启动命令 创建dm8的容器并设置大小写不敏感运行 docker run -d -p 5236:5236 \ --restartalwa…

移远EC600U-CN开发板 day02

1.QuecPythonLVGL显示图片 由于官方提供的显示图片函数使用失败&#xff0c;为了能在屏幕上显示图片&#xff0c;通过对出厂脚本的分析&#xff0c;成功使用LVGL显示图片 (1)代码 import lvgl as lv from tp import gt9xx from machine import LCD from machine import Pin …

【网络协议】聊聊HTTPDNS如何工作的

传统 DNS 存在哪些问题&#xff1f; 域名缓存问题 我们知道CND会进行域名解析&#xff0c;但是由于本地会进行缓存对应的域名-ip地址&#xff0c;所以可能出现过期数据的情况。 域名转发问题 出口 NAT 问题 域名更新问题 解析延迟问题 因为在解析DNS的时候&#xff0c;需要进行…

K7系列FPGA进行FLASH读写1——CCLK控制(STARTUPE2原语)

最近的工作涉及对 FPGA 进行远程更新&#xff0c;也就是通过远程通信接口将 .bin 文件送到 FPGA&#xff0c;然后写入 FLASH&#xff0c;这样当 FPGA 重新上电后就可以执行更新后的程序了。因此第一步工作就是进行 FLASH 的读写控制。 然而如果尝试配置 FLASH 管脚时&#xff0…

CRM客户管理系统究竟是什么?如何实施?

很多销售人员都不是特别喜欢使用信息化软件&#xff0c;然而从销售经理的角度看&#xff0c;信息化又的确提升了团队的管理效率和业绩。追究这些矛盾的原因&#xff0c;无外乎几点&#xff1a; 认知角度 → 销售员&#xff1a;数据没用又浪费我时间 VS 销售经理&#xff1a;数…

怎么在相册里去水印?三种方法教你去除

当你查看相册时&#xff0c;有时可能会注意到一些照片上有水印&#xff0c;这可能会让人感到不满,不管你是想保存这些照片还是与他人分享&#xff0c;水印往往会影响图片的观赏效果&#xff0c;不过别担心我将向你介绍一些简单的方法&#xff0c;帮助你在相册中轻松去除这些水印…

uniapp使用vue3和ts开发小程序自定义tab栏,实现自定义凸出tabbar效果

要实现自定义的tabbar效果&#xff0c;可以使用自定义tab覆盖主tab来实现&#xff0c;当程序启动或者从后台显示在前台时隐藏自带的tab来实现。自定义一个tab组件&#xff0c;然后在里面实现自定义的逻辑。 组件中所使用的组件api可以看&#xff1a;Tabbar 底部导航栏 | uView…

使用c++解压rar文件,基于UnRAR64,非命令行

最近项目需要解压缩rar文件&#xff0c;我们都知道rar是闭源收费软件&#xff0c;如果直接采用命令行可能会有限制&#xff0c;或者盗版问题&#xff0c;使用正版的winrar命令行解压rar文件是否有限制&#xff0c;这个我没来得及测试&#xff0c;但是从交互体验上来说&#xff…

「Verilog学习笔记」位拆分与运算

专栏前言 本专栏的内容主要是记录本人学习Verilog过程中的一些知识点&#xff0c;刷题网站用的是牛客网 1、寄存器的位是可以分开单独运算的&#xff0c;并不是一个输入就一定是一个数据&#xff0c;在很多情况下&#xff0c;一个输入既包括数据又包括地址等其他有效信息 2、需…

利用浩客无代码开发API集成客服系统,提升用户服务质量

【浩客简介】 浩客&#xff0c;是由十年 SaaS 表单产品「金数据」团队打造的新产品。它主要面向数字化系统的用户评价、反馈、调研、通知工具&#xff0c;特定时机、精准触达&#xff0c;帮助产品经理、用研、UX、运营&#xff0c;聆听用户心声&#xff0c;增强用户触达&#…

大数据商城人流数据分析与可视化 - python 大数据分析 计算机竞赛

0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 基于大数据的基站数据分析与可视化 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c;学长非常推荐&#xff01; &#x1f947;学长这里给一个题目综合评分(每项满分5分) 难度…