seL4微内核操作系统初期总结 2018.10

 [email protected]衷心感谢您的拜读,希望我的分析对您有所帮助;另外,若您发现本文分析错误,或seL4版本更新特性变化,您可以发邮件告诉我,以便我能及时更新。考虑到关于信息量较多,在阅读过程中难免出现语义难明的词汇,对于前文出现的所有非公共词汇,后文均会明确其含义,请耐心阅读。

seL4综述——可能是一个以权限控制为基础的微内核

——————————seL4相关理念——————————

1. 由于seL4官方文档未区分Thread和Process,因此下文表述均采用线程

2. 关于权限,seL4描述为能力,明确的抽象出3大基本元素:

Read、Write、Grant(权限授予,即传递)。

#define seL4_ReadWrite seL4_CapRights_new(0, 1, 1)

#define seL4_AllRights seL4_CapRights_new(1, 1, 1)

#define seL4_CanRead   seL4_CapRights_new(0, 1, 0)

#define seL4_CanWrite  seL4_CapRights_new(0, 0, 1)

#define seL4_CanGrant  seL4_CapRights_new(1, 0, 0)

#define seL4_NoWrite   seL4_CapRights_new(1, 1, 0)

#define seL4_NoRead    seL4_CapRights_new(1, 0, 1)

#define seL4_NoRights  seL4_CapRights_new(0, 0, 0)

3. 显式的权限控制

seL4的权限控制是显式的,seL4的一切操作

(下文提到的seL4提供的基础服务)

都要在CSpace存在相关权限的情况下才能执行

4. 权限:Grant

seL4的权限以CNode为单位可被复制、转移。

由于权限的可复制即可产生子权限,因此可以形成权限树。

CSpace即据此组织CNode,形成有向图。

5. 线程的VSpace和CSpace

线程的创建会建立VSpace和CSpace,VSpace即虚拟地址空间;

CSpace为Capability Space,

为seL4内核的Capability全面控制提供基础

6. 线程的IPC Buffer

存在于其他线程通讯、与内核通讯需要的线程,

在创建时即加入IPC Buffer,为后期IPC的基础,

为设置IPC Buffer的线程不能对外通讯。

7. 内存管理

seL4仅可能分配出power(2,n)且大于16byte的内存

8. 一般平台无关内存对象大小

n-bit Untyped对象 power(2,n) bytes(n>=4)

n-bit CNode对象 16*power(2,n) bytes(n>=2)

Endpoint对象 16 bytes

Notification对象 16 bytes

IRQ Control --

IRQ Handler --

9. 其他平台相关对象

TCB对象——一般1KB/512bytes

页表相关对象

ASID相关对象

——————————seL4词汇解释——————————

1. Capability——权限的复合体,内容丰富

(可能是seL4最精华的理念,因为seL4的一切据此展开)。

每个线程不光有地址空间(VSpace),

还有CapabilitySpace。

线程想要调用系统功能,将会通过调用

能力空间中的能力来实现系统功能

(如IPC会调用endpoint capability)

2. CNode(capability node)

Capability的基础承载者,

创建时即确定拥有的slot数量(power of 2),

slot用于保存Capabilities,

所保存的Capability为更深层的CNode时,即形成有向图。

也由此,当父CNode的Capability被取消时,

其子将会递归取消此Capability。

3. TCB 一般线程控制块

4. Endpoints

为线程间通讯提供支持(详述见IPC)

5. Notification 一般信号机制

poll

6. Untyped Memory 未类型内存

Untyepd内存可被Retype成seL4定义的一些内存对象。

7. CDT树(capability derivation tree)

——追踪源capability复制出的capability。

CDT虽是独立的概念,但在实际实现是CNode对象的一部分

(其实现可能是CNode数据结构中)

seL4_Untyped_Retype()//大致是申请内存

seL4_CNode_Mint();//复制CNode(可能包含权限降低)

seL4_CNode_Copy();//复制CNode

seL4_CNode_Mutate();//迁移CNode(可能包含权限降低)

上述函数均生成子capability,均被CDT追踪。

8. Slot——一段物理内存空间的实体。

——————————seL4基础服务——————————

1. 线程(Threads)

上下文切换、处理器时间分片的基本单位。

1.1 每一个线程,都会有相应的CSpace(Capability Space)

和VSpace(Virtual Space);

同时,线程还会有IPC buffer,

用于实现线程间通讯(详述见1.3 IPC)。

1.2 每一个线程都有其归属的调度域

(此处调度域与linux中存在很大区别)。

内核在完成编译时就确定了此内核中的调度域的个数,

内核将会定时、循环的调度各域。

调度域内可存在多个线程(无上限),

当且仅当线程所在调度域正在调度中时,线程才可能被调度执行。

1.3 在调度域内,seL4采用256优先级的抢占式循环调度器。

2. 地址空间(Address space)

虚拟地址空间,由页表完成地址翻译。

由于ASID资源限制,seL4设计了一个ASID Pool,

通过ASID Control能力,线程VSpace与ASID Pool链接,

以及通过ASID Pool使用ASID。

3. 线程间通讯(IPC Inter-process communication)

seL4线程间通讯通过endpoint(我认为应该是某种端点的含义)进行,

消息内容的第一段为tag段,

含有四部分:标志,消息长度,能力个数,开放能力的区域。

seL4在IPC通讯时,会尽可能多的使用CPU寄存器,

很多短内容的消息会直接通过CPU寄存器完成传递。

seL4对IPC通讯的支持并不关心内容,

