- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章理解 ARM64 内核中对 52 位虚拟地址的支持由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
随着 64 位硬件的引入,增加了处理更大地址空间的需求.
当 64 位硬件变得可用之后,处理更大地址空间(大于 232 字节)的需求变得显而易见。现如今一些公司已经提供 64TiB 或更大内存的服务器,x86_64 架构和 arm64 架构现在允许寻址的地址空间大于 248 字节(可以使用默认的 48 位地址支持).
x86_64 架构通过让硬件和软件启用五级页表以支持这些用例。它允许寻址的地址空间等于 257 字节(详情见 x86:在 4.12 内核中启用 5 级页表)。它突破了过去虚拟地址空间 128PiB 和物理地址空间 4PiB 的上限.
arm64 架构通过引入两个新的体系结构 —— ARMv8.2 LVA(更大的虚拟寻址) 和 ARMv8.2 LPA(更大的物理地址寻址) —— 拓展来实现相同的功能。这允许使用 4PiB 的虚拟地址空间和 4PiB 的物理地址空间(即分别为 252 位).
随着新的 arm64 CPU 中支持了 ARMv8.2 体系结构拓展,同时现在开源软件也支持了这两种新的硬件拓展.
从 Linux 5.4 内核开始, arm64 架构中的 52 位(大)虚拟地址(VA)和物理地址(PA)得到支持。尽管内核文档描述了这些特性和新的内核运行时对旧的 CPU(硬件层面不支持 52 位虚拟地址拓展)和新的 CPU(硬件层面支持 52 位虚拟地址拓展)的影响,但对普通用户而言,理解这些并且如何 “选择使用” 52 位的地址空间可能会很复杂.
因此,我会在本文中介绍下面这些比较新的概念:
。
ARMv8.2 架构提供两种重要的拓展:大虚拟寻址(LVA)和大物理寻址(LPA).
当使用 64 KB 转换粒度时,ARMv8.2-LVA 为每个翻译表基地址寄存器提供了一个更大的 52 位虚拟地址空间.
在 ARMv8.2-LVA 中允许:
需要注意的是这些特性仅在 AArch64 架构中支持.
目前下列的 Arm64 Cortex-A 处理器支持 ARMv8.2 拓展:
更多细节请参考 Armv8 架构参考手册.
。
伴随着 ARMv8.2 拓展增加了对 LVA 地址的支持(仅当以页大小为 64 KB 运行时可用),在第一级转换中,描述符的数量会增加.
用户地址将 63-48 位位置为 0,然而内核地址将这些位设置为 1。TTBRx 的选择由虚拟地址的 63 位决定。swapper_pg_dir 仅包含内核(全局)映射,然而 pgd 仅包含用户(非全局)的映射。swapper_pg_dir 地址会写入 TTBR1,且永远不会写入 TTBR0.
页面大小为 64 KB 和三个级别的(具有 52 位硬件支持)的 AArch64 架构下 Linux 内存布局如下:
开始 结束 大小 用途 。
----------------------------------------------------------------------- 。
0000000000000000 000fffffffffffff 4PB 用户 。
fff0000000000000 fff7ffffffffffff 2PB 内核逻辑内存映射 。
fff8000000000000 fffd9fffffffffff 1440TB [间隙] 。
fffda00000000000 ffff9fffffffffff 512TB Kasan 阴影区 。
ffffa00000000000 ffffa00007ffffff 128MB bpf jit 区域 。
ffffa00008000000 ffffa0000fffffff 128MB 模块 。
ffffa00010000000 fffff81ffffeffff ~88TB vmalloc 区 。
fffff81fffff0000 fffffc1ffe58ffff ~3TB [保护区域] 。
fffffc1ffe590000 fffffc1ffe9fffff 4544KB 固定映射 。
fffffc1ffea00000 fffffc1ffebfffff 2MB [保护区域] 。
fffffc1ffec00000 fffffc1fffbfffff 16MB PCI I/O 空间 。
fffffc1fffc00000 fffffc1fffdfffff 2MB [保护区域] 。
fffffc1fffe00000 ffffffffffdfffff 3968GB vmemmap 。
ffffffffffe00000 ffffffffffffffff 2MB [保护区域] 。
4 KB 页面的转换查询表如下:
+--------+--------+--------+--------+--------+--------+--------+--------+ 。
|63 56|55 48|47 40|39 32|31 24|23 16|15 8|7 0| 。
+--------+--------+--------+--------+--------+--------+--------+--------+ 。
| | | | | | 。
| | | | | v 。
| | | | | [11:0] 页内偏移量 。
| | | | +-> [20:12] L3 索引 。
| | | +-----------> [29:21] L2 索引 。
| | +---------------------> [38:30] L1 索引 。
| +-------------------------------> [47:39] L0 索引 。
+-------------------------------------------------> [63] TTBR0/1 。
64 KB 页面的转换查询表如下:
+--------+--------+--------+--------+--------+--------+--------+--------+ 。
|63 56|55 48|47 40|39 32|31 24|23 16|15 8|7 0| 。
+--------+--------+--------+--------+--------+--------+--------+--------+ 。
| | | | | 。
| | | | v 。
| | | | [15:0] 页内偏移量 。
| | | +----------> [28:16] L3 索引 。
| | +--------------------------> [41:29] L2 索引 。
| +-------------------------------> [47:42] L1 索引 (48 位) 。
| [51:42] L1 索引 (52 位) 。
+-------------------------------------------------> [63] TTBR0/1 。
。
arm64 Multi-level Translation 。
。
因为支持 LVA 的较新的内核应该可以在旧的 CPU(硬件不支持 LVA 拓展)和新的 CPU(硬件支持 LVA 拓展)上都正常运行,因此采用的设计方法是使用单个二进制文件来支持 52 位(如果硬件不支持该特性,则必须在刚开始启动时能回退到 48 位)。也就是说,为了满足 52 位的虚拟地址以及固定大小的 PAGE_OFFSET,VMEMMAP 必须设置得足够大.
这样的设计方式要求内核为了新的虚拟地址空间而支持下面的变量:
VA_BITS 常量 *最大的* 虚拟地址空间大小 。
。
vabits_actual 变量 *实际的* 虚拟地址空间大小 。
因此,尽管 VA_BITS 设置了最大的虚拟地址空间大小,但实际上支持的虚拟地址空间大小由 vabits_actual 确定(具体取决于启动时的切换).
保持一个单一内核二进制文件的设计方法要求内核的 .text 位于高位地址中,因此它们对于 48/52 位虚拟地址是不变的。因为内核地址检测器(KASAN)区域仅占整个内核虚拟地址空间的一小部分,因此对于 48 位或 52 位的虚拟地址空间,KASAN 区域的末尾也必须在内核虚拟地址空间的上半部分。(从 48 位切换到 52 位,KASAN 区域的末尾是不变的,且依赖于 ~0UL,而起始地址将“增长”到低位地址) 。
为了优化 phys_to_virt() 和 virt_to_phys(),页偏移量将被保持在 0xFFF0000000000000 (对应于 52 位),这消除了读取额外变量的需求。在早期启动时将会计算 physvirt 和 vmemmap 偏移量以启用这个逻辑.
考虑下面的物理和虚拟 RAM 地址空间的转换:
/* 。
* 内核线性地址开始于虚拟地址空间的底部 。
* 测试区域开始处的最高位已经是一个足够的检查,并且避免了担心标签的麻烦 。
*/ 。
。
#define virt_to_phys(addr) ({ \ 。
if (!(((u64)addr) & BIT(vabits_actual - 1))) \ 。
(((addr) & ~PAGE_OFFSET) + PHYS_OFFSET) 。
}) 。
。
#define phys_to_virt(addr) ((unsigned long)((addr) - PHYS_OFFSET) | PAGE_OFFSET) 。
。
在上面的代码中:
PAGE_OFFSET — 线性映射的虚拟地址的起始位置位于 TTBR1 地址空间 。
PHYS_OFFSET — 物理地址的起始位置以及 vabits_actual — *实际的*虚拟地址空间大小 。
。
有几个用户空间应用程序可以用于调试正在运行的/活动中的内核或者分析系统崩溃时的 vmcore 转储(例如确定内核奔溃的根本原因):kexec-tools、makedumpfile 和 crash-utility.
当用它们来调试 Arm64 内核时,因为 Arm64 内核内存映射被“翻转”,因此也会对它们产生影响。这些应用程序还需要遍历转换表以确定与虚拟地址相应的物理地址(类似于内核中的完成方式).
相应地,在将“翻转”引入内核内存映射之后,由于上游破坏了用户态应用程序,因此必须对其进行修改.
我已经提议了对三个受影响的用户态应用程序的修复;有一些已经被上游接受,但其他仍在等待中:
除非在用户空间应用程序进行了这些修改,否则它们将仍然无法调试运行/活动中的内核或分析系统崩溃时的 vmcore 转储.
。
为了保持与依赖 ARMv8.0 虚拟地址空间的最大为 48 位的用户空间应用程序的兼容性,在默认情况下内核会将虚拟地址从 48 位范围返回给用户空间.
通过指定大于 48 位的 mmap 提示参数,用户态程序可以“选择”从 52 位空间接收虚拟地址.
例如:
.mmap_high_addr.c 。
---- 。
。
maybe_high_address = mmap(~0UL, size, prot, flags,...),
通过启用以下的内核配置选项,还可以构建一个从 52 位空间返回地址的调试内核:
CONFIG_EXPERT=y && CONFIG_ARM64_FORCE_52BIT=y 。
请注意此选项仅用于调试应用程序,不应在实际生产中使用.
。
总结一下:
原文地址:https://linux.cn/article-13069-1.html 。
最后此篇关于理解 ARM64 内核中对 52 位虚拟地址的支持的文章就讲到这里了,如果你想了解更多关于理解 ARM64 内核中对 52 位虚拟地址的支持的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
目前,我有以下设置: A记录: mydomain.com - aaa.aaa.aaa.aaa subdomain.mydomain.com - aaa.aaa.aaa.aaa NS记录: mydoma
有人可以帮助我以最佳方式在流畅的 nHibernate 中映射以下情况吗? Address 类用于 Client 和 Company。如何在 SQL 中最有效地存储它?映射应该是什么样的?我已经考虑过
我正在尝试编写一个 Windows 应用程序,它将在来自 PC 的以太网链接上生成流量。 我想使用 webBrowser 控件不断拉取网页以产生流量。 在这种情况下,我希望每个 webBrowser
我正在编写一个 SIP 堆栈,我需要在消息中插入一个 IP 地址。该地址必须是用于发送消息的地址。我知道目标 IP 并且需要确定将用于发送消息的 NIC(其地址).... 最佳答案 为了扩展 Remy
如何使用 IP 地址获取 MAC 地址,但以下代码不起作用 packet = ARP(op=ARP.who_has,psrc="some ip",pdst = ip) response = srp(p
目前我想知道如何实现对本地无线网络(路由器)的获取请求以获取当前连接到当前连接的 LAN 的所有设备.... 所以我做了一些研究,显然“nmap”是一个终端/命令提示符命令,它将连接的设备返回到本地无
这个问题在这里已经有了答案: 关闭 11 年前。 Possible Duplicates: how to find MAC address in MAC OS X programmatically
我们正在为 ipad 开发一个 iOS 应用程序,它使用 bonjour 与其他设备连接,使用 couchbaseListener 与对等数据库进行复制。我们观察到,每当 [nsnetservice
我创建了 3 个实例,其中 3 个弹性 IP 地址指向这些实例。 我做了 dsc 的 yum 安装:dsc12.noarch 1.2.13-1 @datastax 并且/etc/cassandra/d
我正在尝试获取规模集中所有虚拟机的私有(private) IP 地址列表(没有一个虚拟机故意拥有任何公共(public) IP 地址)。我找到了如何从 az cli 获取此内容,如下所示: az vm
我正在尝试获取规模集中所有虚拟机的私有(private) IP 地址列表(没有一个虚拟机故意拥有任何公共(public) IP 地址)。我找到了如何从 az cli 获取此内容,如下所示: az vm
我正在尝试与该端口上的任何 IP 建立连接。最初,我将其设置为 10.0.0.7,这是我网络上另一台计算机的 IP,因此我可以测试客户端/服务器。但是,我希望它可以与任何计算机一起使用而不必将 IP
作为序言,我开发了自己的 CRM(类似于 SalesForce 或 SAP),其“规模”要小得多,因为它面向服务,而不是销售。我在 Ubuntu 16.04 服务器上使用 MySql 或 MariaD
在我的项目中,我想做如下事情: static void test0(void) { printf("%s [%d]\n", __func__, __LINE__); } static void
我的机器上有两个网卡,配置了两个独立的 IP 地址。两个 IP 地址都属于同一个网络。我是否正确地说,当我创建一个特定于这些 IP 地址之一的套接字时? 更新: 这是我的情况: 我有一个位于 192.
当然,我意识到没有一种“正确的方法”来设计 SQL 数据库,但我想就我的特定场景中的优劣获得一些意见。 目前,我正在设计一个订单输入模块(带有 SQL Server 2008 的 Windows .N
我们将保存大量地址数据(在我公司的眼中,每个客户大约有150.000至500.000行)。 地址数据包含约5列: 名称1 名称2 街(+否) 邮政编码 市 也许以后再添加一些东西(例如电话,邮件等)
好的,我们在生产中实现了 Recaptcha。我们收到错误是因为它无法到达使用该服务所需的 IP 地址。我们为 IP 地址打开一个端口以到达 Google。没问题。我们这样做并显式配置该 IP 地址以
此页面使用 Drupals 联系表发送电子邮件:http://www.westlake.school.nz/contact 问题是,学校员工使用 outlook。当他们收到来自 parent 等的电子
是否可以将用户输入的邮政编码转换为文本框并将其转换为CLLocation?我正在尝试比较其当前位置与地址或邮政编码之间的距离,如果可以从NSString中创建CLLocation,这将很容易。 最佳答
我是一名优秀的程序员,十分优秀!