seL4 Mapping(三)

官网链接: Mapping

Mapping

这节课程主要是介绍seL4的虚存管理。

虚存 Virtual memory

除了用于操作硬件分页结构的内核原语之外,seL4不提供虚拟内存管理。用户必须为创建中间级分页结构,映射页面以及取消映射页面提供服务。
用户可以随意的定义他们自己的地址空间布局,但是有一个限制:seL4会占用虚地址空间的高地址部分。在大多数的32位的平台中,内核占用0xe0 00 00 00以上的空间。每个平台的这个变量是不太一样的,可以通过在seL4的源码中通过寻找kernelBase找到这个变量。
上面来个更直观的例子:

+--------------------------+  <- 高地址
|    seL4 Kernel Space     |  <- 内核空间,受保护
+--------------------------+
|                          |  
|        User Space        |  <- 用户空间,可以自由定义
|                          |
+--------------------------+  <- 低地址

分页结构 Paging structures

作为启动进程的一部分,seL4初始化根任务时还会为其创建一个顶级的硬件虚存对象,这个对象被称之为VSpace。根任务中的seL4_CapInitThreadVSpace能力槽是针对该结构可用的能力。对于每种架构(architecture),该能力将会对应不同的与硬件和顶级页结构相符的对象类型。下面的表列出了对于每种支持的架构的对象类型。

ArchitectureVSpace Object
aarch32seL4_PageDirectory
aarch64seL4_PageGlobalDirectory
ia32seL4_PageDirectory
x86_64seL4_PML4
RISC-VseL4_PageTable

除了顶级的页结构。需要中间硬件虚拟内存对象来映射页面。下面的表按照顺序列出了每个体系结构的这些对象。

ArchitectureObjects
aarch32seL4_PageTable
aarch64seL4_PageUpperDirectory, seL4_PageDirectory, seL4_PageTable
ia32seL4_PageTable
x86_64seL4_PDPT, seL4_PageDirectory, seL4_PageTable
RISC-VseL4_PageTable

这篇课程使用的是x86_64架构,但是包含了足够多的由seL4提供的虚存API信息以概括了其他的架构。
为了映射或者取消映射每种也结构都能够被调用。下面是一个映射x86_64seL4_PDRT对象的案例。

/* map a PDPT at TEST_VADDR */
error = seL4_X86_PDPT_Map(pdpt, seL4_CapInitThreadVSpace, TEST_VADDR, seL4_X86_Default_VMAttributes);

所有的映射函数都带有三个参数:

  • 该对象映射到的VSpace
  • 映射对象的虚拟地址
  • 虚存属性

如果提供的虚存地址与分页对象的大小不对齐,seL4将屏蔽任何未使用位。例如映射在0xDEADBEEF的4KiB页最终将映射在0xDEADB000上面。对齐含义不清楚的可参考下面的解释:
在 32 位机器上,虚拟地址是 32 位长,通常按照字节来编址,即总共有232B的虚存。如果每个页面大小为 4 KiB (即212字节),那么虚拟内存可以容纳的页面数为232/212=220个页。
在地址结构中,前 20 位用于标识虚拟页号(VPN),后 12 位用于页内偏移。因此,每个 4 KiB 的页面在映射到虚存时,必须对齐到虚存的 4 KiB 边界上。这就是为啥映射在0xDEADBEEF的4KiB页最终将被映射在0xDEADB000上面。
虚存属性决定了映射的缓存属性,这是架构依赖的。除了本教程使用的属性seL4_X86_Default_VMAttributes,你可以在libsel4中找到其他的可以替换的值。

Pages 页

一旦所有的中间页结构被映射到了特定的虚拟地址范围,可以通过调用帧(frame)能力将物理帧(frame)映射到这个范围。下面的代码片段展示了一个在地址TEST_VADDR映射一个帧的示例(将物理帧映射到虚拟地址)。

 /* map a read-only page at TEST_VADDR */error = seL4_X86_Page_Map(frame, seL4_CapInitThreadVSpace, TEST_VADDR, seL4_CanRead, seL4_X86_Default_VMAttributes);

