当前位置: 首页 > news >正文

[ 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 实现流程图

在这里插入图片描述

相关文章:

[ Linux Busybox ] flash_eraseall 命令解析

文章目录 相关结构体flash_eraseall 函数实现flash_eraseall 实现流程图 文件路径&#xff1a;busybox-1.20.2/miscutils/flash_eraseall.c 相关结构体 MTD 相关信息结构体 struct mtd_info_user {__u8 type; // MTD 设备类型__u32 flags; // MTD设…...

RabbitMQ 消息中间件 消息队列

RabbitMQ1、RabbitMQ简介2、RabbitMQ 特点3、什么是消息队列4、RabbiMQ模式5、集群中的基本概念 单实例安装RabbitMQ安装依赖安装erlang安装rabbitmq开启rabbitmq的web访问界面添加用户修改配置文件重启服务浏览器访问Rabbit-test rabbitMQ集群准备工作&#xff08;三台&#x…...

ChatGPT王炸升级GPT-4 Turbo:更强大还更便宜

11月7日&#xff0c;OpenAI首届开发者大会如期召开&#xff0c;在大会上OpenAI正式推出了GPT-4 Turbo。 据OpenAI介绍&#xff0c;相比于GPT-4&#xff0c;GPT-4 Turbo主要有6方面的提升&#xff1a; 第一&#xff0c;上下文对话长度&#xff0c;GPT4最大只能支持8k的上下文长…...

3.JMeter高级使用-让你与众不同

目录 概述插件下载与安装插件下载配置插件 服务器硬件资源监控(精简版)配置服务端代理JMeter配置监控CPU监控网络 JMeter下载结束 概述 今日目标&#xff1a; 插件下载与安装Basic Graphs 主要点 Average Response Time 平均响应时间Active Threads 活动线程数Successful/Fai…...

考研408-计算机网络 第一章-计算机网络体系结构学习笔记及习题

第一章 计算机网络体系结构 一 计算机网络概述 1.1 概念及功能 1.1.1 计算机网络的概念 计算机网络就是互连的、自治的计算机系统的集合 互连&#xff1a;通过通信链路互联互通 自治&#xff1a;各个节点之间无主从关系&#xff0c;高度自治的 1.1.2 计算机网络的功能 功…...

【快速使用ShardingJDBC的哈希分片策略进行分库分表】

文章目录 &#x1f50a;博主介绍&#x1f964;本文内容&#x1f34a;1.引入maven依赖&#x1f34a;2.启动类上添加注解MapperScan&#x1f34a;3.添加application.properties配置&#x1f34a;4.普通的自定义实体类&#x1f34a;5.写个测试类验证一下&#x1f34a;6.控制台打印…...

102. 二叉树的层序遍历

原题链接&#xff1a;102. 二叉树的层序遍历 以下代码为模板&#xff0c;需要层序遍历时都可以使用该模板进行代码更改 全代码&#xff1a; class Solution { public:vector<vector<int>> levelOrder(TreeNode* root) {//创建一个TreeNode* 队列用于存储树中的每…...

macOS磁盘分区调整软件--Paragon Camptune X 中文

Paragon Camptune X是一款专为Mac用户设计的强大分区大小调整工具。通过它&#xff0c;用户可以简便地调整Mac硬盘上的分区大小&#xff0c;实现存储空间的高效管理。无论是需要在Mac和Windows系统之间切换的双系统用户&#xff0c;还是有其他特定存储需求的用户&#xff0c;Ca…...

kaggle中报错NameError: name ‘q_1‘ is not defined

在开始练习之前&#xff0c;先点击“全部运行”按钮。...

SQL注入漏洞 其他注入

文章目录 宽字节注入案例 HTTP头部注入Cookie注入base64User-Agent注入Referer 注入 SQL注入读写文件条件1.是否拥有读写权限2.文件路径3.secure_file_priv 读取文件写入文件 SQLMap安装sqlmapkail 源安装仓库克隆 参数简介快速入门&#xff1b;SQLmap&#xff08;常规&#xf…...

Java自学第2课:Java语言基础知识要点

1 Java主类结构 任务&#xff1a;创建新项目名为item&#xff0c;包名为number&#xff0c;类名为first。 1.1 包声明 不指定包时&#xff0c;默认就是工程名&#xff0c;指定后&#xff0c;类文件可以分类了&#xff0c;是这意思吧。包就大概等于一个文件夹。而且在类文件中…...

flink状态和检查点

检查点和状态后端的区别 检查点 就是某个时间点下的所有算子的状态快照。这个时间点就是等所有任务将“同一个数据”处理完毕的时候。 状态后端&#xff1a;是一个管理状态的组件&#xff0c;还负责将本地状态&#xff08;检查点&#xff09;持久化到远程文件存储系统中。 分…...

数据仓库工具箱-零售业务

文章目录 一、维度模型设计的4步过程1.1 第一步&#xff1a;选择业务过程1.2 第二步&#xff1a;声明粒度1.3 第三步&#xff1a;确定维度1.4 第四步&#xff1a;确定事实 二、零售业务案例研究2.1 第一步&#xff1a;选择业务过程2.2 第二步&#xff1a;声明粒度2.3 第三步&am…...

网络工程实验记录

网络工程 show ip route show running-config 第一周 相同设备使用交叉线&#xff0c;不同设备之间使用直通线 R1能ping通10.1.1.1 R2能ping通所有的 R3能ping通172.16.1.1 即路由器只能到达自身线连接出去的&#xff0c;另一端就连接不了了。 此时给R1分配静态路由 R…...

Danswer 接入 Llama 2 模型 | 免费在 Google Colab 上托管 Llama 2 API

一、前言 前面在介绍本地部署免费开源的知识库方案时&#xff0c;已经简单介绍过 Danswer《Danswer 快速指南&#xff1a;不到15分钟打造您的企业级开源知识问答系统》&#xff0c;它支持即插即用不同的 LLM 模型&#xff0c;可以很方便的将本地知识文档通过不同的连接器接入到…...

react:路由

官方文档&#xff1a;https://reactrouter.com/en/main/start/overview#pending-navigation-ui 一&#xff1a;简单版本 先 npm i react-router-dom main.ts中内容替换为 import ReactDOM from react-dom/client import App from ./App.tsx import ./index.css import {creat…...

【AI工具】手把手带你使用Gradio分享你的模型

手把手带你使用Gradio分享你的模型 1. 快速入门2. 基本参数|支持的接口2.1 Interface类以及基础模块2.2 组件属性2.3 多输入输出组件2,4 图像组件2.5 Chatbots2.6 动态界面接口2.7 Blocks:更具灵活性和调控性2.7.1 Blocks入门2.7.2 更复杂的Blocks3. 分享自定义采样训练参考资…...

海洋专用cmocean颜色包_共22种--全平台可用

海洋专用cmocean颜色包_共22种–全平台可用 往期推荐&#xff1a; Python语言_matplotlib包_共80种–全平台可用 Python语言_single_color_共140种–全平台可用 R语言_RColorBrewer包–全平台可用 R语言gplots包的颜色索引表–全平台可用 R语言中的自带的调色板–五种–全平台…...

uni-app多端开发

uni-app 多端开发 一、命令创建uni-app 项目二、在微信小程序后台找到 appId 填写 appId三、运行项目四、使用 uni-ui4-1、下载4-2、自动导入4-3、ts项目下载类型校验 &#xff08;uni-ui 组件库&#xff09;4-3-1、下载4-3-2、配置 五、持久化 pinia六、数据请求封装七、获取组…...

Linux中固定ip端口和修改ip地址

一&#xff0c;更改虚拟网络编辑器 1&#xff0c;首先启动VMware&#xff0c;选择自己要更改ip或固定ip的虚拟机&#xff0c;并找到虚拟网络配编辑器&#xff0c;点击进入 2&#xff0c;进入之后需要点击右下角获取管理员权限后才能修改&#xff0c;有管理员权限之后图片如下 …...

csdn初始模板【自用】

这里写自定义目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个…...

2311rust无畏并发.

原文 Rust无畏并发 Rust是为了解决两个麻烦问题: 1,如何安全系统编程 2,如何无畏并发 最初,这些问题似乎是无关的,但令惊讶的是,方法竟然是相同的:使Rust安全的相同工具也可帮助解决并发问题. 内存安全和并发错误,一般认为是代码在不应访问数据时访问数据.Rust依靠所有权为…...

阿里云中的云服务器的ubuntu中的vim没有显示行号

没有行号&#xff1a; 在终端输入命令&#xff1a; vim ~/.vimrc set nu...

Golang 在 Mac、Linux、Windows 下如何交叉编译

Golang 支持交叉编译&#xff0c;在一个平台上生成另一个平台的可执行程序。 GOOS&#xff1a;目标平台的操作系统&#xff08;darwin、freebsd、linux、windows&#xff09; GOARCH&#xff1a;目标平台的体系架构&#xff08;386、amd64、arm&#xff09; 具体组合&#xf…...

如何写好一篇学术论文

目录 前言 1.标题和摘要 1.1标题 1.2摘要及关键词 1.2.1摘要 1.2.2关键词 2.正文 2.1引言 2.2问题建模 2.3研究方法及分析 2.4仿真&#xff08;伪代码&#xff09; 2.5实验结果及分析 2.6 总结 2.7延深 2.7.1图片处理 2.7.2审稿回复 2.7.3如何避免拒稿 2.7.4写…...

kubernetes资源监控

目录 一、资源限制 1、limitrange 2、ResourceQuota 二、metrics-server 三、图形化监控和代码行监控 1、dashboard 2、k9s 四、hpa 一、资源限制 Kubernetes采用request和limit两种限制类型来对资源进行分配。request(资源需求)&#xff1a;即运行Pod的节点必须满足运…...

Bitget Wallet:使用 Base 链购买 ETH 的简明教程

Base 链是一种 Layer 2&#xff08;L2&#xff09;公链&#xff0c;它可以为用户提供以太坊&#xff08;ETH&#xff09;代币&#xff0c;而 Bitget Wallet 是一款多功能加密货币钱包&#xff0c;支持 Base 链以及其他主要区块链。...

PostgreSQL简介及安装步骤

PostgreSQL简介 PostgreSQL是一款开源的关系型数据库管理系统&#xff0c;具有强大的扩展性、高度的可定制性和可靠的稳定性&#xff0c;因此在企业级应用和开发领域中得到了广泛的应用。本文将介绍PostgreSQL的基本概念以及在各种操作系统上的安装步骤。 安装步骤 1. Window…...

《安富莱嵌入式周报》第326期:航空航天级CANopen协议栈,开源USB PD电源和功耗分析,开源EtherCAT伺服驱动板,时序绘制软件,现代机器人设计

周报汇总地址&#xff1a;嵌入式周报 - uCOS & uCGUI & emWin & embOS & TouchGFX & ThreadX - 硬汉嵌入式论坛 - Powered by Discuz! 更新一期视频教程&#xff1a; BSP视频教程第28期&#xff1a;CANopen协议栈专题&#xff0c;CANopen主从机组网实战&a…...

[Kettle] Excel输入

Excel文件采用表格的形式&#xff0c;数据显示直观&#xff0c;操作方便 Excel文件采用工作表存储数据&#xff0c;一个文件有多张不同名称的工作表&#xff0c;分别存放相同字段或不同字段的数据 数据源 物理成绩(Kettle数据集2).xls https://download.csdn.net/download/H…...