深入了解 Linux 中的 MTD 设备:/dev/mtd* 与 /dev/mtdblock*

目录

  • 前言
  • 一、什么是MTD子系统?
  • 二、 `/dev/mtd*` 设备文件
      • 用途
      • 注意事项
  • 三、`/dev/mtdblock*` 设备文件
      • 用途
      • 注意事项
  • 三、这两种设备文件的关系
  • 四、关norflash的一些小知识

前言

  在嵌入式Linux系统的世界里,非易失性存储技术扮演着至关重要的角色。MTD(Memory Technology Device)子系统是Linux内核的一个组成部分,它为各种类型的闪存和EEPROM设备提供了一个统一的接口。本文将深入探讨Linux系统中的两种MTD设备文件:/dev/mtd*/dev/mtdblock*,它们的用途、区别以及如何在实际场景中应用这些知识。
在这里插入图片描述

一、什么是MTD子系统?

  MTD(Memory Technology Device)子系统是 Linux 内核中的一个子系统,用于管理非易失性存储器设备,如闪存芯片(NAND、NOR 等)。MTD 子系统提供了一组通用的接口和驱动程序,使得 Linux 能够方便地访问和操作这些存储设备。

  MTD 子系统的主要功能包括:

  1. 设备抽象和管理:MTD 子系统提供了一个设备抽象层,允许系统对不同类型的非易失性存储设备进行统一的管理。它提供了一种通用的方式来表示和操作这些设备,无论它们是基于 NAND、NOR 还是其他技术。

  2. 设备擦除和编程:MTD 子系统允许 Linux 内核对支持擦除和编程操作的存储设备执行这些操作。这对于闪存等设备是至关重要的,因为它们通常需要在写入新数据之前先擦除存储单元。

  3. 分区支持:MTD 子系统允许将存储设备划分为多个逻辑分区,每个分区可以独立管理。这使得在同一个物理设备上实现多个逻辑存储空间成为可能,可以用于实现文件系统、内核映像等。

  4. 驱动程序支持:MTD 子系统提供了一组通用的驱动程序接口,使得开发者可以编写适配不同类型存储设备的驱动程序,并将其与 MTD 子系统集成起来。

总的来说,MTD 子系统为 Linux 内核提供了与非易失性存储设备交互的标准接口,使得开发者可以更方便地实现对这些设备的管理、操作和访问。

二、 /dev/mtd* 设备文件

  /dev/mtd*设备文件是MTD子系统的核心组成部分。这些文件代表了系统中的MTD设备,通常用于访问小块的、页对齐的内存区域。每个/dev/mtd*设备文件都有一个数字后缀,例如/dev/mtd0/dev/mtd1等,这些数字代表了设备在系统中的索引。

用途

  • 系统更新/dev/mtd*设备常用于更新系统的引导加载程序(bootloader)和内核。在嵌入式系统中,这些组件通常存储在闪存设备上,需要通过MTD子系统进行更新。
  • 数据存储:某些系统可能会使用MTD设备来存储关键的数据,如U-Boot环境变量或其他系统配置信息。
  • 设备测试:开发者可以使用/dev/mtd*设备文件来测试闪存设备的读写性能和可靠性。

注意事项

  • 访问/dev/mtd*设备文件通常需要root权限。
  • 由于MTD设备通常用于存储关键的系统数据,因此在对其进行操作时需要格外小心,以避免数据丢失或系统损坏。

三、/dev/mtdblock* 设备文件

/dev/mtd*不同,/dev/mtdblock*设备文件提供了对MTD设备的块设备接口。这意味着它们可以被挂载为文件系统,并以块为单位进行读写操作。/dev/mtdblock*设备文件的命名方式与/dev/mtd*类似,也使用数字后缀来区分不同的设备。

用途

  • 文件系统挂载/dev/mtdblock*设备文件可以挂载为文件系统,用于存储操作系统、应用程序或用户数据。这对于没有传统硬盘驱动器的嵌入式设备尤其有用。
  • 数据分区:通过使用/dev/mtdblock*设备,开发者可以在闪存设备上创建多个分区,每个分区可以独立地挂载和管理。
  • 系统恢复:在系统崩溃或损坏的情况下,/dev/mtdblock*设备可以用于恢复系统镜像或重要的配置文件。