为了使页面映射成功,必须映射所有的中级分页结构。libsel4中的函数seL4_MappingFailedLookupLevel() 可以被用于确定哪个等级的页结构是缺失的。注意,为了能将一个帧映射多次,必须复制帧能力:每个帧能力只能追踪一个映射。
除了中间分页结构的映射方法所采用的参数之外,页面映射还携带一个right参数,该参数决定了映射的类型。在上面的例子中,我们映射的这个页面是只读的。

Types and sizes

页的类型和大小是体系结构决定的。对于x86和ARM架构,每个尺寸的页面都是具有特定尺寸的不同对象类型(不像人话)。在RISC-V中,页面具有相同的对象类型和不同的大小。配置和硬件设置可改变可用的页面大小。

上面讲了一通看的人乱七八糟的,一方面可能是我翻译的不到位,还有就是解释篇幅是真的小啊。下面具体的总结一下上面说的啥:

解释

在 seL4 操作系统中,虚拟内存管理通过一个叫做 VSpace(虚拟地址空间)来完成,VSpace 是一个虚拟内存的层次结构,负责将虚拟地址映射到物理地址。为了做到这一点,seL4 借助了一些特定的硬件支持(比如 x86 和 ARM 架构的分页机制)和相应的页表对象。可以将 seL4 的虚拟内存结构理解为多级页表管理体系,每一级页表都有不同的角色和功能。下面将详细解释 VSpace 以及各级页表对象:

1、VSpace(虚拟地址空间)

VSpace 是一个抽象的概念,代表了进程可以使用的所有虚拟地址。每个进程在 seL4 中都有自己的虚拟地址空间(VSpace),这个空间通过分层的页表结构将虚拟地址映射到物理内存。VSpace 的核心在于将虚拟地址翻译成实际的物理内存地址。
VSpace 在 seL4 中通常会涉及到下面的几个核心组件:

  • 页表对象(Page Table Objects):这些对象存储页表条目,它们定义了虚拟地址如何映射到物理地址。
  • 顶级页表(Top-level page structure object):在某些体系结构中,虚拟地址空间的映射由多级页表组成,顶级页表是多级页表结构中的最高层,负责指向下一级页表。

不同的架构对页表对象有不同的层次结构,下面我们以常见的架构来说明。

2、顶级页结构对象(Top-level Page Table Object)

这个对象处于页表的最高层,用来管理整个虚拟地址空间的最上层映射。它是虚拟内存层次结构的入口,指向中间的页表层次,多级页表的感觉。
不同的硬件架构对顶级页表的命名有所不同(通过上面的表也可以看出来):
x86_64 架构:

  • 在 x86_64 架构上,顶级页表对象叫做 PML4(Page Map Level 4)。
  • PML4 是四级页表体系的最高级,用来指向PDPT(Page Directory Pointer Table)。
  • 一个 PML4 条目可以指向 512 个 PDPT 条目,涵盖整个 48 位虚拟地址空间。

3、中间硬件虚拟内存对象(Intermediate Page Table Objects)

这些对象位于顶级页表与实际的页之间,负责分割虚拟地址空间并指向具体的页表条目
在 x86_64 架构中的中间层次对象:

  • PDPT(Page Directory Pointer Table):位于 PML4 下一级,每个 PDPT 对应 512 个 PDE(Page Directory Entry)。
  • PDE(Page Directory Entry):指向具体的页表条目(Page Table Entry,PTE),PDE 层次可以覆盖到 1 GiB 的虚拟地址范围。
  • Page Table Entry (PTE):这是实际的页表条目,PTE 包含了物理帧(page frame)的地址信息。

4、页表条目(Page Table Entry, PTE)

  • 页表条目是分页机制中的最底层条目,直接映射虚拟页到物理页。每个页表条目通常记录着物理内存页的地址以及该页的访问权限、缓存设置等属性。
  • PTE 中的地址是指向物理内存页的开始地址,通常是按页对齐的。比如,在使用 4KiB 页大小时,PTE 中记录的地址最低的 12 位是 0(因为页大小是 2^12 B)。

