From 87123f4801394669a0205218cc32345afeed1329 Mon Sep 17 00:00:00 2001 From: Runji Wang Date: Tue, 28 Jul 2020 04:04:25 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E5=86=85=E6=A0=B8=E5=AF=B9?= =?UTF-8?q?=E8=B1=A1=E7=AE=80=E4=BB=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/src/ch01-01-kernel-object.md | 61 +++++++++++++++++++++---- docs/src/img/ch01-01-kernel-object.png | Bin 0 -> 24499 bytes 2 files changed, 53 insertions(+), 8 deletions(-) create mode 100644 docs/src/img/ch01-01-kernel-object.png diff --git a/docs/src/ch01-01-kernel-object.md b/docs/src/ch01-01-kernel-object.md index 1a6dd69..d7dc10b 100644 --- a/docs/src/ch01-01-kernel-object.md +++ b/docs/src/ch01-01-kernel-object.md @@ -2,13 +2,57 @@ ## 内核对象简介 -TODO +在动手编写我们的代码之前,需要首先进行调研和学习,对目标对象有一个全面系统的了解。 +而了解一个项目设计的最好方式就是阅读官方提供的手册和文档。 -详细内容可参考 Fuchsia 官方文档:[内核对象]。 - -在这一节中我们将在 Rust 中实现内核对象的概念。 +让我们先来阅读一下 Fuchsia 官方文档:[内核对象]。这个链接是社区翻译的中文版,已经有些年头了。如果读者能够科学上网,推荐直接阅读[官方英文版]。 [内核对象]: https://github.com/zhangpf/fuchsia-docs-zh-CN/blob/master/zircon/docs/objects.md +[官方英文版]: https://fuchsia.dev/fuchsia-src/reference/kernel_objects/objects + +通过阅读文档,我们了解到与内核对象相关的三个重要概念:**对象(Object),句柄(Handle),权限(Rights)**。它们在 Zircon 内核中的角色和关系如下图所示: + +![](img/ch01-01-kernel-object.png) + +简单来说: + +* Zircon是一个基于对象的内核,内核资源被抽象封装在不同的 **对象** 中。 +* 用户程序通过 **句柄** 与内核交互。句柄是对某一对象的引用,并且附加了特定的 **权限**。 +* 对象通过 **引用计数** 管理生命周期。当最后一个句柄关闭时,对象随之销毁。 + +此外在内核对象的文档中,还列举了一些[常用对象]。点击链接进去就能查看到这个对象的[具体描述],在页面最下方还列举了与这个对象相关的[全部系统调用]。 +进一步查看系统调用的 [API 定义],以及它的[行为描述],我们就能更深入地了解用户程序操作内核对象的一些细节: + +[常用对象]: https://github.com/zhangpf/fuchsia-docs-zh-CN/blob/master/zircon/docs/objects.md#应用程序可用的内核对象 +[具体描述]: https://github.com/zhangpf/fuchsia-docs-zh-CN/blob/master/zircon/docs/objects/channel.md +[全部系统调用]: https://github.com/zhangpf/fuchsia-docs-zh-CN/blob/master/zircon/docs/objects/channel.md#系统调用 +[API 定义]: https://github.com/zhangpf/fuchsia-docs-zh-CN/blob/master/zircon/docs/syscalls/channel_read.md#概要 +[行为描述]: https://github.com/zhangpf/fuchsia-docs-zh-CN/blob/master/zircon/docs/syscalls/channel_read.md#描述 + +* 创建:每一种内核对象都存在一个系统调用来创建它,例如 [`zx_channel_create`]。 +创建对象时一般需要传入一个参数选项 `options`,若创建成功则内核会将一个新句柄写入用户指定的内存中。 + +* 使用:获得对象句柄后可以通过若干系统调用对它进行操作,例如 [`zx_channel_write`]。 +这类系统调用一般需要传入句柄 `handle` 作为第一个参数,内核首先对其进行检查,如果句柄非法或者对象类型与系统调用不匹配就会报错。 +接下来内核会检查句柄的权限是否满足操作的要求,例如 `write` 操作一般要求句柄具有 `WRITE` 权限,如果权限不满足就会继续报错。 + +* 关闭:当用户程序不再使用对象时,会调用 [`zx_handle_close`] 关闭句柄。当用户进程退出时,仍处于打开状态的句柄也都会自动关闭。 + +[`zx_channel_create`]: https://github.com/zhangpf/fuchsia-docs-zh-CN/blob/master/zircon/docs/syscalls/channel_create.md +[`zx_channel_write`]: https://github.com/zhangpf/fuchsia-docs-zh-CN/blob/master/zircon/docs/syscalls/channel_write.md +[`zx_handle_close`]: https://github.com/zhangpf/fuchsia-docs-zh-CN/blob/master/zircon/docs/syscalls/handle_close.md + +我们还发现,有一类 Object 系统调用是对所有内核对象都适用的。 +这表明所有内核对象都有一些公共属性,例如 ID、名称等等。每一种内核对象也会有自己特有的属性。 + +其中一些 Object 系统调用和信号相关。Zircon 每个内核对象都附带有 32 个 **[信号(Signals)]**,它们代表了不同类型的事件。 +与传统 Unix 系统的信号不同,它不能异步地打断用户程序运行,而只能由用户程序主动地阻塞等待在某个对象的某些信号上面。 +信号是 Zircon 内核中很重要的机制,不过这部分在前期不会涉及,我们留到第五章再具体实现。 + +[信号(Signals)]: https://github.com/zhangpf/fuchsia-docs-zh-CN/blob/master/zircon/docs/signals.md + +以上我们了解了 Zircon 内核对象的相关概念和使用方式。接下来在这一节中,我们将用 Rust 实现内核对象的基本框架,以方便后续快速实现各种具体类型的内核对象。 +从传统面向对象语言的视角看,我们只是在实现一个基类。但由于 Rust 语言模型的限制,这件事情需要用到一些特殊的技巧。 ## 建立项目 @@ -174,10 +218,11 @@ DummyObject *dummy = dynamic_cast(base); [`Any`]: https://doc.rust-lang.org/std/any/ -```rust,editable,noplaypen -# use core::any::Any; -# use alloc::sync::Arc; -# +```rust,editable +# use std::any::Any; +# use std::sync::Arc; +# fn main() {} + trait KernelObject: Any + Send + Sync {} fn downcast_v1(object: Arc) -> Arc { object.downcast::().unwrap() diff --git a/docs/src/img/ch01-01-kernel-object.png b/docs/src/img/ch01-01-kernel-object.png new file mode 100644 index 0000000000000000000000000000000000000000..9c8cdf66d08c97dfe71983b9f1b70f4c29266bfc GIT binary patch literal 24499 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�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