rtthread - ROMFS 的使用方式
ROMFS 使用方式
在RT-Thread中的实现:
在RT-Thread中,ROMFS的物理存储通常有两种形式:
1、独立Flash分区
将ROMFS镜像直接烧录到Flash的特定分区,适用于外部 Nor/Nand flash
const struct romfs_dirent romfs_root =
{ ROMFS_DIRENT_DIR, "/", NULL, 0, (rt_uint8_t *)rt_romfs_root
}; dfs_mount("rom", "/", "rom", 0, &romfs_root);+---------------------+
| Bootloader | 0x0000
+---------------------+
| Kernel | 0x8000
+---------------------+
| ROMFS Image | 0x20000 ← 物理起始地址
| (文件系统二进制块) |
+---------------------+
| App Code | 0xA0000
+---------------------+
通过绝对地址直接访问(XIP:eXecute In Place)
在RT-Thread中通过
fal_partition_find("romfs")
获取分区信息其中`rt_romfs_root` 指向 ROMFS镜像 在Flash中的起始地址。
2、链接到代码段(直接嵌入固件)
存储方式:文件内容编译时转换为C语言数组,适用于内部芯片的 片上flash
const unsigned char romfs_img[] __attribute__((section(".romfs"))) =
{ // 由工具生成的二进制数据
};物理位置:指定链接到.rodata-> romfs 段,位于芯片内部Flasheg:
// 自动生成的romfs_img.c
const unsigned char romfs_img[] = {0x52, 0x4F, 0x4D, 0x31, // 'ROM1' 魔数0x08, 0x00, 0x00, 0x00, // 文件头偏移// ... 文件系统二进制数据 ...
};物理位置:常规链接到.rodata 段,位于芯片内部Flash
深度理解 ROMFS
static const struct dfs_mount_tbl mnt_table[] = {{ "mtdblk0", "/", "elm", 0, NULL }, // FATFS 挂载{ NULL, "/mnt/romfs", "rom", 0, &romfs_root }, // ROMFS 挂载{ NULL }
};
ROMFS 设备参数 NULL
的含义
NULL 表示的是 ROMFS 的 设计特性 而非缺陷,明确表示 ROMFS 不依赖任何块设备驱动(如 SPI Flash、SD 卡等)。这与传统文件系统(如 FATFS)有本质区别。这种设计使 ROMFS 成为零开销的只读文件系统,特别适合存储嵌入式系统中的静态资源。
关键设计:
ROMFS 是 直接内存映射型 文件系统,其数据源是编译时就已经确定存储在静态内存区域 .rodata 段。(由&romfs_root
指向存储在静态内存区域中的地址),而非运行时动态挂载的块设备
&romfs_root
的核心作用
物理存储本质:
romfs_root
是一个struct romfs_dirent
结构体指针,它直接指向 存储在 Flash 中的 ROMFS 镜像二进制数据。
// ROMFS 镜像数据(编译时生成)
const unsigned char romfs_img[] = {0x52,0x4F,0x4D,0x31, // 'ROMfs' magic// ... 文件系统二进制数据 ...
};// 在 romfs.c 中定义的全局结构
const struct romfs_dirent romfs_root = {.name = "",.type = ROMFS_DIRENT_DIR,.size = sizeof(romfs_img)/sizeof(romfs_img[0]),.data = (rt_uint8_t *)romfs_img // 指向实际文件数据
};
组件 | 物理位置 | 内容 | 访问方式 |
---|---|---|---|
romfs_root 结构体 | 内部 Flash (.rodata 段) | 文件系统元数据(目录结构) | 直接内存访问 |
romfs_img 数据 | 内部 Flash (.rodata 段) | 实际文件内容 | 通过 romfs_root->data 访问 |