跳转到内容

术语表

本术语表定义了 OpenOS 文档中使用的核心术语。

不可伪造的权限令牌,引用内核对象。在 OpenOS 中,能力通过 HandleRights 实现。进程无法访问任何内核资源,除非它持有该资源的能力。能力可以传输(通过 Channel)但只能收窄,不能放大。这完全消除了环境权限。

对比:POSIX 文件描述符是环境权限——进程中的任何代码都可以使用任何 FD。OpenOS Handle 是显式的——你必须持有一个。


两个端点之间的双向、同步消息管道。Channel 是 OpenOS 的主要 IPC 机制。两端都持有 Handle。消息是字节序列,可以包含其他 Handle(能力传输)。每个方向最多一个消息在传输中。

关键操作:

  • channel_create — 创建一对连接的 Handle
  • channel_call — 原子发送 + 阻塞等待回复(客户端)
  • channel_receive + channel_reply — 接收 + 回复(服务器端)

对比:POSIX 管道是单向字节流,无 Handle 传输。POSIX 套接字需要单独的 socket/bind/listen/accept


进程命名空间中的命名条目,将服务名称映射到 Channel 的服务器 Handle。同一命名空间中的其他进程可以调用 endpoint_discover 获取客户端 Handle。

命名空间是每进程的——每个进程有自己的可用服务视图,由父进程在 process_start 之前填充。

对比:POSIX 有全局文件系统命名空间。OpenOS 有每进程的服务命名空间,没有全局表。


信号原语。可以是一次性的(信号在第一次等待后清除)或电平触发的(信号持续到显式清除)。用于异步通知——Channel 同步模型的非阻塞对应物。

对比:POSIX 信号是异步的、有损的、类型不好的,普遍被讨厌。OpenOS Event 是类型化的、无损的,通过 Channel 传递。


不透明的、进程本地的令牌,引用内核对象。用户空间与内核交互的唯一方式。每个 Handle 携带一个 Rights 位掩码,限制允许的操作。

Handle 是 64 位值,编码:object_id(32 位)、rights(16 位)、generation(16 位)。generation 防止关闭后使用的 bug。

Handle 可以:

  • 关闭 — 释放引用,可能销毁对象
  • 复制 — 在同一进程内克隆(权限可以收窄)
  • 传输 — 通过 Channel 移动到另一个进程(权限可以收窄)

对比:POSIX 文件描述符是全局表中的小整数。OpenOS Handle 是具有显式权限和 generation 检查的不透明令牌。


带有资源限制的进程容器。Job 形成——每个 Job 都有一个父 Job(除了在启动时创建的根 Job)。每个进程属于恰好一个 Job。

job_kill 终止 Job 中的所有进程和所有子 Job——这是清理整个服务子树的批量终止机制。

没有隐式重新挂靠:如果进程退出,其子进程留在同一个 Job 中。根 Job 的所有者(init)负责回收孤儿。

对比:POSIX 有进程组和会话,但孤儿处理是隐式的(重新挂靠到 init)。OpenOS Job 使层次结构显式化。


表示页面粒度物理内存区域的内核对象。内存对象默认映射到任何地址空间——需要 memory_map 才能访问。

内存对象是引用计数的:每个 Handle 和每个映射都持有引用。物理页面仅在引用计数达到 0 时释放。

标志:

  • MEMORY_RESIZABLE — 创建后可以增长/收缩
  • MEMORY_SHARED — 可以同时映射到多个进程

对比:POSIX mmap 混淆了分配和映射。OpenOS 将它们分离:memory_create 分配,memory_map 映射。这使共享内存显式且可通过 Handle 传输。


从服务名称(UTF-8 字符串)到 Channel Handle 的每进程映射。每个进程有自己的命名空间,由父进程在 process_start 之前填充。

  • endpoint_register("name", channel) — 添加条目到自己的命名空间
  • endpoint_discover("name") — 在自己的命名空间中查找条目

