操作系统—微内核通信

操作系统—微内核通信

在微内核架构下,一个应用程序获取系统服务通常需要通过进程间通信的方式。

Mach:早期的微内核进程间通信设计

mach通过两种基本的抽象—端口和消息,设计和实现一种间接通信ipc。

端口设计:
mach将端口分为发送者端口和接受者端口,mach的通信不是指定的,而是发送者从发送端口发送消息,然后接收者可以从接受端口去拿消息,发送端口可以有多个,但接受端口只能有一个。

消息设计:
mach传递消息支持传递端口,比如进程a与进程b通信,进程a也与进程c通信,那么进程a可以发送给进程b,进程c的端口,这样就建立了b与c的连接。

mach有三个借口,msg_send,msg_receive,msg_rpc,单向通信一般用msg_send,双向通信一般用msg_rpc。

L4:围绕进程间通信优化而设计的微内核系统

L4消息传递:前面介绍的mach消息传递端口的方式,在sel4中以消息传递capability的方式传递下来。L4将消息分为长消息和短消息,后期还有中等消息,这样设计的目的是减少数据拷贝。

短消息:短消息通过寄存器来传递,这样实现了零拷贝。
具体流程:
1.调用者将消息写在全局寄存器中
2.控制流转移,陷入内核,从调用者上下文切换到被调用者的上下文。
3.被调用者从寄存器取数据

长消息:长消息通常需要两次拷贝:从发送者用户态拷贝到内核缓冲区,以及从内核缓冲区拷贝到接收者用户态。有一种优化可以让拷贝次数只有一次,就是将发送者临时缓冲区的虚拟地址映射到接收者物理地址。

L4控制流转移

惰性调度:就是在线程被阻塞时,我们还把线程放在就绪队列中,只改变线程TCB中的状态,这样避免大量的队列操作,当他不阻塞时我们还是改变TCB中的状态即可。

L4通信连接:以前L4是直接通信,知道一个线程号就可以与他一对一通信,由于一些安全问题,转变为像mach一样的间接通信了。

L4权限检查:capability机制,capability简单看来是对内核对象的一个引用,以及对该内核对象的一个权限。以ipc为例,微内核会在每个通信连接维护一个IPC内核对象,这个内核对象包含接受者,发送者,缓冲区等通信相关信息,当发送者要发起通信时,需要告知内核一个特定的capability来发起通信,内核检查capability,然后找到capability对应的内核对象以及与之对应的接受者,从而开启通信。
所以在开启通信前,两个进程要先通过命名服务等方式获取到对应的capability。

LRPC:迁移线程模型

迁移线程就是把服务端的代码拉取到客户端来处理数据。这样就避免了控制流切换和数据传输。

迁移线程的基本原则:

  1. 简化控制流切换,让客户端线程执行“服务端的代码”。
  2. 简化数据传输,共享参数栈和寄存器
  3. 简化接口,减少序列化等开销
  4. 优化并发,避免共享的全局数据结构。

迁移线程中,服务端更像一个代码提供者,此外内核不会进行完整的上下文切换,而是只切换地址空间等和请求处理相关的系统状态。其中不会涉及线程和优先级的切换,也不会调用调度器。

LRPC设计:

共享参数栈和寄存器:内核为每个rpc都设立一个参数栈。然后将参数栈映射到客户端和服务端的地址空间,这样他们就可以通过这个栈来传递数据。

通信连接的建立:当客户端申请和一个服务端建立连接时,内核会分配参数栈和连接记录(用来返回的),并返回给客户端一个绑定对象,之后客户端可以通过绑定对象发起通信。

通信过程

  1. 内核验证绑定对象的正确性,并找到正确的服务描述符
  2. 内核验证参数栈和连接记录的正确性
  3. 内核检查是否有并发调用(可能导致参数栈异常)
  4. 内核将调用者的返回地址和栈指针放到连接记录中
  5. 内核将连接记录放到线程控制结构体中的栈上
  6. 内核切换到被调用者进程地址空间
  7. 内核找到被调用者进程的运行栈(执行代码所用的栈)
  8. 内核将调用者线程的栈指针设置为被调用者线程的运行栈地址
  9. 内核将代码指针指向被调用者地址空间中的处理函数
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值