gpt4 book ai didi

Does the address space not use the first bit on macos/arm64?(地址空间不使用MacOS/arm64上的第一位吗?)

转载 作者:bug小助手 更新时间:2023-10-24 23:23:30 29 4
gpt4 key购买 nike



I'm using an ARM64 system(M1).

我使用的是ARM64系统(M1)。


$ uname -m
arm64

This is the C program I'm using to find out the virtual address space range on my system.

这是我用来找出系统上的虚拟地址空间范围的C程序。


#include <stdlib.h>
#include <stdio.h>
#define _GNU_SOURCE
#include <assert.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/resource.h>

int main(void) {
printf("Page size = %d\n", getpagesize());

struct rlimit x;

getrlimit(RLIMIT_AS, &x);
printf("Current maximum size = %llx\n", x.rlim_cur);
printf("Limit on maximum size = %llx\n", x.rlim_max);

unsigned long long int value = 0;
value -= 1;
printf("Maximum float = %llx", value);
return 0;
}

Output:

产出:


Current maximum size = 7fffffffffffffff // 9223372036854775807
Limit on maximum size = 7fffffffffffffff // 9223372036854775807
Maximum float = ffffffffffffffff // 18446744073709551615

The maximum size seems to be 2^63-1. The last bit is not being used at all.

最大大小似乎是2^63-1。最后一位根本没有被使用。


Why is this the case? On a 64bit system, the virtual memory address range should be until 2^64-1 right?

为何会是这样呢?在64位系统上,虚拟内存地址范围应该是到2^64-1,对吗?


I am aware that for addresses only 48 bits are used, but that doesn't seem to be related for the range of address space(Why there are two different lengths for addresses in 32 and 64 bit?)

我知道地址只使用了48位,但这似乎与地址空间的范围无关(为什么32位和64位的地址有两种不同的长度?)


更多回答

I'm having little luck finding anything darwin/arm64 specific. The closest I got was netbsd/amd64. But that leads me to believe that the top half of the address space is reserved for the kernel. Same as Linux.

我没有找到任何达尔文/arm64特定的东西。我得到的最接近的是netbsd/amd64。但这让我相信地址空间的上半部分是为内核保留的。与Linux相同。

I doubt rlimit_max is related to the underlying operating system'a address space layout, the default (max) value may be related to the maximum value of ssize_t, which is indeed 0x7fffffffffffffff.

我怀疑rLimit_max与底层操作系统的地址空间布局有关,默认(Max)值可能与size_t的最大值有关,后者实际上是0x7fffffffffffffff。

In any case, on ARM64 you usually have two translation table base registers (TTBR0 and TTBR1) that are used to hold the address of the first level page table. Which one to use depends on the highest bit of the virtual address to translate. The kernel usually gets TTBR1 and userspace gets TTBR0, hence userspace will never have the MSB set, while the kernel always will.

无论如何,在ARM64上,通常有两个转换表基寄存器(TTBR0和TTBR1),用于保存第一级页表的地址。使用哪一个取决于要转换的虚拟地址的最高位。内核通常获取TTBR1,而用户空间获取TTBR0,因此用户空间永远不会设置MSB,而内核总是会设置。

优秀答案推荐

As far as arm64 hardware goes though, EL0 and EL1 share a translation regime, with TTBR0_EL1 and TTBR1_EL1 controlling the lower and upper halves of the address space respectively. Usually the lower half is used for userland, and the upper half for the kernel.

就ARM64硬件而言,EL0和EL1共享一种转换机制,TTBR0_EL1和TTBR1_EL1分别控制地址空间的下半部分和上半部分。通常,下半部分用于用户空间,上半部分用于内核。


But as a first note, rlimit has nothing to do with the hardware. This is about the operating system.

但首先要注意的是,rLimit与硬件无关。这是关于操作系统的。


XNU has this (which also gets copied into Apple's SDKs):

XNU有这个(它也会被复制到苹果的SDK中):


#define RLIM_INFINITY   (((__uint64_t)1 << 63) - 1)     /* no limit */

So that's just the "no limit" value.

所以这只是“无限制”的值。


As a second note, despite the description of RLIMIT_AS, this has nothing to do with the address space size. This is about the sum of all existing mappings in the process.

第二点,尽管描述了RLIMIT_AS,但这与地址空间大小无关。这大约是该过程中所有现有映射的总和。


The real maximum address at which arm64 XNU will let you map memory is 0x00007ffffe000000. This value is just hardcoded for macOS. There is also a minimum address, which is set at process initialisation to the base address of the main binary in the process (usually 0x100000000) plus ASLR slide.

Arm64 XNU允许您映射内存的实际最大地址是0x00007ffffe000000。该值仅针对MacOS进行了硬编码。还有一个最小地址,它在进程初始化时设置为进程中主二进制的基地址(通常为0x100000000)加上ASLR幻灯片。


On Apple OSes other than macOS, the rules for the maximum address are more complicated, but here are the relevant code bits:

在MacOS以外的苹果操作系统上,最大地址的规则更为复杂,但以下是相关的代码位:


osfmk/mach/arm/vm_param.h:

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:

Osfmk/mach/Shared_Region.h:


#define SHARED_REGION_BASE_ARM64                0x180000000ULL
#define SHARED_REGION_SIZE_ARM64 0x100000000ULL

osfmk/arm/pmap/pmap.c:

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;
}

So on iOS and other non-macOS configs, the address size limit is either 0x0000000fc0000000 if you have "jumbo" maps (which you can get with the com.apple.developer.kernel.extended-virtual-addressing entitlement, or on some devices with com.apple.developer.kernel.increased-memory-limit), and otherwise either 0x00000002a0000000, 0x00000002b8000000 or 0x00000003b8000000, depending on how much physical memory the device has.

因此,在iOS和其他非MACOS配置上,如果您有“巨型”映射(您可以通过com.apple.developer.kernel.extended-virtual-addressing授权获得),则地址大小限制为0x0000000fc0000000,或者在一些具有com.apple.developer.kernel.increased-memory-limit),的设备上,或者是0x00000002a0000000、0x00000002b8000000或0x00000003b8000000,具体取决于设备有多少物理内存。


Note that the latter three sizes are subject to change though, because they're calculated from the size of the shared cache region bounds, which is itself subject to change. The "9.375GB" and "13.375GB" comments are also wrong today, because they stem from a time when SHARED_REGION_SIZE_ARM64 was 0xa0000000.

请注意,后三个大小可能会发生变化,因为它们是根据共享缓存区域边界的大小计算的,而共享缓存区域边界本身可能会发生变化。“9.375 GB”和“13.375 GB”的注释今天也是错误的,因为它们源于Shared_Region_SIZE_ARM64为0xa0000000的时候。


更多回答

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com