注意事项

  • 在对/dev/mtdblock*设备进行写操作之前,应确保没有任何文件系统挂载在其上。
  • /dev/mtd*一样,访问/dev/mtdblock*设备文件也需要root权限。

三、这两种设备文件的关系

  这些不同的设备文件通常对应同一块存储区域。比如在使用 NOR Flash 存储器时,不同的设备文件只是提供了不同的访问方式和操作权限,但是它们对应的确实是同一个物理空间或逻辑分区。

  举例来说,当你在一个嵌入式系统中使用 NOR Flash 存储器时,可能会看到 /dev/mtd0/dev/mtdblock0/dev/mtd0ro 这几个设备文件,它们对应的都是 NOR Flash 存储器中的同一个物理空间或逻辑分区。其中 /dev/mtd0/dev/mtdblock0 提供了不同的读写方式,/dev/mtd0ro 则是只读的。这些设备文件允许用户以不同的方式与 NOR Flash 存储器进行交互和访问,例如可以进行烧写、读取和执行代码等操作。

  因此,无论是块设备文件还是字符设备文件,以及只读设备文件,它们都可以对应同一块存储区域或相同的物理空间。区别在于它们提供了不同的权限和访问方式,以满足不同的使用需求。

四、关norflash的一些小知识

  在 NOR Flash 存储器中,一个 block 的大小通常是 64KB(64 * 1024 字节)。这个 block 大小是 NOR Flash 存储器常见的值,但实际上在不同型号的 NOR Flash 存储器中,block 的大小可能会有所不同。因此,在具体使用时,需要查阅相关的数据手册或规格说明来确认所使用的 NOR Flash 存储器 block 的确切大小。

  对于 NOR Flash 存储器来说,通常是在对其进行写操作之前需要先擦除。这是因为 NOR Flash 存储器中的存储单元(如字节或扇区)在执行写操作时,是将数据从逻辑值 1 写入逻辑值 0,因此需要先将要写入的存储单元擦除为逻辑值 1,然后再写入新的数据。

  具体来说,擦除操作会将存储单元的数据全部置为逻辑值 1,而写操作则是将特定的存储单元从逻辑值 1 写入为逻辑值 0。如果在进行写操作时不进行擦除,那么由于 NOR Flash 存储器一般不支持原地写入(in-place write),可能会导致写入的数据无法正确覆盖之前的数据,从而产生错误数据或不稳定的状态。

  因此,为了确保 NOR Flash 存储器中数据的正确性和稳定性,通常在进行写操作之前需要先执行擦除操作。在擦除操作和写操作过程中,还需要注意避免中断电等意外情况,以确保数据的完整性和一致性。

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/mtd/mtd.h>
#include <linux/mtddll.h>#define MTD_DEVICE_0 "/dev/mtd0"
#define MTD_DEVICE_1 "/dev/mtd1"int main() {int mtd0_fd, mtd1_fd;struct mtd_info_user mtd_info;struct erase_info_user erase_info;ssize_t bytes_read, bytes_written;char buffer[4096]; // 读取/写入的缓冲区大小// 打开第一个MTD设备进行读取if ((mtd0_fd = open(MTD_DEVICE_0, O_RDONLY)) < 0) {perror("Error opening MTD device 0");return EXIT_FAILURE;}// 获取MTD设备信息if (ioctl(mtd0_fd, MEMGETINFO, &mtd_info) < 0) {perror("Error getting MTD device information");close(mtd0_fd);return EXIT_FAILURE;}// 打开第二个MTD设备进行写入if ((mtd1_fd = open(MTD_DEVICE_1, O_WRONLY)) < 0) {perror("Error opening MTD device 1");close(mtd0_fd);return EXIT_FAILURE;}// 擦除第二个MTD设备的相关块for (int i = 0; i < mtd_info.eraseblocks; i++) {erase_info.start = i * mtd_info.erasesize;erase_info.length = mtd_info.erasesize;if (ioctl(mtd1_fd, MEMERASE, &erase_info) < 0) {perror("Error erasing MTD device 1");close(mtd0_fd);close(mtd1_fd);return EXIT_FAILURE;}}// 从第一个MTD设备读取数据while ((bytes_read = read(mtd0_fd, buffer, sizeof(buffer))) > 0) {// 将数据写入第二个MTD设备bytes_written = write(mtd1_fd, buffer, bytes_read);if (bytes_written != bytes_read) {perror("Error writing to MTD device 1");close(mtd0_fd);close(mtd1_fd);return EXIT_FAILURE;}}// 关闭MTD设备文件描述符close(mtd0_fd);close(mtd1_fd);printf("Data transfer from MTD device 0 to MTD device 1 completed successfully.\n");return EXIT_SUCCESS;
}

  在这个示例中,我们使用MEMERASEioctl调用来擦除/dev/mtd1设备上的每个擦除块。erase_info_user结构体被用来指定要擦除的块的起始地址和长度。这个操作通常比读取和写入操作慢,因此在实际应用中,您可能希望优化这个过程,例如通过并行擦除或使用更高效的写入策略。

  请记住,擦除操作是破坏性的,因此在执行之前应该确保数据已经备份。此外,确保您有足够的权限来执行这些操作,通常需要root权限。在实际部署之前,应该在受控环境中彻底测试代码,以避免数据丢失。

