seL4 Mapping(三)

news2024/11/15 19:25:21

官网链接: 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.coloradmin.cn/o/2161362.html

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

相关文章

Python图表显示添加中文

import re import numpy as np import matplotlib.pyplot as plt from matplotlib.font_manager import FontProperties# 动态加载字体文件 font_path /usr/local/sunlogin/res/font/wqy-zenhei.ttc # 替换为实际字体路径 my_font FontProperties(fnamefont_path)# 定义日志…

Go语言基础学习01-Liunx下Go开发环境配置;源码组织方式;go build/install/get详解

目录 Linux环境下配置安装VScode并配置Go语言开发环境Go语言源码的组织方式Go语言源码安装后的结果Go程序构建和安装的过程go build扩展go get 命令详解 之前学习过Go语言&#xff0c;学习的时候没有记录笔记&#xff0c;最近找了个极客时间的Go语言36讲&#xff0c;打算时间学…

影响RPA流程稳定运行的若干因素|实在RPA研究

RPA发展现状 当前&#xff0c;中国正处于实现高质量发展、数字化转型升级的关键时期。RPA作为数字化转型的一项重要工具&#xff0c;已经开始在许多领域发挥积极作用。 RPA&#xff08;Robotic Process Automation 机器人流程自动化&#xff09;是一种通过软件机器人自动执行…

stm32 keil有一些别人的工程在你这打开为什么会乱码?如何解决的

因为别人编辑代码使用的编辑器和你的不一样&#xff0c;要更正可以调一下自己的翻译器编码格式 也可以直接换掉文件的格式&#xff0c; 用记事本打开文件&#xff0c;然后点会另存为&#xff0c;下面有个编码格式选择&#xff0c;换成你自己的就行

Neko一个在Docker环境下的虚拟浏览器

Neko是一个在 Docker 中运行并使用 WebRTC 技术的自托管虚拟浏览器。Neko 是一个强大的工具&#xff0c;可让您在虚拟环境中运行功能齐全的浏览器&#xff0c;使您能够从任何地方安全、私密地访问互联网。使用 Neko&#xff0c;您可以像在常规浏览器上一样浏览 Web、运行应用程…

Python接口测试实践—参数化测试、数据驱动测试和断言的使用

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 在Python接口测试实践中&#xff0c;参数化测试、数据驱动测试和断言是常用的技术手段。 参数化测试 参数化测试是指将测试用例中的某些部分&#xff08;如输入数…

蓝桥杯算法之暴力

暴力 1.十进制数转换成罗马数字 2.判断给出的罗马数字是否正确 小知识 %&#xff08;模除&#xff09;&#xff1a; % 符号用作模除&#xff08;或取模&#xff09;运算符。模除运算是一种数学运算&#xff0c;它返回两个数相除的余数。 具体来说&#xff0c;如果 a 和 b 是…

初识 C++ ( 1 )

引言&#xff1a;大家都说c是c的升级语言。我不懂这句话的含义后来看过解释才懂。 一、面向过程语言和面向对象语言 我们都知道C语言是面向过程语言&#xff0c;而C是面向对象语言&#xff0c;说C和C的区别&#xff0c;也就是在比较面向过程和面向对象的区别。 1.面向过程和面向…

自然语言处理实战项目:从理论到实现

一、引言 自然语言处理&#xff08;NLP&#xff09;是计算机科学、人工智能和语言学交叉的领域&#xff0c;旨在让计算机能够理解、处理和生成人类语言。随着互联网的飞速发展&#xff0c;大量的文本数据被产生&#xff0c;这为自然语言处理技术的发展提供了丰富的素材&#xf…

【动态规划】(五)动态规划——子序列问题

动态规划——子序列问题 子序列问题☆ 最长递增子序列&#xff08;离散&#xff09;最长连续递增序列&#xff08;连续&#xff09;最大子序和&#xff08;连续&#xff09;最长重复子数组&#xff08;连续&#xff09;☆ 最长公共子序列&#xff08;离散-编辑距离过渡&#xf…

