我有一些数据存储在闪存中,我需要使用 C 指针访问这些数据,以便能够使非 Linux 图形驱动程序工作(我认为这个要求与 DMA 相关,不确定)。调用 read 可以工作,但我不想在 FLASH 和非 Linux 驱动程序之间有中间 RAM 缓冲区。
但是,仅仅创建一个指针并在其上存储我想要的地址就会使 Linux 发出关于我的无效访问的异常。
void *ptr = 0xdeadbeef;
int a = *ptr; // invalid access!
我在这里缺少什么?有人可以向我指出一些 Material 来让我清楚地了解这个概念吗?
我正在阅读有关 mmap 的内容但我不确定这是否是我所需要的。
最佳答案
你遇到的问题是linux在virtual address space中运行你的程序。 。因此,您在代码中直接使用的每个地址(例如 0xdeadbeef)都是一个由 memory management unit 转换的虚拟地址。到一个物理地址,它不一定与您的虚拟地址相同。这可以轻松分离多个独立进程和其他内容,例如分页等。
现在的问题是,在您的情况下,没有物理地址映射到虚拟地址 0xdeadbeef 导致内核中止执行。
您已经找到的调用 mmap 要求内核将特定文件(从特定偏移量)分配给进程的虚拟地址。请注意,mmap 的返回地址可能是完全不同的地址。因此,不要对您获得的虚拟地址做出任何假设。
因此,有一些使用 mmap 和/dev/mem 的示例,其中内存设备的偏移量是物理地址。在内核能够将文件从您指定的偏移量分配给进程的虚拟地址后,您可以像直接访问一样访问内存区域。
当您不再需要该区域后,请不要忘记对该区域进行 munmap。否则,您将导致类似于内存泄漏的情况。
/dev/mem 方法的一个问题是运行该进程的用户需要访问该设备。这可能会引入安全问题(例如 Samsung recently introduced such a security hole 在其手持设备中)
更安全的方法是我发现的文章 ( The Userspace I/O HOWTO ) 中描述的方法,因为您仍然可以控制用户进程可访问的内存区域。
关于c - Linux 不允许我访问固定的内存区域,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14605595/