我正在使用64位Linux机器上的程序,该程序需要将多个任意长度的数据数组映射到我无法控制的固定内存地址。我以为带有MAP_FIXED和MAP_ANONYMOUS的mmap()是可行的方法,例如:
mmap((void *) 0x401000, 0x18e, PROT_NONE, MAP_ANONYMOUS | MAP_FIXED, -1, 0);
但是,每次我调用此函数时,它都会返回MAP_FAILED。我将fd设置为-1,我知道某些系统需要此地址,该地址是我的页面大小(4096)的倍数,并且长度为非负数,因此我想知道是否可能已经有0x401000由我的系统使用;我也尝试了0x402000、0x403000和0x404000,结果相同。
关于mmap()我是否缺少什么,或者是否有办法找出此地址上已有的内容?更好的是,由于我无法控制需要的地址,是否有更好的方法来避免遇到现有的映射?
编辑:检查errno后,我发现我得到的代码是无效的参数,因此,根据手册页,"我们不喜欢addr,length或offset(例如,它们太大,或未在页面边界上对齐)。"不过,我还不能弄清楚是哪一个问题。
鉴于0x400000似乎是我的amd64 Debian系统上进程的.text地址(x86不同),我怀疑您正在失败,因为您正在尝试映射现有的内容,例如 你以为。 不确定(以编程方式)确定要映射/可用的段的最佳方法,但是您可以先检查/proc//maps的"典型"过程数量,以了解系统如何将地址范围分配给程序和库。 地址空间随机化还会在其中增加一些额外的皱纹...
我发现我的代码失败并给出了无效的参数错误,因为我没有在flags参数中指定MAP_FIXED或MAP_SHARED。 在我解决了这个问题之后,只有到0x401000的映射失败,并且只有在使用MAP_FIXED时,它才看起来好像完全占据了该地址。 谢谢你的帮助!
这是我很久以前写的一个示例,它完成了固定地址的映射。 它映射帧缓冲区以设置/清除像素:
http://stromberg.dnsalias.org/~strombrg/pbmonherc.html
videoBase = (unsigned char *) mmap((caddr_t) videoBase, VideoRamLength,
PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_FIXED,
fd, VideoRamStart);
fd对/ dev / mem开放。
向devmem打开fd的意义是什么? 据我所知,那是我们的代码之间唯一的显着差异,而我从未见过这样做。
ISTR / dev / mem是一个文件,它提供了有关计算机物理内存的视图。