/*
BLKGETSIZE64 用于获取块设备的大小(以字节为单位),返回的值是一个 unsigned long long 类型
的整数,表示设备的总容量。这个命令通常用于获取大于 2 TB 的设备大小,因为 BLKGETSIZE 在 32 
位系统上可能会出现溢出问题。BLKGETSIZE 用于获取块设备的大小(以扇区为单位),返回的值是一个 long 类型的整数,表示设备
的总扇区数。通常情况下,这个命令可以满足大多数小于 2 TB 的设备大小获取需求。
*/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>#define MTD_BLOCK_DEVICE "/dev/mtdblock0"int main() {int fd;unsigned long long erase_size, total_size;unsigned int erase_flags = 0; // 通常为0,表示默认擦除选项// 打开MTD块设备进行读写if ((fd = open(MTD_BLOCK_DEVICE, O_RDWR)) < 0) {perror("Error opening MTD block device");return EXIT_FAILURE;}// 获取MTD块设备的擦除大小和总大小if (ioctl(fd, BLKGETSIZE64, &total_size) != 0) {perror("Error getting device size");close(fd);return EXIT_FAILURE;}erase_size = total_size; // 假设整个设备需要擦除// 擦除MTD块设备if (ioctl(fd, BLKERASE, &erase_size) != 0) {perror("Error erasing MTD block device");close(fd);return EXIT_FAILURE;}// 准备要写入的数据const char *data_to_write = "This is a test.\n";size_t data_len = strlen(data_to_write) + 1; // 加1是为了包括字符串的终止符'\0'// 从设备开头开始写入数据if (write(fd, data_to_write, data_len) != data_len) {perror("Error writing to MTD block device");close(fd);return EXIT_FAILURE;}// 关闭MTD块设备close(fd);printf("Data successfully written to MTD block device.\n");return EXIT_SUCCESS;
}

  在这个示例中,我们首先打开/dev/mtdblock0设备进行读写操作。然后,我们使用BLKGETSIZE64ioctl调用来获取设备的总大小。接着,我们使用BLKERASEioctl调用来擦除整个设备。最后,我们使用write函数将一个简单的字符串写入设备。

  请注意,这个示例代码假设整个设备都需要擦除,这可能不是所有情况的最佳实践。在实际应用中,您可能需要根据设备的擦除块大小和您的写入需求来计算需要擦除的确切区域。

  在编译和运行此代码之前,请确保您有足够的权限(通常需要root权限),并且/dev/mtdblock*设备文件确实存在于您的系统中。您可以使用以下命令来编译代码:

gcc -o mtdblock_write mtdblock_write.c

  然后,使用以下命令以root用户身份运行编译后的程序:

