Zircon 是基于对象的内核。用户模式代码几乎完全通过对象句柄与操作系统资源进行交互 。句柄可以被视为与特定操作系统子系统(限定为特定资源)的活跃会话。
Zircon 会主动管理以下资源:
- 处理器时间
- 内存和地址空间
- 设备 I/O 内存
- 中断
- 信令与等待
- 进程间通信
应用的内核对象
常规
IPC
任务
调度
信令
内存和地址空间
等待
驱动程序的内核对象
内核对象生命周期
内核对象是引用计数的。大多数内核对象是在“创建”系统调用期间创建的,并由第一个句柄(作为创建系统调用的输出)保持活跃状态。调用方会获得句柄的数字 ID,而句柄本身则放置在进程的句柄表中。
只要句柄存在于句柄表中,就会保持活跃状态。句柄会通过以下方式从句柄表中移除:
通过
zx_handle_close关闭句柄,这会减少相应内核对象的引用 计数。通常,当最后一个句柄关闭时,内核对象引用计数将达到 0,这会导致内核对象被销毁。当持有包含句柄的未读消息的通道端点被销毁时,所有待处理的消息也会被销毁,同时关闭消息中包含的所有句柄。
当拥有句柄表的进程被销毁时。内核实际上会遍历整个句柄表,依次关闭每个句柄。
当通过 zx_handle_duplicate 创建新句柄(引用同一对象)时,引用计数会增加,但当获取直接指针引用(通过某些内核代码)时,引用计数也会增加;因此,内核对象的生命周期可能比创建它的代码的生命周期更长。系统还会维护引用对象的活跃句柄的单独计数,以便内核在对象的句柄计数达到零时触发特定行为,即使内核由于直接指针引用而在后台保持对象活跃状态也是如此。
在以下三种重要情况下,当没有未完成的句柄时,内核对象会保持活跃状态:
对象被尚未使用的消息中的句柄引用。 这种情况可以通过通道 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 |
| IOBuffer | ZX_IOB_PEER_CLOSED |
所有对等对象都是成对创建的,它们在内部以对等关系相互关联。 当对等对象的活跃句柄计数
达到 0 时,如果该对象仍与对等对象存在关联,则对等对象将置于 PEER_CLOSED 状态,从而导致关联被销毁,特定 ZX_*_PEER_CLOSED 信号在对等对象上断言,并且涉及对象对等对象的系统调用(例如 zx_channel_write)返回错误 ZX_ERR_PEER_CLOSED。
当通过调用 zx_handle_close 或 zx_handle_close_many 关闭对象的最后一个句柄时,可以保证对象的对等对象(如果有)将置于 PEER_CLOSED 状态,并在该过程中断言其关联的信号,然后 zx_handle_close 系统调用从内核返回。
请注意,当对象的对等对象的活跃句柄计数达到零时,对象将置于 PEER_CLOSED 状态,即使对等对象由于内核持有的直接指针引用而继续保持活跃状态也是如此。 活跃句柄计数
内核对象安全性
内核对象没有固有的安全性概念,也不会执行授权检查;安全权限由每个句柄持有。单个进程可以拥有同一对象的两个不同句柄,这些句柄具有不同的权限。