c - Linux 不允许我访问固定的内存区域

标签 c linux memory-management

我有一些数据存储在闪存中,我需要使用 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/

相关文章:

iphone - 可能优化卸载 UIScrollView 和 PageControl 中不再可见的 View + Controller

c++ - EasyBMP c++ 的 RGBApixel 内存问题

r - 无法在大小为 11.8 Gb 的 R 中分配向量

linux - 如何使用 Bash 脚本安装 Puppet 并立即运行模块?

linux - docker : directory mapped in volume is not created with same user of host

c - 在未正确分配的函数中初始化的链表结构

html - 可以使用哪些技术和协议(protocol)来允许 c 程序启动并与 Web 服务器交互?

ruby - 在 Ruby 中将目录添加到加载路径的末尾?

c - 将文本文件读入 C 中的二维数组

c - 取消引用 void * 指针,结构数组