我缺乏C知识,这可能是一个更大的问题,但是我希望有人能够提供可能的解决方案。简而言之,我试图读取存储在内存中的结构,并且我拥有它的物理内存地址。同样,这是在64位Linux系统(Debian(Wheezy)内核3.6.6)上完成的,我想使用C作为语言。
例如,相关结构的当前地址位于物理地址:0x3f5e16000
现在,我确实确实尝试使用指向/dev/mem的指针来访问该地址。但是,自那以后,我得知不允许访问任何大于1024MB的地址,并且在var/log/messages中收到一条不错的错误消息,告诉我有关此问题的所有信息。目前正在尝试从用户空间应用程序进行访问,但是如果需要的话,我很乐于考虑编写内核模块。
有趣的是,我还发现了一种称为“kprobe”的东西,据说可以绕过> 1024MB/dev/mem限制。但是,我真的不想在系统中引入任何潜在的安全问题,并且我相信必须有一种更简单的方法来实现此目的。有关kprobe的信息可以在这里找到:http://www.libcrack.so/2012/09/02/bypassing-devmem_is_allowed-with-kprobes/
我已经读了一些书,并且找到了使用mmap将物理地址映射到用户空间以便可以读取的引用,但是我必须承认我不理解在C语言中的实现。
如果有人可以提供一些有关访问物理内存的信息,或者将数据从物理地址映射到用户空间虚拟地址,我将不胜感激。
如果我对我正在做的事情有些含糊,则必须原谅我,但这是项目的一部分,我不想透露太多信息,所以请多多包涵:)我不是什么钝的东西。
内存中的结构是由四个int和10个long组成的块,该块由正在运行的内核模块加载到内存中。
我正在使用的地址肯定是物理地址,并且设置为非分页,内核模块执行了到物理地址的转换,并且我没有使用address-of运算符。
我想知道是否应该将问题改写为如何从物理位置读取int,因为这是该结构的第一个元素。我希望这有助于澄清问题!
编辑-阅读更多内容后,似乎可以解决此问题的一种方法是构造一个内核模块,然后使用mmap
函数将物理地址映射到该内核模块可以访问的虚拟地址。谁能提供使用mmap实现此目标的任何建议?
最佳答案
我只会回答这个问题:
不。问题不是int
和struct
,问题在于C本身没有物理内存的概念。操作系统与MMU结合使用可确保每个进程(包括每个正在运行的C程序)都在虚拟内存沙箱中运行。操作系统可能会为物理内存提供一个逃生通道。
如果您正在编写一个内核模块,用于管理物理地址0x3f5e16000
上的某些对象,那么您应该提供一些API来访问该内存,最好是使用文件描述符或其他抽象方法来隐藏内核内存管理实质的API从与之通信的用户程序。
如果您试图与设计不当的内核模块通信,期望您访问固定的物理内存地址,那么涉及/dev/mem
的丑陋骇客就是您的本分。
关于c - 从C中的物理内存地址读取struct,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14264809/