From fbccd9a7cfab541b6dc2d6814ae3efa4be661636 Mon Sep 17 00:00:00 2001 From: Yukiteru Lee Date: Mon, 27 Jul 2020 10:11:03 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E7=BC=96=E5=86=99=20README.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) mode change 120000 => 100644 README.md diff --git a/README.md b/README.md deleted file mode 120000 index 95cf2af..0000000 --- a/README.md +++ /dev/null @@ -1 +0,0 @@ -docs/src/README.md \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..05c2959 --- /dev/null +++ b/README.md @@ -0,0 +1,20 @@ +# zCore Tutorial + +## 仓库目录 + +* `docs/`: 教学实验指导 +* `zcore`: 操作系统代码 + +## 实验指导 + +基于 mdBook,目前目前已经部署到了 [GitHub Pages](https://rcore-os.github.io/zCore-Tutorial/) 上面。 + +### 文档本地使用方法 + +```bash +git clone https://github.com/rcore-os/zCore-Tutorial.git +cd zCore-Tutorial +cargo install mdbook +mdbook serve docs +``` + From f700eef6c4a865a1b2427d0e9ecf7b5de63e19d6 Mon Sep 17 00:00:00 2001 From: Yukiteru Lee Date: Mon, 27 Jul 2020 10:37:29 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E4=BD=BF=E6=96=87=E6=A1=A3=E6=94=AF?= =?UTF-8?q?=E6=8C=81=20editable?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/book.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/book.toml b/docs/book.toml index 15e81fa..aebc721 100644 --- a/docs/book.toml +++ b/docs/book.toml @@ -4,3 +4,5 @@ language = "cn" multilingual = false src = "src" title = "简明 zCore 教程" +[output.html.playpen] +editable = true From 374b3f5d7c3db202e2babae43c7b1a44a94cad16 Mon Sep 17 00:00:00 2001 From: Yukiteru Lee Date: Mon, 27 Jul 2020 11:52:31 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E8=B7=AF=E5=BE=84=20=E6=B7=BB=E5=8A=A0=E9=93=BE=E6=8E=A5=20?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=83=A8=E5=88=86=E4=BB=A3=E7=A0=81=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/src/ch01-01-kernel-object.md | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/docs/src/ch01-01-kernel-object.md b/docs/src/ch01-01-kernel-object.md index b8e76f1..1a6dd69 100644 --- a/docs/src/ch01-01-kernel-object.md +++ b/docs/src/ch01-01-kernel-object.md @@ -41,6 +41,7 @@ $ cd zcore 为此我们需要移除对标准库的依赖,使其成为一个不依赖当前 OS 功能的库。在 `lib.rs` 的第一行添加声明: ```rust,noplaypen +// src/lib.rs #![no_std] extern crate alloc; ``` @@ -67,7 +68,8 @@ Rust 是一门部分面向对象的语言,我们通常用它的 trait 实现 首先创建一个 `KernelObject` trait 作为内核对象的公共接口: -```rust +```rust,noplaypen +// src/object/mod.rs /// 内核对象公共接口 pub trait KernelObject: Send + Sync { {{#include ../../zcore/src/object/mod.rs:object}} @@ -86,6 +88,7 @@ pub trait KernelObject: Send + Sync { 接下来我们实现一个最简单的空对象 `DummyObject`,并为它实现 `KernelObject` 接口: ```rust,noplaypen +// src/object/object.rs {{#include ../../zcore/src/object/object_v1.rs:dummy_def}} ``` @@ -109,6 +112,7 @@ pub trait KernelObject: Send + Sync { 然后我们为新对象实现构造函数: ```rust,noplaypen +// src/object/object.rs {{#include ../../zcore/src/object/object_v1.rs:dummy_new}} ``` @@ -120,6 +124,7 @@ ID 类型使用 `u64`,保证了数值空间足够大,在有生之年都不 最后我们为它实现 `KernelObject` 接口: ```rust,noplaypen +// src/object/object.rs {{#include ../../zcore/src/object/object_v1.rs:dummy_impl}} ``` @@ -129,6 +134,7 @@ ID 类型使用 `u64`,保证了数值空间足够大,在有生之年都不 为了证明上面代码的正确性,我们写一个简单的单元测试,替换掉自带的 `it_works` 函数: ```rust,noplaypen +// src/object/object.rs {{#include ../../zcore/src/object/object_v1.rs:dummy_test}} ``` @@ -168,9 +174,10 @@ DummyObject *dummy = dynamic_cast(base); [`Any`]: https://doc.rust-lang.org/std/any/ -```rust,editable -#use std::any::Any; -#use std::sync::Arc; +```rust,editable,noplaypen +# use core::any::Any; +# use alloc::sync::Arc; +# trait KernelObject: Any + Send + Sync {} fn downcast_v1(object: Arc) -> Arc { object.downcast::().unwrap() @@ -190,11 +197,12 @@ fn downcast_v2(object: Arc) -> Arc { {{#include ../../zcore/Cargo.toml:downcast}} ``` -(题外话:这个库原来是不支持 no_std 的,zCore 有这个需求,于是就顺便帮他实现了一把) +(题外话:这个库原来是不支持 `no_std` 的,zCore 有这个需求,于是就顺便帮他实现了一把) 按照它文档的描述,我们要为自己的接口实现向下转换,只需以下修改: ```rust,noplaypen +// src/object/mod.rs use core::fmt::Debug; use downcast_rs::{impl_downcast, DowncastSync}; @@ -206,6 +214,7 @@ impl_downcast!(sync KernelObject); `impl_downcast!` 宏用来帮我们自动生成转换函数,然后就可以用 `downcast_arc` 来对 `Arc` 做向下转换了。我们直接来测试一把: ```rust,noplaypen +// src/object/object.rs {{#include ../../zcore/src/object/object_v1.rs:downcast_test}} ``` @@ -244,12 +253,14 @@ test object::tests::dummy_object ... ok 而所谓的内部 struct,其实就是我们上面实现的 `DummyObject`。为了更好地体现它的功能,我们给他改个名叫 `KObjectBase`: ```rust,noplaypen +// src/object/mod.rs {{#include ../../zcore/src/object/mod.rs:base_def}} ``` 接下来我们把它的构造函数改为实现 `Default` trait,并且公共属性和方法都指定为 `pub`: ```rust,noplaypen +// src/object/mod.rs {{#include ../../zcore/src/object/mod.rs:base_default}} impl KObjectBase { /// 生成一个唯一的 ID @@ -264,24 +275,29 @@ impl KObjectBase { 最后来写一个魔法的宏! ```rust,noplaypen +// src/object/mod.rs {{#include ../../zcore/src/object/mod.rs:impl_kobject}} ``` 轮子已经造好了!让我们看看如何用它方便地实现一个内核对象,仍以 `DummyObject` 为例: ```rust,noplaypen +// src/object/mod.rs {{#include ../../zcore/src/object/mod.rs:dummy}} ``` 是不是方便了很多?最后按照惯例,用单元测试检验实现的正确性: ```rust,noplaypen +// src/object/mod.rs {{#include ../../zcore/src/object/mod.rs:dummy_test}} ``` -有兴趣的读者可以继续探索使用功能更强大的 **过程宏(proc_macro)**,进一步简化实现新内核对象所需的模板代码。 +有兴趣的读者可以继续探索使用功能更强大的 [**过程宏(proc_macro)**],进一步简化实现新内核对象所需的模板代码。 如果能把上面的代码块缩小成下面这两行,就更加完美了: +[**过程宏(proc_macro)**]: https://doc.rust-lang.org/proc_macro/index.html + ```rust,noplaypen #[KernelObject] pub struct DummyObject;