sudo ./mtdblock_write

  请记住,在对MTD设备进行操作时,您应该非常小心,因为不正确的操作可能会导致数据丢失。在实际部署之前,务必在受控环境中进行彻底的测试。

  欢迎大家指导和交流!如果我有任何错误或遗漏,请立即指正,我愿意学习改进。期待与大家一起进步!

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

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

相关文章

Spring Aop 源码解析(下)

ProxyFactory选择cglib或jdk动态代理原理 ProxyFactory在生成代理对象之前需要决定到底是使用JDK动态代理还是CGLIB技术: config就是ProxyFactory对象,把自己传进来了,因为ProxyFactory继承了很多类,其中一个父类就是ProxyConfig // config就是ProxyFactory对象// 是不是…

开发npm上传发布

第一步&#xff1a;注册npm账号 首先去官网注册一个npm账号&#xff0c;npm官网 第二步&#xff1a;创建项目 新建文件夹&#xff0c;并执行npm init 填写对应的信息name就是插件名称。 文件夹下就会生成一个package.json文件。 你可以在项目编辑你的插件。 第三步&…

第十二届蓝桥杯物联网试题(省赛)

思路&#xff1a; 这个考了一个RTC的配置&#xff0c;RTC我只配过一次&#xff0c;所以有些生疏&#xff0c;还是不能大意&#xff0c;一些偏僻的考点还是要多练&#xff0c;在获取RTC时间的时候也遇到一些bug,这个后续会用一篇博客将最近遇到的BUG都总结一下 主要的难点还是…

wordpress将图片默认连接到媒体文件

wordpress上传图片后&#xff0c;图片链接可以选择链接到媒体文件或附件页面。如果选择链接到媒体文件&#xff0c;就是链接到了图片的地址了。如果选择链接到附件页面&#xff0c;就是链接到图片所在的attachment页面了。 具体链接到哪里&#xff0c;在wordpress模板制作时&a…

基于GA优化的CNN-LSTM-Attention的时间序列回归预测matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1卷积神经网络&#xff08;CNN&#xff09;在时间序列中的应用 4.2 长短时记忆网络&#xff08;LSTM&#xff09;处理序列依赖关系 4.3 注意力机制&#xff08;Attention&#xff09; 5…

Android15功能和 API 概览

Android 15 面向开发者引入了一些出色的新功能和 API。以下部分总结了这些功能&#xff0c;以帮助您开始使用相关 API。 如需查看新增、修改和移除的 API 的详细列表&#xff0c;请参阅 API 差异报告。如需详细了解新的 API&#xff0c;请访问 Android API 参考文档&#xff0…

FastAPI+React全栈开发03 为什么使用MongoDB

Chapter01 Web Development and the FARM Stack 03 Why use MongoDB FastAPIReact全栈开发03 为什么使用MongoDB In the following paragraphs, we will go through the main features of our selected database system - MongoDB - and give a high-level overview of the …

VSCode基本配置(编辑器)

VSCode基本配置 设置快捷键&#xff1a;Ctrl , 下载中文插件&#xff1a;Chinese&#xff0c;重启一下&#xff0c;如果没有&#xff0c;Ctrl Shift P&#xff0c;搜索&#xff1a;Display Language 主题推荐&#xff1a;Solarized Dark&#xff0c;快捷键&#xff1a;Ct…

速盾:cdn加速效果好吗

CDN&#xff08;Content Delivery Network&#xff09;是一种通过分布在全球多个节点的服务器来加速网络内容传输的技术。CDN加速效果好不好&#xff0c;需要从几个方面来考量。 首先&#xff0c;CDN可以显著提高网站的加载速度。由于CDN服务器分布在全球各地&#xff0c;用户…

C++零基础入门学习视频课程

教程介绍 本专题主要讲解C基础入门学习&#xff0c;所以不会涉及很深入的语法和机制。但会让你整体多面的了解和学习C的核心内容&#xff0c;快速学习使用C&#xff0c;我们的目标是先宏观整体把握&#xff0c;在深入各个击破&#xff01; 学习地址 链接&#xff1a;https:/…

多线程合并练习题,线程安全(售票任务引入)--学习JavaEE的day30

