seL4 Capabilities(翻自官网)(一)

官网教程链接: Capability

初始化Capabilities tutorials

// 先使用repo拉取一下tutorials,然后执行repo sync,所有的教程都在里面,学习某个的时候只需要改变的是 --tut 后面的参数
./init --tut capabilities
# building the tutorial exercise
cd capabilities_build
ninja

什么是Capability?

简单的讲是一个访问系统中实体或者对象的凭证(token),可以将其简单理解为是一个访问权限的指针,再seL4中有三种capabilities。

  • 控制访问内核对象的,例如TCB(thread control blocks)
  • 控制访问抽象资源的,例如IRQControl(Interrupt Requests, IRQ)
  • 未分类能力

seL4中,初始化时,由内核控制的资源的能力赋予给根任务。若用户代码想要改变任何资源的状态,则可以使用内核API,可在libsel4中请求对特定能力指向的资源进行操作。
举例而言,根任务初始化的时候会携带一个指向它自己线程控制块(TCB)的能力,也即是 seL4_CapInitThreadTCB,其是一个由libsel4定义的常量。若想改变初始TCB的属性,则可以在该能力上使用TCB API中的任何方法。
下面是一个更改根任务TCB栈指针的例子,如果需要一个更大的栈则需要以下的操作:

// 这两行不懂,先扔这吧
seL4_UserContext registers;
seL4_Word num_registers = sizeof(seL4_UserContext)/sizeof(seL4_Word);/* Read the registers of the TCB that the capability in seL4_CapInitThreadTCB grants access to. */
seL4_Error error = seL4_TCB_ReadRegisters(seL4_CapInitThreadTCB, 0, 0, num_registers, &registers);
assert(error == seL4_NoError);/* set new register values */
registers.sp = new_sp; // the new stack pointer, derived by prior code./* Write new values */
error = seL4_TCB_WriteRegisters(seL4_CapInitThreadTCB, 0, 0, num_registers, &registers);
assert(error == seL4_NoError);

seL4_TCB_ReadRegisters和seL4_TCB_WriteRegisters的第一个参数指向seL4_CapInitThreadTCB插槽中的能力(capability)的地址。之后会解释地址(address)和插槽(slots)。剩余的参数是此次调用中特定的,进一步的解释可以查API。

CNodes和CSlots

一个CNode是一个装满能力的对象,可以将其理解为一个能力数组。将插槽(slot)称为功能插槽(capability-slots)。在上面的例子中,seL4_CapInitThreadTCB是根任务的CNode的插槽,该CNode包含着根任务TCB的能力。每个CNode中的插槽可能有如下状态:

  • empty:插槽中没有能力
  • full:包含一个指向内核资源的能力

按照惯例(by convention),0号插槽一般是空的,类似于在进程虚拟地址空间中将NULL标识未分配或者无效的内存位置一样,是为了避免在不小心使用未初始化的槽位时出现错误。
info->CNodeSizeBits字段给出了初始CNode大小的度量:它将会有1<<CNodeSizeBits个插槽(2CNodeSizeBits)。一个插槽有1<<seL4_SlotBits(2seL4_SlotBits)个字节,所以一个CNode的大小未2CNodeSizeBits+seL4_SlotBits个字节。

CSpace

CSpace指的是能力空间,也就是一个线程中所有可访问的能力,可能是由一个或者多个CNodes组成的。在这一篇教程中,我们主要集中于由seL4的初始化协议为根任务构建的能力空间,是由一个CNode组成的。

CSpace addressing

为了引用一个能力且利用其执行操作,你必须要对其进行定位。在seL4 API中有两种方式对能力进行寻址。首先是通过调用,其次是通过直接寻址。调用是一种简写,我们用它来操作根任务TCB的寄存器(registers),下面是对其的进一步解释。

Invocation 调用