需要用户层根据IPC消息的tag、消息所传来的能力等获得消息全部。

(感觉类似socket?优化了的socket。)

其他细节还很多,在此仅给以简述。

4. Notification

非阻塞的信号机制(与linux类似),比如对多路复用I/O的支持等。

5. Device primitive

seL4驱动是作为非特权程序执行在内核外,

内核通过IPC实现硬件终端的分发。

6. Capability Spaces(CSpace)

CSpace是一个线程下CNode组成的的有向图的集合;

也就是线程所拥有的Capability的集合。

seL4以线程为单位拥有CSpace,

内核启动第一个用户线程时即为之创建CSpace,

此CSpace将包含所有其创建的CNode,

当然也就包含所有其子线程的CSpace。

CSpace含有CNodes,CNode中address可以找到slot,

slot中有(或无)capability;

当slot的Capability为另一个CNode,即可形成有向图;

对每个线程,其CSpace都存在root CNode,可连通所有节点,

另:

线程发生系统调用,就会找到线程CSpace中,

关于这个系统调用Capability的address,

进而读取到相应slot,slot内容决定此系统调用是否执行。

内核通过CNodes对象管理线程的CSpace;

(简单说就是所有CNode都是连在一起的,有着共同的根,

根据父子进程,CSpace通过CNode产生逐级依赖)

——————————seL4创建线程——————————

1. seL4_Untyped_Retype()

Retype对象来创建线程的TCB

2. seL4_TCB_SetSpace()/seL4_TCB_Configer()

设置TCB的CSpace、VSpace和EndPoint等

3. seL4_TCB_WriteRegisters()

关于栈指针和指令指针的一些操作

4. seL4_TCB_Resume()

激活线程,线程将会加入其父所在CPU调度

5. 至此,线程将会被执行

6. seL4_TCB_SetAffinity()

在多核平台,可设置此线程的执行CPU

——————————seL4一些特点——————————

1.缓存溢出免疫(基于严苛的capability设计)

Buffer overflows are a classic security attack against operating systems, trying to make the software crash or even to inject malicious code into the cycle. We have proved that no such attack can be successful on seL4.

2.访问空指针免疫(原理未知)

Null pointer dereferences are another common issue in the C programming language. In applications they tend to lead to strange error messages and lost data. In operating systems they will usually crash the whole system. They do not occur in seL4.

3.C中指针指错数据类型免疫(原理未知)

In C it is possible to accidentally use a pointer to the wrong type of data. This is a common programming error. It does not happen in the seL4 kernel.

4.内存泄漏免疫(基于严苛的capability设计)

Memory leaks occur when memory is requested, but never given back. The other direction is even worse: memory could be given back, even though it is still in use. Neither of these can happen in seL4.

5.算术溢出/异常免疫(原理未知)

Humans and mathematics usually have a concept of numbers that can be arbitrarily big. Machines do not, they need to fit them into memory, usually into 32 or 64 bits worth of storage. Machines also generate exceptions when you attempt to do things that are undefined like dividing by zero. In the OS, such exceptions would typically crash the machine. This does not occur in seL4.

6.未定义行为免疫(原理未知)

There are many static analysis and verification tools that check for the absence of undefined behaviour in C. Our proof explicitly checks that no such undefined behaviour occurs.

——————————seL4总结————————————

1. seL4内核层面的显式权限控制可以提供很高的安全保障,如DDOS不再有效。

2. seL4提供的内存管理类类似于伙伴系统,能够有效减少内存碎片的产生,同样,不灵活的内存管理模式应该难以对内存充分利用。

3. seL4的IPC基于Endpoint,受制于Capability,短消息由于采用CPU寄存器传递,效率不会明显下降,但长消息机制依赖于IPC Buffer的复制,效率不高。

4. seL4的调度域根本隔离,带来的安全保障我并未想到,但调度域的静态设置应该会带来域内线程对用户响应的延迟,造成用户操作卡顿。

因此,基于上述分析, 

seL4的形式验证是一大亮点,

其显式的权限管理也可以带来安全,

但seL4还很年轻,社区活跃度不是非常高;

seL4的应用开发框架基于C语言,必须采用接口-实体开发模式,

不支持变长参数函数、函数指针等,因此代码移植可能存在难度。

基础设施建设不完善,基于其设计思想的工业应用很少,

若要真正投入使用,需要详尽分析其内核细节,

详细分析其可能存在的缺陷、困难再考虑是否应用。

seL4后续

1.seL4中断通过Notification分发

中断触发后,内核signal特定Notification,

线程会seL4_Wait()/seL4_Poll()这个notification

用户态用

seL4_IRQHandler_SetNotification()

之后线程开始seL4_Wait()/seL4_Poll()这个notification

中断到达,线程处理完后

seL4 IRQHandler Ack()提示内核处理完,内核可以发进一步的数据或后续中断

seL4_IRQHandler_Clear()接触这个Notification的注册

seL4没在主线中支持DMA

但对于x86

seL4支持了IOMMU

也是作为一种能力

seL4使用musl libc

seL4可能会有文件系统(同济裴喜龙)

seL4用的是gcc -O1,

有形式验证过的编译器CompCert

Norman Feske是搞Genode的,

Genode是微内核之上的系统框架,

这个系统框架类似linux的rootfs,

Norman Feske把Genode移植到seL4了。

写于2018.10

发布了24 篇原创文章 · 获赞 3 · 访问量 2338

猜你喜欢

转载自blog.csdn.net/ytfy339784578/article/details/103946461