C++ 闪存仿真库-捕获内存写入访问

C++ 闪存仿真库-捕获内存写入访问,c++,windows,emulation,device-driver,systems-programming,C++,Windows,Emulation,Device Driver,Systems Programming,我被要求写一个库(用C++编写),它将模拟和flash一样的行为。 (平台-Windows,语言-C++) (很抱歉发了这么长的帖子,我想解释一下我到目前为止做了什么:)) 所需行为: 所以,这就是它的工作原理,我需要返回内存范围,用户将其用作闪存。他应该能够从返回的内存缓冲区中读取任何字节,这不是问题,主要问题在于写入,因为闪存的写入行为不同,因此,如果一个地址包含内容(二进制)10101010,并且用户尝试将01011001写入该地址,则只能重置一点,那么在写入之后,该位置实际上应该包含10

我被要求写一个库(用C++编写),它将模拟和flash一样的行为。 (平台-Windows,语言-C++) (很抱歉发了这么长的帖子,我想解释一下我到目前为止做了什么:))

所需行为:

所以,这就是它的工作原理,我需要返回内存范围,用户将其用作闪存。他应该能够从返回的内存缓冲区中读取任何字节,这不是问题,主要问题在于写入,因为闪存的写入行为不同,因此,如果一个地址包含内容(二进制)10101010,并且用户尝试将01011001写入该地址,则只能重置一点,那么在写入之后,该位置实际上应该包含10101010&01011001=000011000。我不知道如何才能做到这一点

以下是我正在考虑的方法:

我需要将数据作为文件存储在内部,以便能够多次使用它并在多次使用后进行分析,因此我计划使用内存映射文件IO来返回内存。读取不是问题,但我不知道如何在写入之前捕获内存写入、应用和屏蔽

以下是我想的一些方法

方法1:

将暴露的指针标记为只读,因此允许用户从内存直接读取,但对于写入,我们可以公开一个接口,该接口将是写入内存的唯一接口。由于它是我们的接口,我们可以处理应用掩蔽的要求

优点:

=>使实现保持简单

缺点:

=>通过限制用户写入,降低了模块的可用性

方法2:

编写一个类,该类将重载所有可能的内存访问运算符。像这样的

template <class T> class flashMemory
{
    T data;
public:
    void operator = (T newData) {data &= newData};
    // Overload other operators too...
};
因此,这可能再次不是一个完整的解决方案,并且实际上可能会对任何新代码造成很多问题

方法3:

第三种方法是将页面保护设置为只读,并通过信号处理程序(Linux上的mprotect和sigaction)捕获任何写入尝试,但到目前为止,我只能捕获写入调用,但还无法获取更多信息来完成写入请求。将查看是否可能在应用掩码后捕获写入调用和写入数据。 如果这是可能的,它可以是完整的解决方案

优点:

1) 可以使用emulator透明地处理写请求,而无需对用户进行任何更改

这看起来很完美,但我只能得到中断,说有访问冲突,但我不知道如何实际获得正在写入的数据,并在将其写入中断处理程序之前应用掩码!(但我在Linux中尝试过,但在Windows中没有尝试过)

方法4:

有一些带有内存映射IO的模拟设备,任何对设备内存范围的写入都将进入我的设备驱动程序,我可以用它做任何我想做的事情

这只是一个想法,我不确定这是否可以做到,即使做到了,对我的要求来说也可能是一种过度

方法4:

为了像在方法3中那样透明地支持读写,我们可以使用linux的FUSE框架,相当于Windows(到目前为止,我得到了DOKAN和CBFS)。使用它,我们可以将代码作为文件系统呈现给系统,所有读写调用都将转移到用户空间中的代码中,在那里我们可以以任何方式操作数据。 因此,我们的代码将有两部分

  • 将flash_emulator类公开给应用程序编写器的库(我们现在拥有的库), =>这将在我们创建的用户空间文件系统中打开闪存仿真文件,并执行内存映射文件io,并将映射地址返回给用户,应用程序编写器可以使用该地址执行内存操作,这些操作将转换为文件系统操作(读和写)

  • 简单的用户空间文件系统。 =>这将实现用户空间文件系统所需的基本接口,并在内部使用系统文件系统实际存储文件。执行的读写操作将访问存储在光盘上的数据。读取将像现在一样从文件开始读取,但写入操作将对文件系统应用掩码和写入

  • 优点: =>可以透明地支持所有内存操作,并在幕后模拟类似闪存的行为

    缺点: =>它需要使用比我们编写的代码大得多的外部框架。 (我需要检查它们是否是免费的框架,我还不确定,如果它们不是免费的,我会检查并返回)

    实现用户空间文件系统只是为了具有透明的类似flash的写入特性,这可能是一种过分的做法,但如果在不影响应用程序编写器的代码的情况下实现它更为重要,那么这似乎是一种可能性。 请让我知道你对此的看法。多谢各位

    谢谢,

    微核

    flashMemory *flashPtr = flashObj.getPointer();
    flashPtr[10] = 'X';                        //Using overloaded operator, This is fine
    memcpy(flashPtr, someBuff, someSize);    //This is NOT fine
    ...
    char *myPtr = (void*)flashPtr;    //Everything below using typecasted ptr is NOT fine. 
    myPtr[100] = 'X';
    memcpy(myPtr, 0, someSize);
    memcpy(myPtr, destPtr, dataSize);