一、VFS解析
VFS全称是Virual file system,Linux中的不同文件系统包含FAT、ROMFS、RAMFS等,不同的文件操作系统均包含Open、Close、Read、Write等接口,但不同文件系统的对文件的处理方式是不同的,因此需要单独抽象出一层级作为上层差异性的屏蔽,VFS提供统一的文件操作接口(如struct file_operations
),根据不同的文件系统,调用不同的底层接口。VFS实现了对上层应用在不同文件系统下的文件操作接口差异屏蔽,即对上层应用隐藏不同文件系统的实现细节,对驱动开发者来说影响不大,不同的文件系统对应不同的驱动,驱动开发者只需把该封的驱动封完毕即可。
图示VFS在系统中的层级关系:
+---------------------+
| 应用程序层 | 用户空间
| (如ls, cat, 自定义应用)|
+---------------------+
│
▼
+---------------------+
| 系统调用接口 | 如open、read、write等
+---------------------+
│
▼
+---------------------+
| VFS层 | 内核空间
| - 统一文件操作接口 |
| - 管理inode/dentry缓存|
| - 页缓存(Page Cache)|
+---------------------+
├───────────────────┬───────────────────┐
│ │ │
▼ ▼ ▼
+---------------------+ +---------------------+ +---------------------+
| Ext4文件系统 | | YAFFS/FAT文件系统 | | procfs/sysfs/tmpfs |
+---------------------+ +---------------------+ +---------------------+
│ │ │
▼ ▼ │
+---------------------+ +---------------------+
| 块设备驱动层 | | 字符设备驱动等 |
| (SCSI, SATA, NVMe) | | (如终端、打印机驱动) |
+---------------------+ +---------------------+
│ │
▼ ▼
+---------------------+ +---------------------+
| 硬件存储设备 | | 其他物理设备 |
| (硬盘、SSD、U盘) | | (如USB设备、GPU) |
+---------------------+ +---------------------+
Ex4、FAT等文件系统对应块设备驱动;
procfs/sysfs这类伪文件系统,直接映射内存数据;
二、扇区、页、块的区别
nandflash没有扇区的概念,以块和页作为存储单元,页是最小的读取和写入单元,块是最小的擦除单元。页包括主存储区和备用区,备用区用于存储本页的纠错码等信息,通常占主数据区的3%~5%。嵌入式中的页大小一般是2KB~4KB。
norflash中没有页的概念,以字节进行读取和写入,以扇区作为最小擦除单元,写入前需进行擦除操作(负荷检测单元,存储90天数据,一天天擦除,按扇区进行)。
扇区的由来,是由于早期的数据是以磁盘指针以扇形的形式从存储单元中读取的,故扇区这个名称沿用下来的了。
三、MTD和Yaffs的使用
MTD是Linux内核的基础措施,为上层提供擦除、读、写、坏块管理等操作,其仅提供接口,不涉及文件的组织结构,即仅提供操作文件的能力。
Yaffs是一种专门用于nandflash的文件系统,由于nandflash具有先擦后写等特性,传统的ext4无法有效处理这些特性。
YAFFS通过以下设计适配:
- 页级管理:以NAND页(Page)为单位组织数据。
- OOB(Out-of-Band)空间利用:存储ECC校验码和元数据。
结构图如下:
+-------------------+
| YAFFS文件系统 | → 文件组织结构、元数据管理
+-------------------+
| MTD层 | → 原始闪存操作(读/写/擦除)
+-------------------+
| NAND/NOR闪存硬件 |
+-------------------+
依赖关系:YAFFS通过MTD API访问闪存硬件,二者是互补的上下层关系。
若直接使用MTD而不搭配YAFFS(或其他闪存文件系统),系统将无法有效管理文件,也无法保证闪存寿命和数据完整性。
如何我明确定义了nandflash中每一块的作用,yaffs就没法实现磨损均衡了吧?
YAFFS2 的磨损均衡核心是动态选择空闲块进行写入和回收,确保所有块的擦除次数接近。若固定每个块的做用户,磨损机制将失效。
四、MTD系统解析
为什么需要MTD?
MTD实现了坏块管理、错误纠正(ECC)、磨损次数统计。
MTD屏蔽了底层差异,若后续更换Flash芯片,直接底层驱动函数即可,上层无需变化。
VFS→文件系统层(JFFS2/UBIFS)→MTD抽象层→硬件驱动层
MTD如何标记坏块?
驱动加载时,MTD会自动扫描所有块,并加载一个坏块表(BBT)。
nand_scan() → nand_scan_bbt() → nand_memory_bbt() → scan_block_fast() → nand_block_checkbad()
读写操作时,MTD会自动监测当前块的状态,防止写入至坏块中。
mtd_erase() → mtd_erase_nand() → nand_erase_nand() → nand_block_checkbad()
MTD的擦除次数统计给谁用的?
给yaffs文件系统使用,可交由其实现磨损均衡等。
五、OOB
OOB(Out of Band)区域主要用于记录页的相关信息,包括坏块标记和ECC校验码等。 OOB区域是NAND Flash存储结构中的一个重要部分,通常位于每个页的末尾,用于存放该页的校验值和其他相关信息。
第一个page的oob区的第6个字节为坏块标记。
六、Flash之间的关系
Nandflash与Norflash的原理均为浮栅晶体管,注意:电流是正电子的移动方向,但电子是负电子的移动方向,通过在基底和控制栅加入压差实现电子的移动。参照如下知乎理解。https://zhuanlan.zhihu.com/p/662232323
NorFlash容量小、价格高、速度快,一般用于主程序存储,也要先擦后写。
Nandflash容量大、价格低,写入前需先擦除,故用于大容量存储,如SSD。
机械硬盘:依靠磁盘与盘片存储,非nandflash类型。