IPC 协议
OpenOS 采用基于 Channel 的同步消息传递 IPC 机制,灵感来自 seL4 和 Zircon(Fuchsia)。Channel 是双向、同步的消息管道,支持 Handle 传递。
Channel 架构
Section titled “Channel 架构”┌─────────────┐ 消息 ┌─────────────┐│ 任务 A │ ──────────────→ │ 任务 B ││ (发送方) │ │ (接收方) │└─────────────┘ └─────────────┘ │ │ ▼ ▼ Handle A Handle B (End A) (End B)- Channel - 双向同步消息管道
- Handle - 不透明的能力令牌,引用内核对象
- Rights - 10 位权限位掩码
- Generation - 防止关闭后使用
Channel 操作
Section titled “Channel 操作”channel_create
Section titled “channel_create”创建一个新的 Channel,返回两端的 Handle。
fn channel_create(flags: u64) -> (handle_a: Handle, handle_b: Handle)Handle 格式:
bits [0:31] object_id — 内核对象表索引bits [32:47] rights — 能力权限位掩码bits [48:63] generation — 防止关闭后使用channel_send
Section titled “channel_send”发送消息。阻塞直到接收方调用 channel_receive。
fn channel_send(handle: u64, msg: *const u8, len: u64) -> i64行为:
- 消息被复制到内核
- 如果接收方已阻塞在 channel_receive,消息立即传递
- 否则,发送方阻塞直到接收方准备好
channel_receive
Section titled “channel_receive”接收消息。阻塞直到有消息可用。
fn channel_receive(handle: u64, buf: *mut u8, len: u64) -> u64行为:
- 如果已有消息,立即返回
- 否则,阻塞直到有消息到达
- 返回实际接收的字节数
channel_call
Section titled “channel_call”原子性的发送 + 阻塞等待回复(RPC 原语)。
fn channel_call(handle: u64, msg: *const u8, len: u64) -> u64行为:
- 发送消息
- 阻塞等待回复
- 返回回复数据
超时: 可通过 flags 参数指定超时。
channel_reply
Section titled “channel_reply”回复接收到的消息。解除调用方 channel_call 的阻塞。
fn channel_reply(handle: u64, msg: *const u8, len: u64) -> i64重要规则:
- 必须对每个 channel_receive 调用 channel_reply
- 如果服务器崩溃而没有回复,内核自动发送 EPIPE 错误
Handle 操作
Section titled “Handle 操作”handle_close
Section titled “handle_close”关闭 Handle。如果这是最后一个引用,销毁对象。
fn handle_close(handle: u64) -> i64handle_duplicate
Section titled “handle_duplicate”克隆 Handle,可选择收窄权限。
fn handle_duplicate(handle: u64, new_rights: u64) -> u64权限收窄: 新权限 = 原始权限 & new_rights
handle_transfer
Section titled “handle_transfer”通过 Channel 将 Handle 发送给另一个进程。
fn handle_transfer(handle: u64, target_channel: u64, rights: u64) -> i64特性:
- Handle 被移动——在发送方不再有效
- 接收方获得新 Handle,权限 = 原始权限 & rights
- 单调特权递减——权限只能减少
Channel 是同步和无缓冲的——send 阻塞直到 receive。三种模式处理并发:
模式 1:线程池(推荐)
Section titled “模式 1:线程池(推荐)”// 服务器预先创建 N 个工作线程loop { let msg = channel_receive(handle); let response = process(msg); channel_reply(handle, response);}模式 2:接受线程 + 分发
Section titled “模式 2:接受线程 + 分发”// 一个线程接受请求,分发到工作池loop { let msg = channel_receive(handle); spawn(move || { let result = process(msg); channel_reply(handle, result); });}模式 3:内联处理
Section titled “模式 3:内联处理”// 内核内部处理(用于简单服务)// channel_send 触发内联处理RPC 模式
Section titled “RPC 模式”基本 RPC
Section titled “基本 RPC”客户端 服务器 │ │ │ channel_call(msg) │ │ ─────────────────────────────→ │ │ │ channel_receive() │ │ 处理请求 │ │ channel_reply(response) │ ←───────────────────────────── │ │ (解除阻塞) │// 服务器必须回复,即使在错误时match process_request(msg) { Ok(response) => channel_reply(handle, response), Err(e) => channel_reply(handle, error_response(e)),}
// 如果服务器崩溃,内核自动回复 EPIPEHandle 传递
Section titled “Handle 传递”// 进程 A 有 Memory Handle (READ | WRITE)// 想给进程 B 只读访问
let (a_end, b_end) = channel_create(0);
// A 收窄权限并传递handle_transfer(memory_handle, a_end, READ);// memory_handle 在 A 中无效
// B 接收 Handlelet msg = channel_receive(b_end);let shared_mem = received_handles[0]; // 只有 READ 权限权限收窄规则
Section titled “权限收窄规则”原始 Handle: READ | WRITE | TRANSFER | MAP传递 Rights: READ | MAP──────────────────────────────接收方获得: READ | MAP (交集)每进程命名空间
Section titled “每进程命名空间”每个进程有自己的服务命名空间,由父进程填充。
// 父进程let (server, client) = channel_create(0);endpoint_register("console", server);
// 传递给子进程handle_transfer(client, child_channel, READ | WRITE);
// 子进程let console = endpoint_discover("console");channel_call(console, msg);与旧实现的对比
Section titled “与旧实现的对比”| 方面 | 旧实现(端口) | 新实现(Channel) |
|---|---|---|
| IPC 原语 | 端口 + 消息 | Channel + Handle |
| 同步性 | 异步发送 | 同步会合 |
| 能力模型 | 无 | Handle + Rights |
| Handle 传递 | 不支持 | 支持 |
| RPC | 手动实现 | channel_call 原语 |
| 命名空间 | 全局端口表 | 每进程命名空间 |
| 功能 | 状态 | 说明 |
|---|---|---|
| channel_create | [done] 完成 | 创建 Channel |
| channel_send | [done] 完成 | 发送消息 |
| channel_receive | [done] 完成 | 接收消息 |
| channel_call | [done] 完成 | 原子 RPC |
| channel_reply | [done] 完成 | 回复消息 |
| handle_close | [done] 完成 | 关闭 Handle |
| handle_duplicate | [done] 完成 | 克隆 Handle |
| handle_transfer | [done] 完成 | 传递 Handle |
| 用户空间服务 | [done] 完成 | console_svc.elf |
| endpoint_register | [plan] 计划中 | 服务注册 |
| endpoint_discover | [plan] 计划中 | 服务发现 |
- 系统调用参考 - 完整的系统调用接口
- Handle 与 Rights - 能力系统详细设计
- Channel IPC - Channel 通信机制设计