【驱动】修改USB转串口设备的属性,如:Serial

1、查看串口信息 在Windows上,设备管理窗口中查看设备号 2、修改串口号工具 例如使用:CH34xSerCfg.exe 使用步骤:恢复默认值 - -> 修改 Serial String(或者Product String等属性)–> 写入配置 3、查看设备节点 在linux上使用lsub查看新增的设备信息,如下这个…

python多线程开发的具体示例

用一个具体的示例&#xff0c;展示如何使用 ThreadPoolExecutor 和 asyncio 来并行运行多个任务&#xff0c;并输出结果。 代码&#xff1a; import asyncio import time from concurrent.futures import ThreadPoolExecutorclass WorkJob:def __init__(self, job_id):self.j…

报表做着太费劲?为你介绍四款好用的免费报表工具

1. 山海鲸可视化 介绍&#xff1a; 山海鲸可视化是一款免费的国产可视化报表软件&#xff0c;与许多其他宣传免费的软件不同&#xff0c;山海鲸的报表功能完全免费并且没有任何限制&#xff0c;就连网站管理后台这个功能也是免费的。同时山海鲸可视化还提供了种类丰富的可视化…

11.安卓逆向-安卓开发基础-api服务接口设计2

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a;图灵Python学院 本人写的内容纯属胡编乱造&#xff0c;全都是合成造假&#xff0c;仅仅只是为了娱乐&#xff0c;请不要盲目相信。 工…

云手机推荐:五款热门云手机测评!

在云手机市场中&#xff0c;各个品牌层出不穷&#xff0c;让人难以选择。为了帮助你更好地找到适合的云手机应用&#xff0c;我们整理了五款最受欢迎的云手机进行测评。2024年&#xff0c;哪款云手机是你的不二之选&#xff1f;且慢下结论&#xff0c;看看这五款云手机的真实表…

【深度学习】深度卷积神经网络(AlexNet)

在 LeNet 提出后&#xff0c;卷积神经网络在计算机视觉和机器学习领域中很有名气&#xff0c;但并未起到主导作用。 这是因为 LeNet 在更大、更真实的数据集上训练的性能和可行性还有待研究。 事实上&#xff0c;在 20 世纪 90 年代到 2012 年之间的大部分时间里&#xff0c;…

Windows系统的Tomcat日志路径配置

文章目录 引言I Windows系统的Tomcat日志路径配置配置常规日志路径访问日志路径配置,修改server.xmlII 日志文件切割:以分隔割tomcat 的 catalina.out 文件为例子通过Linux系统自带的切割工具logrotate来进行切割引言 需求:C盘空间不足,处理日志文件,tomcat日志迁移到D盘…

中国科学院云南天文台博士招生目录

中国科学院云南天文台是专业基础研究与应用研究结合的综合性天文研究机构&#xff08;其前身是1938年中央研究院天文研究所在昆明东郊凤凰山创建的凤凰山天文台&#xff09;&#xff0c;总部在云南省昆明市&#xff0c;设有两个观测站&#xff08;丽江高美古天文观测站和澄江抚…

Boruta 的库的初识

我在一个kaggle比赛时间预测中发现Boruta我并不熟悉与是我学习了一下 Boruta 的工作原理&#xff1a; 影子特征&#xff08;Shadow Features&#xff09;: Boruta 首先创建一组影子特征&#xff0c;这些影子特征是通过随机打乱原始特征的值生成的。影子特征的目的是作为对照组…

【完结】【PCL实现点云分割】ROS深度相机实践指南(下):pcl::BoundaryEstimation实现3D点云轮廓检测的原理(论文解读)和代码实现

前言 本教程使用PCL对ROS深度相机捕获到的画面进行操场上锥桶的分割 上:[csdn 博客] 【PCL实现点云分割】ROS深度相机实践指南&#xff08;上&#xff09;:PCL库初识和ROS-PCL数据类型转换中:[csdn 博客] 【PCL实现点云分割】ROS深度相机实践指南&#xff08;中&#xff09;:Pl…