mmap
系统调用文档说如果出现以下情况,该函数将失败:
指定了MAP_FIXED并添加了地址 参数不是页面对齐或部分 期望的地址空间驻留 超出有效的地址空间 用户流程。
我无法在任何地方找到说明将作为有效地址进行映射的文档。 (我有兴趣在OS X和Linux上执行此操作,理想情况下,相同的地址对两者都有效。)。
答案 0 :(得分:7)
Linux内核将自身的部分虚拟地址空间保留到用户空间(几乎)无法访问且无法映射任何内容的位置。您正在寻找所谓的“userspace / kernelspace split”。
在i386上,arch默认为3G / 1G one - 用户空间低3 GB的虚拟地址空间,内核高1 GB,另外还有2G / 2G和1G / 3G分割:
config PAGE_OFFSET
hex
default 0xB0000000 if VMSPLIT_3G_OPT
default 0x80000000 if VMSPLIT_2G
default 0x78000000 if VMSPLIT_2G_OPT
default 0x40000000 if VMSPLIT_1G
default 0xC0000000
depends on X86_32
在x86_64上,用户空间位于(当前)48位虚拟地址空间的下半部分:
/*
* User space process size. 47bits minus one guard page.
*/
#define TASK_SIZE_MAX ((1UL << 47) - PAGE_SIZE)
答案 1 :(得分:1)
这取决于许多因素,其中许多因素都不在您的控制之下。正如adobriyan所提到的,根据操作系统,您有各种固定的上限,超出了内核代码和数据。通常,这个上限在32位操作系统上至少 2GB;一些操作系统提供额外的地址空间。 64位操作系统通常提供一个上限,由CPU支持的虚拟地址位数控制(通常至少40位地址空间)。但是,还有其他因素无法控制:
/proc/sys/vm/mmap_min_addr
可以自行执行mmaps,它们位于某个任意位置因此,没有办法绝对保证malloc
会成功,所以通常应该避免。
我见过的唯一需要MAP_FIXED
的地方是葡萄酒启动代码,该代码保留(使用MAP_FIXED
)2G以上的所有地址,以避免混淆不相信的Windows代码映射将显示负面地址。当然,这是对旗帜的高度专业化使用。
如果你为了避免在共享内存中处理偏移而试图这样做,一种选择是在类中包装指针以自动处理偏移:
MAP_FIXED
注意:这是未经测试的代码,但应该为您提供基本的想法。