1,Capability 功能权限
capability is a unique, unforgeable token that gives the possessor permission to access an entity or object in system。这种能力的定义是:他是具有唯一和真实特性的令牌,他给予处理器控制实体或者对象的权利。
2,There are three kinds of capabilities in seL4:具体来说他有三种功能。
a , capabilities that control access to kernel objects such as thread control blocks,一种功能就像线程控制块一样访问内核对象。
b, capabilities that control access to abstract resources such as IRQControl, 另一种功能就像IRQControl一样访问抽象资源
c, untyped capabilities, that are responsible for memory ranges and allocation from those (see also the Untyped tutorial). 不知道说的是啥。。。。
3,seL4系统中在初始化的时内核赋予了跟任务root task访问所有资源的能力。用户代码可以调用kernel API(libsel4中可以请求一个特定的功能来对资源的操作)来改变资源的状态。比如可以通过TCB API methods去改变跟任务(Root task)自己的进程控制块(seL4_CapInitThreadTCB)的属性。
下面一段常见的代码,通过修改跟任务的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, ®isters);
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, ®isters);
assert(error == seL4_NoError);
seL4_TCB_ReadRegisters 和seL4_TCB_WriteRegisters 的第一个参数通过slot 赋予该函数访问权限。下面章节来解释通过slot赋予访问权限。
4,CNodes and CSlots 功能权限集合和功能权限的槽或者钩子
CNode是一个对象的全部功能权限的集合,功能权限形成的一组个叫 一个CNode.
在上面的例子的函数调用中,seL4_CapInitThreadTCB就是可以访问跟任务TCB的跟任务的CNode的一个slot。
在CNode中的Cslot有两种状态:
a, 空闲: 这个CNode的 slot 没有任何功能权限。
b, 工作:the slot 具有访问内核资源的功能权限。
通常来看 第0个Cslot 会保持空闲状态。为了处理非预期的错误的slots ,第0个slot保持空闲,不会被映射到处理器的虚拟空间。
The field info->CNodeSizeBits gives a measure of the size of the initial CNode: it will have 1 << CNodeSizeBits CSlots. A CSlot has 1 << seL4_SlotBits bytes, so the size of a CNode in bytes is 1 << (CNodeSizeBits + seL4_SlotBits.
5,CSpaces 访问线程的一系列功能权限,由一个和多个CNodes 组成。
通过seL4 API 有两种方式可以部署capability。
一种是应用,另一种是直接寻址。 应用简单,在编辑跟任务TCB寄存器的时候就用的这种方式。后面会详细的解释。
a, Invocation 引用:
每一个线程的TCB都包含一个特殊的CNode 作为CSpace root. 这个root可以是空的,比如当这个线程没有去掉用任何功能权限时,或者也可以是表征 CNode中的功能权限。跟任务一定会有CNode就是CSpace root。
引用是隐式调用,通过线程的CSpace root来实施调用寻址。
seL4_TCB_WriteRegisters(seL4_CapInitThreadTCB, 0, 0, num_registers, ®isters);
在这段代码中,引用了一个具有特殊功能权限的Cslot (seL4_CapInitThreadTCB) 去读取或者写入TCB寄存器. 该例中隐式查找CNode 中的seL4_CapInitThreadTCB CSlot是通过 跟任务的CSpace root的功能权限指向实现的。
6,Direct CSpace addressing
与调用寻址不同,直接寻址允许我们指定CNODE查找,而不再是引用CSpace root再指向CNODE查找。这种新式的寻址方式,通常用于组成和使用类似的CSpaces(比如,可能在另一线程中的CSpace)。值得注意的是,直接寻址也会请求调用,这个可能发生在调用 CNode capability的时候,这个CNode是由CSpace root的索引得来。
直接寻址Cslots会涉及到的内容如下:
a,_service/root -CNode 的一个功能权限会被操作
b,index -寻址CNode 中Cslot的索引
c,depth-解析CSlot需要遍历CNode的层级
下面有一个例子,通过直接寻址方式复制了 root task’s TCB (在CSpace root的第0个slot)。CNode copy 过程会直接寻址两个Cslots,目标Cslot 和 源Cslot。seL4_CapInitThreadCNode 在这里承担三种职责:as source root, as destination root, and as source slot,因为我们是在一个CNode(初始化线程的CNode)内部执行copy动作,所以他既是source root 又是destination root。本例是要将初始化线程的seL4_CapInitThreadCNode(一个功能权限的slot)拷贝到slot 0.
seL4_Error error = seL4_CNode_Copy(
seL4_CapInitThreadCNode, 0, seL4_WordBits, // destination root, slot, and depth
seL4_CapInitThreadCNode, seL4_CapInitThreadTCB, seL4_WordBits, // source root, slot, and depth
seL4_AllRights);
assert(error == seL4_NoError);
7,Initial CSpace 初始化CSpace
sel4内核在系统启动的时赋予了root task的CSpace 具有管理所有资源权限。上面的例子已经展示了root CSpace的几个功能权限,比如:seL4_CapInitThreadTCB, and seL4_CapInitThreadCNode.这两个都是在libsel4 里面定义的常量,但是并不是所有的初始功能权限都是这样静态定义的。有些功能权限在seL4_BootInfo的数据结构体中,在libsel4描述,由sel4初始化。seL4_BootInfo 中的初始功能权限包括,使能初始CSpace的空闲 slots。
版权声明:内容来源于互联网和用户投稿 如有侵权请联系删除