首页 > 解决方案 > Linux/C++ 中的 NVM 存储模拟器

问题描述

我目前正在移植一个项目以在 Linux 上运行,该项目将一些数据存储在 NVM 外部存储中。在我的硬件上,我只有一个 eMMC 主存储,Linux rootfs 所在的位置可供我使用。我想做的是在Linux中模拟以前的NVM外部存储,以便我的应用程序可以在那里存储一些数据。

我想到的第一个明显的解决方案是将这些数据存储在 eMMC 的不同内存区域中,Linux 不使用该内存区域,但目前我无法控制对 eMMC 的当前布局进行分区。

我想到的另一个想法是将这些数据存储在 fs 上的文件中,但这将引入大量打开和关闭 fd 以写入和获取数据的操作,除了文件很容易损坏。

旁注:我要移植的应用程序是用 C++ 编写的。

我在这里问这个问题想知道的不是如何具体实施,而是找出解决这个问题的不同解决方案和想法。

有关应用程序和要求的更多信息:

谢谢。

标签: c++linuxdatabasestoragenvm

解决方案


结束在文件系统上打开/创建文件

memFileFd = open(memFilePath.c_str(), O_RDWR | O_CREAT, (mode_t)0600);

将文件扩展至所需大小

// go to the end of the desired size
lseek(memFileFd, memSize, SEEK_SET);

// write termination character to expand it
write(memFileFd, "", 1);

映射为文件分配的内存

memBlock = (uint8_t *)mmap(0, memSize, PROT_READ | PROT_WRITE, MAP_SHARED, memFileFd, 0);

// we can safely close the FD now after the mem was mapped
close(memFileFd);

然后我们可以从内存块中读写,并将其视为虚拟 NVM

// write data
memcpy(memBlock + address, bufferToBeWritten, bufferLength);

// we want to flush the cached pages touched by us so we
// calculate the start address of the cache page written and the
// size of the touched memory as a multiple of page size
int pagesize = getpagesize();
uint32_t syncStartPageOffset = (address / (uint32_t)pagesize) * pagesize;
uint32_t syncSize = ((bufferLength / (uint32_t)pagesize) + 1) * pagesize;

// sync mem
msync(m_memBlock + syncStartPageOffset, syncSize, MS_SYNC);

// read data
memcpy(bufferToBeReadIn, memBlock + address, bufferLength);


推荐阅读