子进程启动时具有命名空间。父进程必须显式传输服务 Handle 以填充它。没有环境发现。

对比:POSIX 有全局 / 命名空间。Plan 9 有每进程命名空间(mount/bind)。OpenOS 继承了 Plan 9 的方法,但使用基于 Handle 的服务发现而非文件操作。


包含一个或多个线程的隔离地址空间。创建时为空——父进程必须显式映射内存对象并启动线程。

生命周期:

  1. process_create(job, name) → 空地址空间
  2. memory_create + memory_map → 填充地址空间
  3. thread_create → 创建执行上下文
  4. process_start(proc, thread, entry, stack, arg) → 开始执行
  5. process_exit(status) → 终止所有线程,关闭所有 Handle
  6. process_wait(proc) → 父进程获取退出状态

对比:POSIX fork() 复制所有内容,然后 exec() 替换它。OpenOS 创建空进程并显式构建。


管理内核对象生命周期的机制。每个对象跟踪:

  • 指向它的 Handle 数量
  • 使用它的 Mapping 数量(对于内存对象)

当所有引用被释放时,对象被销毁,其资源(物理页面、内核内存)被回收。

这防止了 use-after-free 和资源泄漏,无需垃圾收集。


RPC 交换中服务器的响应。在 channel_receive 传递客户端消息后,服务器处理它并调用 channel_reply 发送响应。这解除客户端 channel_call 的阻塞。

如果服务器崩溃而没有回复,内核自动向阻塞的客户端发送 EPIPE 错误——防止无限等待。

对比:POSIX 没有内置的请求-回复机制。每个操作是独立的。OpenOS 使 RPC 模式成为一等公民。


附加到每个 Handle 的位掩码,限制允许的操作。Rights 只能收窄(通过 handle_duplicatehandle_transfer),不能放大。

Right含义
READ0从对象读取数据
WRITE1向对象写入数据
EXECUTE2执行(用于内存对象)
TRANSFER3将 Handle 发送给另一个进程
DUPLICATE4在同一进程内克隆 Handle
SIGNAL5发送信号
WAIT6等待对象
DESTROY7关闭/销毁对象
MAP8映射到地址空间
CONFIGURE9修改对象属性

对比:POSIX 在 open 时有 O_RDONLY/O_WRONLY/O_RDWR。OpenOS 有 10 个独立的权限位,可以按 Handle 任意组合。


进程虚拟地址空间中的命名区域。每个进程有一个根 VMAR(由 process_create 返回)。VMAR 将地址空间组织成逻辑区域——代码、栈、堆、共享内存。

VMAR 被 memory_map 内部使用,将内存对象放置在特定的虚拟地址。内核跟踪哪个 VMAR 拥有哪个地址范围以防止重叠。

对比:POSIX mmap 使用匿名地址范围。OpenOS VMAR 是可以查询和管理的显式对象。


进程内的执行上下文。线程共享进程的地址空间和 Handle 表。每个线程有自己的栈和寄存器状态。

创建时挂起——需要 process_start 才能开始执行。thread_exit 终止当前线程。如果是最后一个线程,进程以状态 0 退出。

对比:POSIX 有 pthread_create,带有复杂的属性。OpenOS 线程是最小的——创建、启动、退出、让出。


截止时间/间隔信号对象。当达到截止时间时,定时器发出信号(兼容 Event 语义)。如果设置了间隔,则重复。

定时器用于:

  • channel_call 的超时
  • 周期性任务(心跳、轮询)
  • 睡眠(timer_create + 等待定时器的 event)

对比:POSIX 有 timer_createtimer_settimenanosleepalarmsetitimer——五个独立的机制。OpenOS 有一个。


未在 OpenOS 中使用。 这是 Zircon(Fuchsia)的概念——可分页的、可调整大小的内存容器。OpenOS 使用内存对象代替,更简单(不可分页,固定大小,除非 MEMORY_RESIZABLE)。

为熟悉 Zircon 术语的读者提及。