每个线程在其TCB中都有一个特殊的CNode能力,该能力作为其能力空间的根。这个根可以是空的(不包含任何能力),例如这个线程没有被授权调用任何能力,或者这个根节点也可以指向一个CNode,线程就可以使用其指向的那个CNode中的能力,这样该线程就可以在他的CSpace中管理和使用其他能力。
在一次invocation中,是通过隐式的调用执行该调用的线程的能力空间根来寻址能力插槽的。在上面的例子中,我们使用seL4_CapInitThreadTCB CSlot的调用,来读取和写入由该特定CSlot中的能力所表示的TCB(线程控制块)的寄存器。

seL4_TCB_WriteRegisters(seL4_CapInitThreadTCB, 0, 0, num_registers, &registers);

这会隐式的查询“调用线程能力空间根能力指向的CNode”(真他妈拗口)中的seL4_CapInitThreadTCB CSlot,这里指的就是根任务。
在某些情况下,当上下文足够清晰且其他信息不重要时,我们有时会用能力(capability)来代指它所指向的对象。比如,代替说“由 CSpace 根能力指向的 CNode”,我们有时会直接说“CSpace 根(其实是个能力)”。但如果不确定,最好还是保持精确。就像 C 语言中的结构体(structs)和指针(pointers)一样,对象(object)和能力(capabilities)并不是完全可互换的:一个对象可以被多个能力指向,而这些能力可能对该对象具有不同的权限级别。

能力空间直接寻址

对比起调用寻址,直接寻址允许你指定CNode进行查找能力,而不是隐式的使用能力空间根。这种方式主要用于构造和操作CSpaces的结构——可能是其他线程的CSpace。需要注意的式直接寻址也需要调用:这个操作需要调用一个CNode能力,而这个能力本身是从CSpace root索引的(搁着套娃呢)。
当对插槽进行直接寻址的时候,以下字段会被用到:

  • _service/root CNode操作的能力
  • index CNode地址中插槽的索引
  • depth 在解析出CSlot之前要遍历CNode多远

