Zircon 内核对象

Zircon 是一种基于对象的内核。用户模式代码几乎只通过对象句柄与操作系统资源进行交互。句柄可以视为一个活跃会话,其特定操作系统子系统的范围限定为特定资源。

Zircon 会主动管理以下资源:

  • 处理器时间
  • 内存和地址空间
  • 设备 I/O 内存
  • 中断
  • 信号和等待
  • 进程间通信

应用的内核对象

IPC

任务

调度

信号

内存和地址空间

正在等待

驱动程序的内核对象

内核对象生命周期

内核对象是受引用计数的。大多数内核对象都是在“create”系统调用期间创建的,并由第一个句柄保持活动状态(作为创建系统调用的输出)。调用方会获取句柄的数字 ID,并且句柄本身位于进程的句柄表中。

只要句柄存在于句柄表中,相应句柄就会一直保持活动状态。句柄通过以下方式从句柄表中移除:

  • 通过 zx_handle_close 关闭它们,这会减少相应内核对象的引用计数。通常,当最后一个句柄关闭时,内核对象引用计数将达到 0,这会导致内核对象被销毁。

  • 当拥有包含句柄的未读消息的通道端点被销毁时,所有待处理的消息也会被销毁,同时关闭消息中包含的所有句柄。

  • 拥有句柄表的进程被销毁时。内核会有效地迭代整个句柄表,然后依次关闭每个句柄。

通过 zx_handle_duplicate 创建新句柄(引用同一对象)以及获取直接指针引用(被某些内核代码)时,引用计数会增加;因此,内核对象的生命周期可能会长于创建该引用的代码的生命周期。此外,还会保留引用对象的活动句柄计数,从而允许内核在对象的句柄计数为零时触发特定行为,即使内核因直接指针引用而让对象保持活跃状态也是如此。

内核对象在没有未处理的句柄的情况下会保持活动状态,具体有三种重要情况:

  • 该对象由未使用的消息中的句柄引用。这可以通过 channel API 实现。当此类句柄位于通道中时,内核会使对象保持活动状态,并且有效句柄计数为非零。

  • 此对象是另一个处于活动状态的对象的父对象。附加到实时 VMAR、具有实时线程的进程和具有实时进程或子作业的作业VMO 就属于这种情况。

  • 线程由调度器保持活跃状态。处于活跃状态的线程将继续存在,直到其通过调用 zx_thread_exit 主动退出或通过 zx_task_kill 终止进程。

最后一种情况的结果是,单个线程可以使其进程和整个作业沿袭(直到根作业为止)保持活跃状态。

对等互连的对象和对等方关闭状态

目前,内核将以下对象类型定义为“对等”对象。

名称 对等关闭的信号名称
声道 ZX_CHANNEL_PEER_CLOSED
套接字 ZX_SOCKET_PEER_CLOSED
先进先出 (FIFO) ZX_FIFO_PEER_CLOSED
事件配对 ZX_EVENTPAIR_PEER_CLOSED

所有对等互连的对象成对创建,这些对象在对等关系中相互关联。当对等互连对象的活动句柄计数达到 0 时,如果该对象仍存在指向其对等项的链接,对等对象将处于 PEER_CLOSED 状态,从而导致链接被销毁,特定的 ZX_*_PEER_CLOSED 信号在对等方上变为断言状态,并且涉及该对象对等方的系统调用(例如 zx_channel_write)也会返回错误 ZX_ERR_PEER_CLOSED

当某个对象的最终句柄通过调用 zx_handle_closezx_handle_close_many 关闭时,可以保证在 zx_handle_close 系统调用从内核返回之前,该对象的对等方(如果有)将被置于 PEER_CLOSED 状态,并在此过程中断言其关联信号。

请注意,当对象对等的活跃句柄计数达到零时,即使对等对象因内核持有直接指针引用而继续存活,对象也会放入 PEER_CLOSED 中。

内核对象安全性

内核对象没有固有的安全概念,也不会执行授权检查;每个句柄都拥有安全权。单个进程可以有两个针对同一对象的不同句柄,但这些句柄具有不同的权限。

另请参阅

标识名