优化 UBIFS 分区磨损均衡的文件大小

问题描述 投票:0回答:1

我需要将 8 字节数据(uint64_t 计数器)重复写入大小为 256 MB 的 ubifs 分区。我担心由于重复写入而导致闪存磨损。

查看分区上的

ubinfo -a
输出,最小 I/O 单元大小为 2048 字节。所以我的第一次尝试是对大小为 2048 字节的文件进行循环写入。 IE。写入 256 次(乘以 8 字节),然后无限地返回到开头。

我已经建立了一个程序来测试这个理论,两周后我注意到

Current maximum erase counter value
又名
max_ec
计数器在大约 18 亿次写入后上升到大约 20,000。这远远超出了我对所有擦除块的完美均匀磨损的预期。我的下一个方法是尝试接近 124KB 的文件大小,即逻辑擦除块的大小,看看是否有任何区别。

我看到三个选项:

  • 尝试不同的文件大小进行比较
  • 读取ubifs驱动代码
  • 在启用调试的情况下重建内核并获取更多 ubifs 调试日志

有更好的方法吗?

这是重复写入的小 C 程序:

#include<stdio.h>
#include<fcntl.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/stat.h>

int main(int argc, char *argv[]){
    int fd;
    char *ptr;
    uint64_t writeops, filesize, index=0, i;

    if (argc!=3){
        printf("Usage: %s filesize(uint64_t) writeops(uint64_t)\n");
        return 1;
    }

    // Sanitise args
    filesize = strtoul(argv[1], &ptr, 10);
    writeops = strtoul(argv[2], &ptr, 10);

    if (filesize%8 !=0){
        printf("Filesize must be a multiple of 8\n");
        return 2;
    }

    // Open a file to write
    fd = open("/mnt/user/magicnumber", O_CREAT|O_RDWR|O_DSYNC|O_LARGEFILE, S_IRUSR|S_IWUSR);

    // Get file size to be as big as the filesize arg
    lseek(fd, filesize-1, SEEK_SET);
    write(fd, '\0', 1);

    // Begin actual testing
    for(i=1,index=0; i<=writeops; i++,index+=8){
        if (index == filesize){
            index = 0;
        }
        lseek(fd, index, SEEK_SET);
        write(fd, (char *)&i, sizeof(i));
    }
    close(fd);
    return 0;
}
filesystems embedded-linux ubifs
1个回答
0
投票

查看分区上的 ubinfo -a 输出,最小 I/O 单元大小为 2048 字节。所以我的第一次尝试是对大小为 2048 字节的文件进行循环写入。

看来您误解了最小I/O单元大小和文件大小之间的关系。最小I/O单元大小主要是NAND闪存芯片的页大小,但这并不意味着相同大小(最小I/O单元大小)的文件只是使用了最小I/O单元的空间,因为任何ubifs 文件将使用额外的空间用于 ubi + ubifs 管理负载。

在大多数情况下执行如此极端频率的写入操作是没有意义的。为什么不直接将数据存储到缓冲区中,然后偶尔将缓冲区写回 NAND?

© www.soinside.com 2019 - 2024. All rights reserved.