5、举例而言

以x86_64为例:

  1. 顶级页表对象是 PML4,负责管理整个虚拟地址空间的最高层。
  2. PML4 中的条目指向 PDPT,每个条目管理 512 GiB 的虚拟地址空间。
  3. PDPT 中的条目指向 PDE,每个条目管理 1 GiB 的虚拟地址空间。
  4. PDE 中的条目指向 PTE,每个条目管理 2 MiB 的虚拟地址空间,或者通过 PTE 对应到具体的 4 KiB 页。

对于 ARMv8-A 架构,过程类似,只是使用了 PGD、PUD、PMD 等层次。

实操

本篇教程使用几个辅助函数去分配对象和能力。使用这几个函数可以帮助把所有的对象和能力槽分配都做了。

Map a page directory

教程运行时,可以看到以下的输出:
在这里插入图片描述
这是因为虽然提供的代码映射在seL4_PDPT对象中,但是缺少两个级别的分页结构。该值对应于libsel4常量SEL4_MAPPING_LOOKUP_NO_PD,它是由于缺少分页结构而无法解析的虚拟地址中的位数。
先看一下代码。
在这里插入图片描述
alloc_object这个方法在手册里面搜不到(说起来感觉好多在手册里都没搜到,应该是我找的不对,有知道的哥们可以说一声)其作用相当于将我们在 Untyped 章节中的 查找操作和 seL4_Untyped_Retype 操作结合在一起,从 untyped 对象中申请一个特定类型的新对象。同时还会返回存储对应 cap 的 CSlot。
可以看到,代码中已经做了PDPT映射,根据上文,x86虚地址管理,从虚地址到物理地址是四层结构,因此需要我们自己实现PD和PT映射。
映射到PD结构中,需要使用seL4_X86_PageDirectory_Map这个方法。
在这里插入图片描述
代码如下:

error = seL4_X86_PageDirectory_Map(pd, seL4_CapInitThreadVSpace, TEST_VADDR, seL4_X86_Default_VMAttributes);

再次运行的结果如下:
在这里插入图片描述
缺少第四级表结构,所以我们需要映射PDE表。需要注意的是,上面的输出中失败位数已经从30变成了21:这是因为我们进行了PDPT表映射,因此少了的9位在此时能够从新的映射页文件夹中进行解析了。
下面映射PT结构,需要使用的方法是seL4_X86_PageTable_Map。
在这里插入图片描述
代码如下

//这几个映射方法的参数基本是一样的
error = seL4_X86_PageTable_Map(pt,seL4_CapInitThreadVSpace, TEST_VADDR, seL4_X86_Default_VMAttributes);

可以看到输出发生了变化。
在这里插入图片描述
这个页被成功映射且读到了0值,这是因为当从untyped中retype的时候,seL4会将所有的非设备页置零。然而之后想要尝试写这个页,从代码之中可以看到我们映射页的时候是只读的,所以这个操作未能成功且内核产生了一个VM错误。
因为初始任务没有错误处理器(在线程的教程中会有更多的这方面的信息),这会触发插槽0(nil)上的后续功能故障(cap故障)。因为教程下的内核跑在debug模式,所以内核会输出详细的错误信息。
vm错误是最有趣的,他展示了错误的地址,错误的状态寄存器,以及指令地址。就是下面那句话:

vm fault on data at address 0xa000000000 with status 0x7
in thread 0xffffff801fe08400 "rootserver" at address 0x401b39

Remap a page

通过赋予其seL4_ReadWrite权限重新映射这个页以修复该错误,使用seL4_X86_Page_Map这个函数:
在这里插入图片描述
代码如下:

