深入了解 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对象// 是不是…

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

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

基于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…

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;最后汇总出…

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、成本控制压…

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

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

jmeter中参数加密

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

面试算法-105-相交链表

题目 给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点&#xff0c;返回 null 。 图示两个链表在节点 c1 开始相交&#xff1a; 题目数据 保证 整个链式结构中不存在环。 注意&#xff0c;函数返回…

各大pdf转word软件都用的哪家的ocr引擎?

国内一般的PDF软件一般都调用某国际PDF原厂的OCR接口&#xff0c;但这家公司是主要做PDF&#xff0c;在OCR方面并不专注&#xff0c;一些不是很复杂的场景还能应付得过来&#xff0c;复杂一点的效果就强差人意了&#xff0c;推荐用金鸣表格文字识别系统&#xff0c;它主要有以下…

抖音视频关键词无水印下载软件|手机网页视频批量提取工具

全新视频关键词无水印下载软件&#xff0c;助您快速获取所需视频&#xff01; 随着时代的发展&#xff0c;视频内容已成为人们获取信息和娱乐的重要途径。为了方便用户获取所需视频&#xff0c;推出了一款功能强大的视频关键词无水印下载软件。该软件主要功能包括关键词批量提取…

yolov8直接调用zed相机实现三维测距(python)

yolov8直接调用zed相机实现三维测距&#xff08;python&#xff09; 1. 相关配置2. 相关代码3. 实验结果 相关链接 此项目直接调用zed相机实现三维测距&#xff0c;无需标定&#xff0c;相关内容如下&#xff1a; 1.yolov5直接调用zed相机实现三维测距&#xff08;python&#…

ISAC代码仿真学习笔记

文章目录 A. MIMO Communication ModelB. MIMO Radar Model III. Joint Waveform and Phase Shift Matrix Design for Given Radar BeampatternA. Problem FormulationB. Proposed Algorithm V. S IMULATION RESULTS A. MIMO Communication Model 用户处的接收信号矩阵由 Y …

Spring Boot 实现定时任务动态管理

前言 本文主要介绍了SpringBoot架构下动态定时任务的使用&#xff0c;定时任务表达式配置在数据库中&#xff0c;通过反射执行到目标方法。 Quartz Quartz 是一个开源的作业调度框架,支持分布式定时任务&#xff0c;Quartz定时任务据我了解可分为Trigger&#xff08;触发器&…

小迪安全47WEB 攻防-通用漏洞Java 反序列化EXP 生成数据提取组件安全

#知识点&#xff1a; 1、Java 反序列化演示-原生 API 接口 2、Java 反序列化漏洞利用-Ysoserial 使用 3、Java 反序列化漏洞发现利用点-函数&数据 4、Java 反序列化考点-真实&CTF 赛题-审计分析 #内容点&#xff1a; 1、明白-Java 反序列化原理 2、判断-J…

javaWeb在线考试系统

一、简介 在线考试系统是现代教育中一项重要的辅助教学工具&#xff0c;它为学生提供了便捷的考试方式&#xff0c;同时也为教师提供了高效的考试管理方式。我设计了一个基于JavaWeb的在线考试系统&#xff0c;该系统包括三个角色&#xff1a;管理员、老师和学生。管理员拥有菜…

Knative 助力 XTransfer 加速应用云原生 Serverless 化

作者&#xff1a;元毅 公司介绍 XTransfer 是一站式外贸企业跨境金融和风控服务公司&#xff0c;致力于帮助中小微企业大幅降低全球展业的门槛和成本&#xff0c;提升全球竞争力。公司连续7年专注 B2B 外贸金融服务&#xff0c;已成为中国 B2B 外贸金融第一平台&#xff0c;目…

荟萃分析R Meta-Analyses 2----发现R

2.1安装R和R Studio 在开始之前&#xff0c;我们必须下载并准备一个计算机程序&#xff0c;该程序使我们能够方便地使用R进行统计分析。目前最好的选择可能是R Studio。该程序为我们提供了一个用户界面&#xff0c;使我们可以更轻松地处理数据、包和输出。最好的部分是 R Studi…