就ARM64硬件而言,EL0和EL1共享一种转换机制,TTBR0_EL1
和TTBR1_EL1
分别控制地址空间的下半部分和上半部分.通常,下半部分用于用户空间,上半部分用于内核.
但首先要注意的是,rlimit
与硬件无关.这是关于操作系统的.
XNU有这样的功能(它也会被复制到苹果的SDK中):
#define RLIM_INFINITY (((__uint64_t)1 << 63) - 1) /* no limit */
所以这只是"无限制"的值.
第二个注意事项是,尽管描述了RLIMIT_AS
,但这与地址空间大小无关.这大约是the sum of all existing mappings in the process.
Arm64 XNU允许您映射内存的实际最大地址是0x00007ffffe000000.This value is just hardcoded for macOS.还有一个最小地址,它在进程初始化时设置为进程中主二进制的基地址(通常为0xThis value is just hardcoded for macOS000000)加上ASLR幻灯片.
在MacOS以外的苹果操作系统上,最大地址的规则更为复杂,但以下是相关的代码位:
osfmk/mach/arm/vm_param.h
:
#if defined(XNU_PLATFORM_MacOSX) || defined(XNU_PLATFORM_DriverKit)
#define MACH_VM_MAX_ADDRESS_RAW 0x00007FFFFE000000ULL
#else
#define MACH_VM_MAX_ADDRESS_RAW 0x0000000FC0000000ULL
#endif
osfmk/mach/shared_region.h
:
#define SHARED_REGION_BASE_ARM64 0x180000000ULL
#define SHARED_REGION_SIZE_ARM64 0x100000000ULL
osfmk/arm/pmap/pmap.c
:
/* end of shared region + 512MB for various purposes */
#define ARM64_MIN_MAX_ADDRESS (SHARED_REGION_BASE_ARM64 + SHARED_REGION_SIZE_ARM64 + 0x20000000)
// Max offset is 13.375GB for devices with "large" memory config
#define ARM64_MAX_OFFSET_DEVICE_LARGE (ARM64_MIN_MAX_ADDRESS + 0x138000000)
// Max offset is 9.375GB for devices with "small" memory config
#define ARM64_MAX_OFFSET_DEVICE_SMALL (ARM64_MIN_MAX_ADDRESS + 0x38000000)
vm_map_offset_t
pmap_max_64bit_offset(
__unused unsigned int option)
{
vm_map_offset_t max_offset_ret = 0;
#if defined(__arm64__)
const vm_map_offset_t min_max_offset = ARM64_MIN_MAX_ADDRESS; // end of shared region + 512MB for various purposes
if (option == ARM_PMAP_MAX_OFFSET_DEFAULT) {
max_offset_ret = arm64_pmap_max_offset_default;
} else if (option == ARM_PMAP_MAX_OFFSET_MIN) {
max_offset_ret = min_max_offset;
} else if (option == ARM_PMAP_MAX_OFFSET_MAX) {
max_offset_ret = MACH_VM_MAX_ADDRESS;
} else if (option == ARM_PMAP_MAX_OFFSET_DEVICE) {
if (arm64_pmap_max_offset_default) {
max_offset_ret = arm64_pmap_max_offset_default;
} else if (max_mem > 0xC0000000) {
// devices with > 3GB of memory
max_offset_ret = ARM64_MAX_OFFSET_DEVICE_LARGE;
} else if (max_mem > 0x40000000) {
// devices with > 1GB and <= 3GB of memory
max_offset_ret = ARM64_MAX_OFFSET_DEVICE_SMALL;
} else {
// devices with <= 1 GB of memory
max_offset_ret = min_max_offset;
}
} else if (option == ARM_PMAP_MAX_OFFSET_JUMBO) {
if (arm64_pmap_max_offset_default) {
// Allow the boot-arg to override jumbo size
max_offset_ret = arm64_pmap_max_offset_default;
} else {
max_offset_ret = MACH_VM_MAX_ADDRESS; // Max offset is 64GB for pmaps with special "jumbo" blessing
}
} else {
panic("pmap_max_64bit_offset illegal option 0x%x", option);
}
assert(max_offset_ret <= MACH_VM_MAX_ADDRESS);
assert(max_offset_ret >= min_max_offset);
#else
panic("Can't run pmap_max_64bit_offset on non-64bit architectures");
#endif
return max_offset_ret;
}
因此,在iOS和其他非MacOS配置上,如果您有"巨型"映射(您可以使用com.apple.developer.kernel.extended-virtual-addressing
授权获得,或者在some设备上使用com.apple.developer.kernel.increased-memory-limit
),则地址大小限制为0x0000000fc0000000;否则,根据设备的物理内存大小,地址大小限制为0x00000002a0000000、0x00000002b8000000或0x00000003b8000000.
请注意,后三个大小可能会发生变化,因为它们是根据共享缓存区域边界的大小计算的,而共享缓存区域边界本身可能会发生变化."9.375 GB"和"13.375 GB"的 comments 在今天也是错误的,因为它们源于SHARED_REGION_SIZE_ARM64
是0xa0000000
的时代.