//先接触映射,再重新映射
error = seL4_X86_Page_Unmap(frame);
assert(error == seL4_NoError);
error = seL4_X86_Page_Map(frame, seL4_CapInitThreadVSpace, TEST_VADDR, seL4_ReadWrite, seL4_X86_Default_VMAtt>
assert(error == seL4_NoError);

这里代码搞完了之后确实输出了Success:
在这里插入图片描述
但是下面还是有报错,没有找到报错的原因。

进一步练习

老规矩。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/150273.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

6种常见位运算符+异或运算符的使用(加密、解密)

一、位运算符 位运算符进行的是整数与整数之间的运算 1、右移运算符&#xff1a;>> &#xff08;1&#xff09;相当于对整数除以2 &#xff08;2&#xff09;举例&#xff1a; int num 2; System.out.println(num >> 1); 2、左移运算符&#xff1a;<< …

opencv-python学习笔记10-图像形态学处理

目录 一、基本概念&#xff1a; &#xff08;1&#xff09;结构元素&#xff08;Structuring Element&#xff09;&#xff1a; &#xff08;2&#xff09;膨胀&#xff08;Dilation&#xff09;&#xff1a; &#xff08;3&#xff09;腐蚀&#xff08;Erosion&#xff0…

巧用解压软件:高效处理云盘文件

百度网盘支持多种文件格式&#xff0c;包括文本文件格式如.txt、.doc、.docx 等&#xff1b;图片文件格式如.jpg、.png 等&#xff1b;音频文件格式如.mp3、.wav 等&#xff1b;视频文件格式如.avi、.mp4 等&#xff1b;压缩文件格式如.zip、.rar、.7z 等&#xff1b;可执行文件…

进度条QProgressBar

进度条控价&#xff0c;用来只是任务的完成情况 值 包括当前值、最大值、最小值 // 获取和设置当前值 int value() const; void setValue(int);// 获取和设置最大值 int maximum() const; void setMaximum(int);// 获取和设置最小值 int minimum() const; void setMinimum(i…

http增删改查四种请求方式操纵数据库

注意&#xff1a;在manage.py项目入口文件中的路由配置里&#xff0c;返回响应的 return语句后面的代码不会执行&#xff0c;所以路由配置中每个模块代码要想都执行&#xff0c;不能出现return 激活虚拟环境&#xff1a;venv(我的虚拟环境名称&#xff09;\Scripts\activate …

【论文翻译】AFLGuard: Byzantine-robust Asynchronous Federated Learning

提示&#xff1a;该论文标题为AFLGuard: Byzantine-robust Asynchronous Federated Learning&#xff0c;我将对其进行部分翻译&#xff0c;便于后续阅读。 文章目录 AFLGuard&#xff1a;拜占庭鲁棒的异步联邦学习一、摘要二、引言三、知识前提拜占庭鲁棒联邦学习 四、问题表述…

排序(插入,希尔,堆排)

常见的排序算法&#xff1a; 插入排序&#xff1a; 直接插入排序&#xff1a;是一种简单的插入排序法&#xff0c;其基本思想是&#xff1a;把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中&#xff0c;直到所有的记录插入完为止&#xff0c;得到一个…

mysql如何替换数据库所有表中某些字段含有的特定值

目录 背景查询所有表名查询表的所有字段过虑特征字段替换字段中含有的特定值 背景 公司的测试域名更换了&#xff0c;导致存放在数据库中的域名也要跟着替换&#xff0c;当然把域名存放在数据库表中是不科学的&#xff0c;不建议这样做&#xff0c;但公司的同事就这样做了&…

AWS开启MFA,提高安全性

引言 多因素认证&#xff08;Multi-Factor Authentication, MFA&#xff09;是一种重要的安全措施&#xff0c;可以显著提高您的AWS账号的安全性。通过启用MFA&#xff0c;即使密码被盗&#xff0c;攻击者也难以访问您的账户。本文中九河云将详细介绍如何在AWS Management Con…

element-plus表格操作

elememt-plus安装见上文 表格的特性 element-plus中的表格和原版表格最大的不同是写法不同&#xff0c;原版表格以行的方式写&#xff0c;element-plus以列的方式写。 element-plus的表格可以更方便的展示数据&#xff0c;只需要考虑数据的格式即可。 表格标签 表格标签有两种…

LeetCode 257. 二叉树的所有路径,dfs

LeetCode 257. 二叉树的所有路径 给定一个二叉树&#xff0c;返回所有从根节点到叶子节点的路径。 说明: 叶子节点是指没有子节点的节点。 目录 LeetCode 257. 二叉树的所有路径算法选择数据结构解题步骤算法流程算法代码算法分析易错点和注意事项相似题目 算法选择 深度优…

Web端云剪辑解决方案,提供多轨视频、音频、特效、字幕轨道可视化编辑

传统视频剪辑软件的繁琐安装、高昂硬件要求以及跨平台协作的局限性&#xff0c;让无数创意者望而却步。美摄科技作为云端视频编辑技术的领航者&#xff0c;携其革命性的Web端云剪辑解决方案&#xff0c;正重新定义视频创作的边界&#xff0c;让专业级视频剪辑触手可及&#xff…

k8s StorageClass 存储类

文章目录 一、概述1、StorageClass 对象定义2、StorageClass YAML 示例 二、StorageClass 字段1、provisioner&#xff08;存储制备器&#xff09;1.1、内置制备器1.2、第三方制备器 2、reclaimPolicy&#xff08;回收策略&#xff09;3、allowVolumeExpansion&#xff08;允许…

多线程:死锁

目录 死锁的条件 死锁的示例 死锁的预防与解决 死锁的检测 总结 死锁&#xff08;Deadlock&#xff09;是多线程或多进程环境中一种特定的状态&#xff0c;指的是两个或多个线程或进程在执行过程中&#xff0c;由于争夺资源而造成的一种相互等待的状态&#xff0c;导致它们…

Linux usb主机控制器HC阅读

intel的UHCI 一种usb主机控制器的接口规范,遵守它的硬件称为UHCI主机控制器,Linux中,把这种硬件叫做HC,host controller,与之对应的软件,叫做HCD,hc driver, depends on usb & pci: 它的内核软件模块代码是uhci-hcd.c uhci_hcd_init初始化开始: usb_disable函数:…

【openwrt】 libubox组件——ustream

文章目录 ustream 核心数据结构struct ustreamstruct ustream_buf_liststruct ustream_bufstruct ustream_fd ustream 核心APIustream_fd_initustream_uloop_cbustream_fd_read_pendingustream_fill_read ustream_write_pendingustream_writeustream_fd_write ustream 应用示例…

前端开发必须了解的css知识

文本过长省略显示 单行 .ellipsis {overflow: hidden;text-overflow: ellipsis;white-space: nowrap; }多行 方法一&#xff1a; .ellipsis {overflow: hidden;text-overflow: ellipsis;-webkit-line-clamp: 3;word-break: break-all; }方法二&#xff1a; .ellipsis {ove…

文献笔记 - Neural Lander: Stable Drone Landing ControlUsing Learned Dynamics

这篇博文是自己看文章顺手做的笔记 只是简单翻译和整理 仅做个人参考学习和分享 如果作者看到觉得内容不妥请联系我 我会及时处理 本人非文章作者&#xff0c;文献的引用格式如下&#xff0c;原文更有价值 [1]Guanya Shi∗,Xichen Shi∗,Michael OConnell∗,et al.Neural La…

LOGO设计新革命:5款AI工具让你秒变设计大师(必藏)

大家好&#xff0c;我是Shelly&#xff0c;一个专注于输出AI工具和科技前沿内容的AI应用教练&#xff0c;体验过300款以上的AI应用工具。关注科技及大模型领域对社会的影响10年。关注我一起驾驭AI工具&#xff0c;拥抱AI时代的到来。 你是否曾因设计一个既独特又专业的LOGO而感…

Tableau|二 如何利用功能区创建视图

一 认识 Tableau 数据 1.数据角色 维度和度量是Tableau的一种数据角色划分&#xff0c;离散和连续是另一种划分方式。 1.维度和度量 维度往往是一些分类、时间方面的定性字段&#xff0c;将其拖放到功能区时&#xff0c;Tableau不会对其进行计算&#xff0c;而是对视图区进行分…