对于初始的,单一级别的能力空间,depth的值总是seL4_WordBits。对于调用而言,depth默认的就是seL4_WordBits。为了将会对该值进行更多的讨论。
在下面的例子中,我们直接寻址根任务的TCB然后将其进行复制到能力空间根中的0号插槽位置(其实是将一个指向TCB的能力复制到另外一个插槽中去)。CNode复制需要两个直接寻址的插槽,为什么称为CNode复制而不叫slot复制呢?因为在进行能力复制的时候实际上实在CNode中操作能力槽,而且slot只是CNode中的一个元素,用于存储能力。复制能力的过程不仅仅是复制槽内容,而是需要操作整个CNode中的多个槽来完成复制,所以称为CNode复制更为合适。需要寻址的两个插槽,一个是目标插槽,另外一个是源插槽。seL4_CapInitThreadCNode的三种角色:

  1. 源根(source root):seL4_CapInitThreadCNode被用作源根,因为我们在同一个CNode中进行复制——即初始线程的CNode
  2. 目标根(destination root),seL4_CapInitThreadCNode也被用作目标根,复制操作发生在同一个CNode内部
  3. 源插槽(source slot),seL4_CapInitThreadCNode 被用作源插槽,因为在初始线程的 CNode 内,seL4_CapInitThreadCNode 是我们想要复制的能力所在的插槽(而 0号插槽是目标)。
 seL4_Error error = seL4_CNode_Copy(seL4_CapInitThreadCNode, 0, seL4_WordBits, // destination root, slot, and depthseL4_CapInitThreadCNode, seL4_CapInitThreadTCB, seL4_WordBits, // source root, slot, and depthseL4_AllRights);
assert(error == seL4_NoError);

所有的CNode调用都需要直接能力空间寻址。

初始化能力空间

根任务的能力空间是由seL4在启动时设置的,包含了由seL4管理的所有资源能力。我们已经看到了在根能力空间的几个能力:seL4_CapInitThreadTCB以及seL4_CapInitThreadCNode。这些都是在libsel4中由常量指定的,但是并不是所有的初始能力都是静态指定的。其他能力由libsel4中的seL4_BootInfo数据结构进行解释,由seL4进行初始化。seL4_BootInfo描述了初始能力的范围,包括了初始能力空间中的可用的插槽。

实操

zjx@in-container:/host$ ./init --tut capabilities

执行成功后是这样的
在这里插入图片描述
看一眼capabilities教程的源码
capabilities的源码

//使用qemu仿真硬件,./simulate进行执行,执行结果如下所示
./simulate

在这里插入图片描述
可以看到其中的主要内容是:

Booting all finished, dropped to user space
Initial CNode is 65536 slots in size
The CNode is 0 bytes in size
<<seL4(CPU 0) [decodeInvocation/646 T0xffffff801fe08400 "rootserver" @4013be]: Attempted to invoke a null cap #65535.>>
main@main.c:31 [Cond failed: error]Failed to set priority

运行时所有的输出都是有意义的。但是现在而言,第一行的输出信息来自内核,第二行的输出信息告诉你初始化CNode有多少个插槽。第三行则阐述了CSpace空间的大小,但是可以看出第三行的输出是错误的,现在的首要任务是将其改为对的。
从源码中可以看到:

 size_t initial_cnode_object_size_bytes = 0; // TODO calculate this.printf("The CNode is %zu bytes in size\n", initial_cnode_object_size_bytes);

根据上面理论上的内容来看,想要计算出CSpace(即此处的一个CNode的大小)还需要知道一个值,也就是seL4_SlotBits,也就是插槽的size_bits,根据下表可以看出,针对某一个对象的大小有两种表达方式Size in Bytes = 2size_bits,为此查询了seL4的手册,发现如下表:
在这里插入图片描述
而我的qemu仿真的是x86-64,因此此处的seL4_SlotBits的值位5,每个插槽也就占了25个字节,因此可以将上面的程序更改如下:

#define seL4_SlotBits 5size_t initial_cnode_object_size_bytes = BIT(info->initThreadCNodeSizeBits + seL4_SlotBits); // TODO calculate this.printf("The CNode is %zu bytes in size\n", initial_cnode_object_size_bytes);

修改之后可以看到输出:
在这里插入图片描述
这里看到,下面的输出有一个报错,“尝试调用了一个空能力,可以看到是未能设置优先级”,修改代码如下所示:

seL4_CPtr last_slot = info->empty.end - 1;/* TODO use seL4_CNode_Copy to make another copy of the initial TCB capability to the last slot in the CSpace */error = seL4_CNode_Copy(seL4_CapInitThreadCNode, last_slot, seL4_WordBits, seL4_CapInitThreadCNode, seL4_CapInitThreadTCB, seL4_WordBits,seL4_AllRights);ZF_LOGF_IF(error, "Failed to copy cap!");/* set the priority of the root task */error = seL4_TCB_SetPriority(last_slot, last_slot, 10);ZF_LOGF_IF(error, "Failed to set priority");

这里有一些需要说明的点,info这个指针指向的对象里面到底都有什么?如下图所示
在这里插入图片描述
可以看到里面empty字段,字段类型是seL4_SlotRegion,在文档的上方找到了对该字段的说明,该类型是一个C结构体,该结构体包含了两个这指针,即start和end。它标示着初始线程CNode插槽的区域,start指向第一个插槽,而end指向最后一个插槽的下一个位置,因此end-1指向的是这片插槽中的最后一个位置。
在代码中,经常能够看到一些突兀的的量,例如seL4_CapInitThreadCNode,seL4_CapInitThreadTCB,这些东西都没定义,从何而来?
在这里插入图片描述
可以是在初始线程的CSpace中包含的,前15个槽(如果没有MSC的是14个槽)包含了如上表指定的特定的能力。
在修改了上述代码之后,再次编译运行可以看到如下的输出:
在这里插入图片描述
从main.c中继续寻找TODO:

 // TODO delete the created TCB capabilities// check first_free_slot is empty
error = seL4_CNode_Move(seL4_CapInitThreadCNode, first_free_slot, seL4_WordBits,seL4_CapInitThreadCNode, first_free_slot, seL4_WordBits);
ZF_LOGF_IF(error != seL4_FailedLookup, "first_free_slot is not empty");// check last_slot is empty
error = seL4_CNode_Move(seL4_CapInitThreadCNode, last_slot, seL4_WordBits,seL4_CapInitThreadCNode, last_slot, seL4_WordBits);
ZF_LOGF_IF(error != seL4_FailedLookup, "last_slot is not empty");

可以看到,这里要求我们做到是删除创建的能力。

如何删除能力?

上面的代码检查first_free_slot和last_slot是不是空的,结果当然不是空的,因为你复制了TCB能力到这些槽里面去。检查一个能力槽是不是空的方法很巧妙:尝试移动能力槽中的能力到他们自身。如果源槽是空的则该操作应以一个错误码seL4_FailedLookup而结束,如果不是空的则是错误码seL4_DeleteFirst。
有两种可以删除能力的方法:

  • 在复制的能力上使用seL4_CNode_Delete删除
  • 在原生的能力上使用seL4_CNode_Revoke进行能力回收,回收所有复制的能力

下面查一下这两个方法:

在这里插入图片描述
seL4_CPtr 是一个无符号整数类型,表示能力指针(capability pointer),它实际上是能力槽的索引。也就是说,first_free_slot 本身就是一个索引,指向 CSpace 中的某个能力槽。这里的深度指的是传入后进行解析的时候的解析位数,例如传入的index为10101100,那么深度为1的时候就解析一位,即最高位1,当深度4的时候解析前四位,即1010,也就是十进制10,以此类推,所以深度是一个必不可少且非常重要的值,因此first_free_slot是第二个参数。

error = seL4_CNode_Revoke(seL4_CapInitThreadCNode, seL4_CapInitThreadTCB,seL4_WordBits);//或者使用Delete
error = seL4_CNode_Delete(seL4_CapInitThreadCNode, first_free_slot, seL4_WordBits);
ZF_LOGF_IF(error,"Failed to delete slot");error = seL4_CNode_Delete(seL4_CapInitThreadCNode, last_slot, seL4_WordBits);
ZF_LOGF_IF(error,"Failed to delete slot");

主要是深度无法确定,在输出的初始化CNode插槽数量的时候可以看到,输出是65536,也就是2的16次方,我以为深度是16,但是传入16不对,错误信息是非法槽,所以应该是深度错了,解析的时候有问题。再看到复制能力的时候,也需要传入深度,程序中传入的深度是seL4_WordBits,将这个值输出后发现是64,是再64位的机器上,所以插槽的索引也是64位的,但是插槽数量只有216个,所以就是有多余的用不上的,因此深度应是64,实际有用的只有低16位,但是默认解析是从高位解析的。
输出为:
在这里插入图片描述

调用能力

在这里插入图片描述
可以看到最后一个TODO是调用能力挂起当前线程,可以使用seL4_TCB_Suspend这个方法尝试挂起当前线程。先查到该方法:

在这里插入图片描述
这个简单,代码如下

seL4_TCB_Suspend(seL4_CapInitThreadTCB);

传入的是对线程TCB操作的能力。输出如下:
在这里插入图片描述
还有进一步的训练,啥时候想起来再做吧。

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

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

相关文章

国内可以使用的ChatGPT服务【9月持续更新】

首先基础知识还是要介绍得~ 一、模型知识&#xff1a; GPT-4o&#xff1a;最新的版本模型&#xff0c;支持视觉等多模态&#xff0c;OpenAI 文档中已经更新了 GPT-4o 的介绍&#xff1a;128k 上下文&#xff0c;训练截止 2023 年 10 月&#xff08;作为对比&#xff0c;GPT-4…

演示:基于WPF的DrawingVisual开发的Chart图表和表格绘制

一、目的&#xff1a;基于WPF的DrawingVisual开发的Chart图表和表格绘制 二、预览 钻井井轨迹表格数据演示示例&#xff08;应用Table布局&#xff0c;模拟井轨迹深度的绘制&#xff09; 饼图表格数据演示示例&#xff08;应用Table布局&#xff0c;模拟多个饼状图组合显示&am…

git使用“保姆级”教程2——初始化及工作机制解释

1、设置用户签名 解释&#xff1a; 签名的作用就是用来&#xff1a;标识用户&#xff0c;以区分不同的开发人员简单来说&#xff1a;用来标识"你是谁"&#xff0c;在提交代码时&#xff0c;会显示提交代码的是谁&#xff0c;把设置的信息一起提交上去 设置&#xff…

weblogic CVE-2019-2725 靶场攻略

漏洞描述 wls9-async等组件为WebLogic Server提供异步通讯服务&#xff0c;默认应⽤于WebLogic部分版本。由于该 WAR包在反序列化处理输⼊信息时存在缺陷&#xff0c;攻击者通过发送精⼼构造的恶意 HTTP 请求&#xff0c;即可获得⽬标服务器的权限&#xff0c;在未授权的情况…

4.使用 VSCode 过程中的英语积累 - View 菜单(每一次重点积累 5 个单词)

前言 学习可以不局限于传统的书籍和课堂&#xff0c;各种生活的元素也都可以做为我们的学习对象&#xff0c;本文将利用 VSCode 页面上的各种英文元素来做英语的积累&#xff0c;如此做有 3 大利 这些软件在我们工作中是时时刻刻接触的&#xff0c;借此做英语积累再合适不过&a…

Codeforces Round 973 (Div. 2) F1. Game in Tree (Easy Version)(思维题 博弈)

题目 思路来源 乱搞ac 题解 两个人的策略是一样的&#xff0c;把1到u的路径标记&#xff0c; 如果能走旁边的链&#xff08;也就是当前点&#xff0c;刨去标记链以外的子树中最长的链&#xff09;&#xff0c; 使得对面走剩余的连通块无法比你大&#xff0c;就走旁边的链&…

【计算机网络】网络层协议解析

网络层的两种服务IPv4分类编址划分子网无分类地址 IPv4地址应用IP数据报的发送和转发过程主机发送IP数据报路由器转发IP数据报 IPv4数据报首部格式ICMP网际控制报文协议虚拟专用网VPN与网络地址转换NAT 网络层主要任务是实现网络互连&#xff0c;进而实现数据包在各网络之间的传…

充电桩项目:前端实现

上次基于VueElement plus实现了充电桩项目后台管理系统的基本架子。 后端管理 员工管理 这次&#xff0c;又把用户端的基本架子搭建完毕&#xff1a;VueVant 首页 个人中心 充值 选择充值方式 优惠券中心 已过期优惠券 用户登录 用户注册 慢慢项目就有点样子了&#xff0c;代码…

远程桌面连接工具Microsoft Remote Desktop Beta for Mac

Microsoft Remote Desktop Beta for Mac 是一款功能强大的远程桌面连接工具&#xff0c;具有以下功能特点&#xff1a; 软件下载地址 跨平台连接&#xff1a; 允许 Mac 用户轻松连接到运行 Windows 操作系统的计算机&#xff0c;打破了操作系统的界限&#xff0c;无论这些 Wi…

Shiro-550—漏洞分析(CVE-2016-4437)

文章目录 漏洞原理源码分析加密过程解密过程 漏洞复现 漏洞原理 Shiro-550(CVE-2016-4437)反序列化漏洞 在调试cookie加密过程的时候发现开发者将AES用来加密的密钥硬编码了&#xff0c;并且所以导致我们拿到密钥后可以精心构造恶意payload替换cookie&#xff0c;然后让后台最…

基于无人机影像的可见光单木分割数据集-json格式

基于无人机影像的可见光单木分割数据集&#xff0c;共1700张影像&#xff0c;数据集大小3.6GB&#xff0c;分割标注采用标准json格式。 该数据集是一个专门用于基于无人机可见光影像进行单木分割的数据集&#xff0c;旨在帮助研究人员和开发者训练和评估基于深度学习的图像分割…

EndNoteX9快捷插入引用文献的教程以及出现的一些问题的解决方法(一)

使用EndNote向Word文档中插入引用文献时报错如图1所示&#xff1a; 解决方法为&#xff1a; 采用管理员身份运行Word与EndNote软件 当电脑中安装好Word与EndNote两款软件之后如何在Word中快速插入引用文献 &#xff08;一&#xff09;直接打开Word如图2&#xff0c;3&#x…

VisionPro - 基础 - 00 模板匹配技术和在VP中的使用 - PMAlign - PatMax - (3)

前言&#xff1a; 针对PatMax 的高级应用和原理&#xff0c;在这一节继续进行说明&#xff1a;这一节主要考虑的是PatMax模板匹配的原理&#xff1a; How PatMax Finds Patterns in an Image PatMax 模板匹配原理 1 Run-time Space When you search for a PatMax pattern in …

生信初学者教程(五):R语言基础

文章目录 数据类型整型逻辑型字符型日期型数值型复杂数数据结构向量矩阵数组列表因子数据框ts特殊值缺失值 (NA)无穷大 (Inf)非数字 (NaN)安装R包学习材料R语言是一种用于统计计算和图形展示的编程语言和软件环境,广泛应用于数据分析、统计建模和数据可视化。1991年:R语言的最…

DOCKER 数据库管理软件自己开发--———未来之窗行业应用跨平台架构

- 数据异地容灾服务--未来之窗智慧数据服务 DATA REMOTE DISASTER RECOVERY SERVICE -CyberWin Future Docker-数据查看 CyberWin DATA Viewer 1.docker 样式 mysqli://root:密码172.17.0.2:端口/数据库 阿雪技术观 拥抱开源与共享&#xff0c;见证科技进步奇迹&#xff0c;…

25届计算机专业毕设选题推荐-基于python+Django协调过滤的新闻推荐系统

&#x1f496;&#x1f525;作者主页&#xff1a;毕设木哥 精彩专栏推荐订阅&#xff1a;在 下方专栏&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; 实战项目 文章目录 实战项目 一、基于协调过滤的新闻推荐系统…

MySQL的登陆错误:ERROR 1049 (42000): Unknown database ‘root‘

MySQL的登陆错误&#xff1a;ERROR 1049 (42000): Unknown database ‘root’ 安装MySQL的时候&#xff0c;到网上查的命令行登陆MySQL的方法都是mysql -u root -p password mysql -r root -p 123456但是奇怪的是这条命令我输进去死活都不对&#xff0c;它都会要求再输入一遍…

how can I train a OpenAI fine tuned model with more prompts

题意&#xff1a;我如何使用更多提示来训练一个 OpenAI 微调模型&#xff1f; 问题背景&#xff1a; I fine-tuned OpenAI model with some prompts following this documentation it succeeded and created a new model in the playground. How I can retrain (fine-tune) th…

如何通过蜂巢(容器安全)管理内部部署数据安全产品与云数据安全产品?

本文将探讨内部部署和云数据安全产品之间的主要区别。在思考这个问题之前&#xff0c;首先了解内部部署和云数据安全产品之间的主要区别。 内部部署数据安全产品意味着管理控制台位于企业客户的内部部署&#xff0c;而德迅云安全则在云中托管云数据安全产品。德迅云安全供应商通…

灵当CRM系统index.php存在SQL注入漏洞

文章目录 免责申明漏洞描述搜索语法漏洞复现nuclei修复建议 免责申明 本文章仅供学习与交流&#xff0c;请勿用于非法用途&#xff0c;均由使用者本人负责&#xff0c;文章作者不为此承担任何责任 漏洞描述 灵当CRM系统是一款功能全面、易于使用的客户关系管理&#xff08;C…