日日是好日

Barrelfish操作系统 (1)系统介绍

November 25, 2019

  网上貌似没有Barrelfish的中文文档,正好最近在写文献综述,所以这里整理一下,为以后想要研究这个系统的童鞋省一点时间。

简介

  Barrelfish是微软剑桥研究院和苏黎世理工大学提出的一个面向异构、众核体系的操作系统,其旨在解决异构、众核体系结构上操作系统的可扩展性问题。系统基于微内核和多内核(Multikernel)的思想设计。
  多内核是指在每一个处理器核心上都运行一个操作系统内核实例,内核之间不共享任何内存(即使在有共享内存的硬件上),系统的其余部分是构建在这些内核之上的单核进程,可以视为一个分布式系统,系统节点之间基于显式的消息进行通信。即共享内存只用于显式的消息传递、数据传递以及动态启动其他内核时。用户级应用进程可以跨核部署并共享地址空间,但这个功能是由Barrelfish用户空间的运行时库提供的。下面是Barrelfish的架构示意图。其中的UMP(User Message Passing)和LMP(Local Message Passing)是Barrelfish内的两种消息通信方式,UMP是跨核的消息通信,LMP是核内消息通信。

内核(CPU Driver)

  CPU Driver是Barrelfish的内核,运行于Barrelfish所运行的机器上的单个处理器核心里,支持多种处理器架构。CPU Driver是单线程、不可抢占的,运行在关中断的模式下。可以认为它在连续地运行异常处理程序,比如中断(interrupt)、异常(fault)、来自用户空间的系统调用(system call)。如果没有可以运行的异常处理程序,它就执行一个用户空间的任务。

  CPU Driver的功能包括:

CPU Driver提供的系统调用:

  CPU驱动程序不提供内核线程,原因有二。首先,Barrelfish提供给用户空间程序的处理器抽象是一个dispatcher,而不是线程(一个Dispatcher内可以有多个用户线程)。其次,由于内核是单线程的且不可抢占的,因此它仅为所有操作使用一个静态分配的堆栈。在执行完单个异常处理程序之后,将丢弃并重置此堆栈的内容。

  Barrelfish目前提供两种在编译时指定的调度方式:

进程(Dispatcher)

  Dispatcher是内核调度的单元,相当于Unix中进程的概念。一个应用程序(在Barrelfish里称为domain)可以分布在多个核上,在每个核上都有一个dispatcher。Dispatcher不能在核间迁移。
  当内核根据调度结果决定运行某一个dispatcher时,内核需要“upcall”该dispatcher,系统从内核态进入用户态,之后与该dispatcher对应的用户级代码开始执行用户空间的线程调度,以及处理其他事件(比如来自内核的缺页错误、或者Domain间消息)。
  内核为每个dispatcher维护一个DCB (dispatcher控制块),如图所示,DCB里面包含了这个dispatcher的各种信息,包括

  每一个dispatcher可以有两种模式,分别是enabled和disabled,当处于enabled模式下时,该dispatcher运行dispatcher下的用户线程,当处于disabled模式下时,该dispatcher运行dispatcher自身代码(如管理TCB、运行线程队列中的线程)。
  Dispatcher定义了一组upcall的接口,以供内核对自身进行调度。其中最主要的upcall是run(),当内核决定调度某个dispatcher时,它以指向该dispatcher的页表基址的capability为参数调用该dispatcher的run(),然后该dispatcher决定运行哪一个用户线程,恢复该线程的状态,并运行该线程。在dispatcher被run()之后,以及用户线程被执行之前,该dispatcher都是disable模式,在用户线程开始运行后,该dispatcher处于enabled模式。
  当处于enabled模式下的disaptcher被抢占时,内核把所有寄存器状态存在该dispatcher的“enabled区域”(见上图),当该dispatcher之后重新被调度时,它可以从enabled区域恢复之前的寄存器状态,继续运行之前的用户线程,也可以调度另外一个用户线程来运行,但在执行另外一个用户线程之前必须先把之前的用户线程的寄存器状态存到TCB里。
  当处于disabled模式下的dispatcher被抢占时,内核把所有寄存器状态存在该dispatcher的“disabled区域”(见上图),当内核调度一个处于disabled模式下的dispatcher时,内核不会调用其run()类型的upcall,而是从disabled区域恢复之前的寄存器状态,允许之前被打断的dispatcher自身代码从被抢占处继续运行。

运行时库(Runtime library)

  Barrelfish提供两个基本的库:

  后者实现了以下系统功能:

权能(Capability)

   Capability可以看作是访问某种资源的令牌、凭证或票据,是提供给主体对资源实体具有特定权限的不可伪造的标志,在系统实现中至少必须包含两种信息:

  基于Capability的访问控制机制有利于实现对系统安全范畴中权限细粒度化(fine-grained privilege)和最小特权原则(least privilege)的支持,即进程所能访问到的资源范围不应大于其完成任务所需要的资源的范围。

  Barrelfish使用了基于Capability的访问控制机制,用来控制系统中进程对系统中物理内存、内核对象的操作。关于Capabiltiy系统的设计与实现可以参考这篇文章


Tags:
Categories: