0

我正在 64 位 Linux 机器上开发一个程序,该程序需要将多个任意长度的数据数组映射到我无法控制的固定内存地址。我认为 mmap() 与 MAP_FIXED 和 MAP_ANONYMOUS 是要走的路,例如:

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(例如,它们太大或未对齐)在页面边界上)。” 不过,我还不能弄清楚哪一个是问题所在。

4

2 回答 2

1

鉴于这0x400000似乎是我的Debian 系统.text上进程的地址(不同),我怀疑您遇到了失败,因为您正在尝试映射现有的东西,正如您所想的那样。不确定(以编程方式)确定哪些段被映射/可用的最佳方法,但您可以首先检查一些“典型”进程,以了解您的系统如何将地址范围分配给程序和库。地址空间随机化也在那里引发了一些额外的皱纹......amd64x86/proc/<pid>/maps

于 2012-07-27T16:53:24.160 回答
0

这是我很久以前写的一个例子,它确实是固定地址的mmap。它映射帧缓冲区以设置/清除像素:

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 开放。

于 2012-07-27T16:35:33.917 回答