day30 练习&#xff08;day29&#xff09; 注意代码注释&#xff0c;里面涉及代码实现遇到问题及解决方案&#xff0c;由于理解方便没有单独出来 1.计算任务 1.计算任务&#xff0c;一个包含了2万个整数的数组&#xff0c;分拆了多个线程来进行并行计算&#xff0c;最后汇总出…

计算机视觉的研究方向

随着科技的快速发展&#xff0c;计算机视觉已成为人工智能领域的一颗璀璨明星。从识别照片中的人物&#xff0c;到自动驾驶汽车的视觉系统&#xff0c;再到医学诊断的辅助工具&#xff0c;计算机视觉正以前所未有的方式改变着我们的生活。在这篇文章中&#xff0c;我们将探讨计…

uniapp先显示提示消息再返回上一页

一、描述 在有些业务场景中&#xff0c;需要先弹出提示后&#xff0c;再返回上一页。 二、思路 使用定时器&#xff0c;先弹出提示消息&#xff0c;然后开个定时器俩秒后再执行&#xff0c;返回上一页的操作&#xff0c;并且清除定时器。 三、实现 uni.showToast({title: …

MySQL三种开窗函数详细用法,图文详解

开窗函数的详细用法 第一章、开窗函数的语法1.1&#xff09;从聚合开窗函数讲起1.2&#xff09;开窗函数之取值1.3&#xff09;排名开窗函数 第一章、开窗函数的语法 开窗函数的语法为&#xff1a;over(partition by 列名1 order by 列名2 )&#xff0c;括号中的两个关键词par…

加速新能源汽车产品迭代:融合前沿科技的重要性

新能源汽车新质生产力提升咨询方案 一、新能源汽车企业行业目前发展现状及特点&#xff1a; 1、快速增长 2、技术迭代快 3、竞争加剧 二、新能源汽车企业发展新质生产力面临的痛点&#xff1a; 1、技术创新压力巨大 2、市场竞争激烈 3、供应链稳定性欠缺 4、成本控制压…

复试专业前沿问题问答合集2

复试专业前沿问题问答合集2 计算机视觉基础知识问答 Q1: 计算机视觉是什么? A1: 计算机视觉是人工智能的一个分支,它使计算机和系统能够从图像和视频中提取信息、分析和理解视觉内容。它结合了图像处理、模式识别和机器学习等技术,以模拟人眼的视觉感知能力。 Q2: 计算机…

微信小程序实战:无痛集成腾讯地图服务

在移动互联网时代,地图服务无疑是应用程序中最常见也最实用的功能之一。无论是导航定位、附近搜索还是路线规划,地图服务都能为用户提供极大的便利。在微信小程序开发中,我们可以轻松集成腾讯地图服务,为小程序赋能增值体验。本文将详细介绍如何在微信小程序中集成使用腾讯地图…

GPT结合R语言回归模型、多元统计分析、混合效应模型、结构方程实战案例

查看原文>>>科研新边界&#xff1a;GPT & R语言联手&#xff0c;让数据分析不再难&#xff01; 自2022年GPT&#xff08;Generative Pre-trained Transformer&#xff09;大语言模型的发布以来&#xff0c;它以其卓越的自然语言处理能力和广泛的应用潜力&#xf…

jmeter中参数加密

加密接口常用的方式有&#xff1a; MD5&#xff0c;SHA&#xff0c;HmacSHA RSA AES&#xff0c;DES&#xff0c;Base64 压测中有些参数需要进行加密&#xff0c;加密方式已接口文档为主。 MD5加密 比如MD5加密的接口文档&#xff1a; 请求URL&#xff1a;http://101.34.221…

【笔试】2023年秋招部分笔试(JD,58、MI,B站,雷火)

文章目录 1、京东笔试2、58笔试&#xff08;dp&#xff09;3、B站笔试&#xff08;sql/leetcode&#xff09;4、小米15、小米26、网易雷火 这边的笔试都是带选择题的&#xff0c;编程题部分占比只有一半上下。 我这里主要只记录下算法题部分的&#xff0c;毕竟单选多选反正408我…