├── .github └── workflows │ ├── deploy.yml │ └── generate-pdf.yml ├── .gitignore ├── .gitmodules ├── LICENSE ├── Makefile ├── README.md ├── all.sh ├── make.bat ├── outline.md ├── puppeteerConfigFile.json ├── requirements.txt ├── scripts ├── deploy.yml.with-nodejs-chrome ├── fix-comments.py ├── latexpdf.patch └── mermaid.js ├── show.sh ├── source ├── _static │ ├── dracula.css │ └── my_style.css ├── appendix-a │ └── index.rst ├── appendix-b │ ├── clion_config.jpg │ └── index.rst ├── appendix-c │ └── index.rst ├── appendix-d │ ├── 1asm.rst │ ├── 2rv.rst │ └── index.rst ├── appendix-e │ └── index.rst ├── appendix-f │ └── index.rst ├── chapter0 │ ├── 0intro.rst │ ├── 1what-is-os.rst │ ├── 2os-interface.rst │ ├── 3os-hw-abstract.rst │ ├── 4os-features.rst │ ├── 5setup-devel-env.rst │ ├── 6hardware.rst.org │ ├── 7exercise.rst │ ├── 8answer.rst │ ├── EE.png │ ├── address-space.png │ ├── basic-EE.png │ ├── complex-EE.png │ ├── computer-hw-sw.png │ ├── context-of-process.png │ ├── context-switch.png │ ├── exception-old.png │ ├── exception.excalidraw │ ├── exception.png │ ├── file-disk.png │ ├── index.rst │ ├── interrupt.png │ ├── k210-final.gif │ ├── k210-final.png │ ├── prepare-sd.gif │ ├── prepare-sd.png │ ├── prog-illusion.png │ ├── qemu-final.gif │ ├── qemu-final.png │ ├── run-app.png │ └── syscall.png ├── chapter1 │ ├── 0intro.rst │ ├── 1app-ee-platform.rst │ ├── 2remove-std.rst │ ├── 3first-instruction-in-kernel1.rst │ ├── 4first-instruction-in-kernel2.rst │ ├── 5support-func-call.rst │ ├── 6print-and-shutdown-based-on-sbi.rst │ ├── 7exercise.rst │ ├── 8answer.rst │ ├── CallStack.png │ ├── MemoryLayout.png │ ├── StackFrame.png │ ├── app-software-stack.png │ ├── boot_stack.png │ ├── ch1.py │ ├── color-demo.png │ ├── function-call.png │ ├── index.rst │ ├── link-sections.excalidraw │ ├── link-sections.png │ ├── load-into-qemu.excalidraw │ └── load-into-qemu.png ├── chapter2 │ ├── 0intro.rst │ ├── 1rv-privilege.rst │ ├── 2application.rst │ ├── 3batch-system.rst │ ├── 4trap-handling.rst │ ├── 5exercise.rst │ ├── 6answer.rst │ ├── EnvironmentCallFlow.png │ ├── PrivilegeStack.png │ ├── ch2.py │ ├── deng-fish.png │ └── index.rst ├── chapter3 │ ├── 0intro.rst │ ├── 1multi-loader.rst │ ├── 2task-switching.rst │ ├── 3multiprogramming.rst │ ├── 4time-sharing-system.rst │ ├── 5exercise.rst │ ├── 6answer.rst │ ├── ch3.pptx │ ├── fsm-coop.png │ ├── index.rst │ ├── interrupts.png │ ├── multiprogramming.png │ ├── switch-1.png │ ├── switch-2.png │ ├── switch.excalidraw │ ├── switch.png │ ├── task-context.excalidraw │ ├── task-context.png │ └── task_context.png ├── chapter4 │ ├── 0intro.rst │ ├── 1rust-dynamic-allocation.rst │ ├── 2address-space.rst │ ├── 3sv39-implementation-1.rst │ ├── 4sv39-implementation-2.rst │ ├── 5kernel-app-spaces.rst │ ├── 6multitasking-based-on-as.rst │ ├── 7more-as.rst │ ├── 8exercise.rst │ ├── 9answer.rst │ ├── address-general.png │ ├── address-translation.png │ ├── app-as-full.png │ ├── clock-strategy.png │ ├── fifo-strategy.png │ ├── index.rst │ ├── kernel-as-high.png │ ├── kernel-as-low.png │ ├── linear-table.png │ ├── lru-strategy.png │ ├── mem-levels.png │ ├── overlay-tech.png │ ├── page-fault-rate-strategy.png │ ├── page-table.png │ ├── pte-rwx.png │ ├── rust-containers.png │ ├── satp.png │ ├── segmentation.png │ ├── simple-base-bound.png │ ├── sv39-full.png │ ├── sv39-pte.png │ ├── sv39-va-pa.png │ ├── swap-tech.png │ ├── trie-1.png │ ├── trie.png │ └── workingset-strategy.png ├── chapter5 │ ├── 0intro.rst │ ├── 1process.rst │ ├── 2core-data-structures.rst │ ├── 3implement-process-mechanism.rst │ ├── 4scheduling.rst │ ├── 5exercise.rst │ ├── 6answer.rst │ ├── deque-schedule.png │ ├── edf1.png │ ├── edf2.png │ ├── fcome-fserverd.png │ ├── index.rst │ ├── multi-core-schedule.png │ ├── pcb.png │ ├── queue-schedule.png │ ├── real-time-schedule.png │ ├── rms.png │ ├── round-robin-theory.png │ ├── sjf1.png │ └── sjf2.png ├── chapter6 │ ├── 0intro.rst │ ├── 1fs-interface.rst │ ├── 2fs-implementation.rst │ ├── 3using-easy-fs-in-kernel.rst │ ├── 4exercise.rst │ ├── 5answer.rst │ ├── ch6-fs.pptx │ ├── file-and-dir.png │ ├── file-open.png │ ├── filesystem-general.png │ ├── index.rst │ ├── simple-file-and-dir.png │ └── 文件系统布局.png ├── chapter7 │ ├── 0intro.rst │ ├── 1file-descriptor.rst │ ├── 2pipe.rst │ ├── 3cmdargs-and-redirection.rst │ ├── 4signal.rst │ ├── 5exercise.rst │ ├── 6answer.rst │ ├── index.rst │ ├── interprocess-communication.png │ ├── pipe-syscall.png │ ├── signal-ctrl-c.png │ ├── signal.png │ └── user-stack-cmdargs.png ├── chapter8 │ ├── 0intro.rst │ ├── 1thread-kernel.rst │ ├── 1thread.rst │ ├── 2lock.rst │ ├── 2lock.rst.backup │ ├── 3semaphore.rst │ ├── 4condition-variable.rst │ ├── 5concurrency-problem.rst │ ├── 6exercise.rst │ ├── 7answer.rst │ ├── adder-example-1.png │ ├── adder-example-2.png │ ├── adder-state-machine.png │ ├── app-as-full-with-threads.png │ ├── avoid-dead-lock.png │ ├── condvar-priority.png │ ├── dead-lock.png │ ├── index.rst │ ├── monitor-condvar.png │ ├── mpsc-problem.png │ ├── semaphore-sync.png │ ├── station.png │ └── thread-switch.png ├── chapter9 │ ├── 0intro.rst │ ├── 1io-interface.rst │ ├── 2device-driver-0.rst │ ├── 2device-driver-1.rst │ ├── 2device-driver-2.rst │ ├── 2device-driver-2.rst.org │ ├── 2device-driver-3.rst │ ├── 2device-driver-4.rst │ ├── 4exercise.rst │ ├── 5answer.rst │ ├── device-tree.png │ ├── dma-steps.png │ ├── index.rst │ ├── interrupt-steps.png │ ├── io-arch-in-pc.png │ ├── io-comm-mode.png │ ├── stream-queue.png │ ├── stream.png │ ├── uart-drive.png │ ├── virtio-arch.png │ ├── virtio-blk.png │ ├── virtio-cpu-device-io.png │ ├── virtio-cpu-device-io2.png │ ├── virtio-simple-arch.png │ ├── virtio-test-example.png │ ├── virtio-test-example2.png │ └── vring.png ├── conf.py ├── final-lab.rst ├── index.rst ├── log.rst ├── pygments-coloring.txt ├── resources │ ├── test.gif │ └── test.png ├── rest-example.rst ├── setup-sphinx.rst └── terminology.rst └── todo.md /.github/workflows/deploy.yml: -------------------------------------------------------------------------------- 1 | name: Deploy 2 | 3 | on: 4 | push: 5 | branches: [main, dev] 6 | 7 | jobs: 8 | deploy-doc: 9 | runs-on: ubuntu-latest 10 | 11 | steps: 12 | - uses: actions/checkout@v2 13 | with: 14 | submodules: "true" 15 | - uses: actions/setup-python@v2 16 | with: 17 | python-version: "3.10" 18 | - name: Install dependencies 19 | run: pip install -r requirements.txt 20 | 21 | - name: build doc 22 | run: | 23 | make html 24 | cp scripts/mermaid.js build/html/_static/ 25 | 26 | - name: create .nojekyll 27 | run: touch build/html/.nojekyll 28 | 29 | - name: Push to gh-pages 30 | uses: peaceiris/actions-gh-pages@v3 31 | with: 32 | github_token: ${{ secrets.GITHUB_TOKEN }} 33 | publish_dir: ./build/html 34 | -------------------------------------------------------------------------------- /.github/workflows/generate-pdf.yml: -------------------------------------------------------------------------------- 1 | name: Generate Tutorial PDF 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | branches: 9 | - main 10 | 11 | jobs: 12 | build: 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - uses: actions/checkout@v2 17 | with: 18 | submodules: 'recursive' 19 | 20 | - name: Setup Environment 21 | run: | 22 | sudo apt update 23 | sudo apt install -y latexmk texlive-latex-recommended texlive-latex-extra texlive-xetex fonts-freefont-otf texlive-fonts-recommended texlive-lang-chinese tex-gyre 24 | curl -fsSL https://deb.nodesource.com/setup_current.x | sudo -E bash - 25 | sudo apt-get install -y nodejs 26 | npm install -g @mermaid-js/mermaid-cli 27 | sudo apt-get install -y python3-sphinx 28 | sudo apt-get install -y python3-pip 29 | 30 | - name: Apply Patch 31 | run: | 32 | git apply --reject scripts/latexpdf.patch 33 | 34 | - name: Install Python Dependencies 35 | run: | 36 | pip install -r requirements.txt 37 | 38 | - name: Generate PDF 39 | run: | 40 | make latexpdf 41 | 42 | - name: Upload PDF to Artifacts 43 | uses: actions/upload-artifact@v4 44 | with: 45 | name: tutorial-pdf 46 | path: build/latex/rcore-tutorial-book-v3.pdf 47 | 48 | - name: Get Current Date and Time 49 | id: datetime 50 | run: echo "::set-output name=datetime::$(date +'%Y%m%d-%H%M')" 51 | 52 | - name: Create Release 53 | id: create_release 54 | uses: actions/create-release@v1 55 | env: 56 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 57 | with: 58 | tag_name: ${{ steps.datetime.outputs.datetime }} 59 | release_name: Release ${{ steps.datetime.outputs.datetime }} 60 | draft: false 61 | prerelease: false 62 | 63 | - name: Upload PDF to Release 64 | uses: actions/upload-release-asset@v1 65 | env: 66 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 67 | with: 68 | upload_url: ${{ steps.create_release.outputs.upload_url }} 69 | asset_path: ./build/latex/rcore-tutorial-book-v3.pdf 70 | asset_name: rcore-tutorial-book-v3.pdf 71 | asset_content_type: application/pdf 72 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | .vscode/ 3 | .idea 4 | source/_build/ 5 | pushall.sh 6 | os-lectures 7 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "os-lectures"] 2 | path = os-lectures 3 | url = git@github.com:LearningOS/os-lectures.git 4 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line, and also 5 | # from the environment for the first two. 6 | SPHINXOPTS ?= -W 7 | SPHINXBUILD ?= sphinx-build 8 | SPHINXAUTOBUILD ?= sphinx-autobuild 9 | SOURCEDIR = source 10 | BUILDDIR = build 11 | 12 | # Put it first so that "make" without argument is like "make help". 13 | help: 14 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 15 | 16 | html: 17 | @$(SPHINXBUILD) -M html "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 18 | @cp scripts/mermaid.js build/html/_static/ 19 | 20 | .PHONY: help html Makefile deploy liveview 21 | 22 | # Catch-all target: route all unknown targets to Sphinx using the new 23 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 24 | %: Makefile 25 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 26 | 27 | view: 28 | make html && firefox build/html/index.html 29 | 30 | # http://127.0.0.1:8000 31 | liveview: 32 | @$(SPHINXAUTOBUILD) "$(SOURCEDIR)" "$(BUILDDIR)/html" 33 | 34 | deploy: 35 | @make clean 36 | @make html 37 | @cp scripts/mermaid.js build/html/_static/ 38 | @python3 scripts/fix-comments.py 39 | @rm -rf docs 40 | @cp -r build/html docs 41 | @touch docs/.nojekyll 42 | @git add -A 43 | @git commit -m "Deploy" 44 | @git push 45 | 46 | htmlpath: 47 | echo file://$(PWD)/build/html/index.html 48 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # rCore-Tutorial-Book-v3 2 | Documentation of rCore-Tutorial version 3 in Chinese. 3 | 4 | ## news 5 | 6 | - 2022.07.01 Welcome to JOIN [**Open-Source-OS-Training-Camp-2022 !**](https://learningos.github.io/rust-based-os-comp2022/) 7 | 8 | ## [Deployed Page](https://rcore-os.github.io/rCore-Tutorial-Book-v3/). 9 | 10 | If you cannot access `github.io` normally due to network problems, please visit the [synchronized version](http://wyfcyx.gitee.io/rcore-tutorial-book-v3) hosted on gitee. 11 | 12 | ## Deploy your own docs 13 | 14 | ```sh 15 | $ FORK https://github.com/rcore-os/rCore-Tutorial-Book-v3.git to YOUR REPO 16 | $ git clone YOUR REPO(e.g. https://github.com/YOUR/rCore-Tutorial-Book-v3.git) 17 | $ cd rCore-Tutorial-Book-v3 18 | $ make html # After that, the generated doc can be found in rCore-Tutorial-Book-v3/build/html 19 | $ # modify the doc 20 | $ git push # or pull request 21 | ``` 22 | -------------------------------------------------------------------------------- /all.sh: -------------------------------------------------------------------------------- 1 | make clean && make html && google-chrome build/html/index.html 2 | 3 | -------------------------------------------------------------------------------- /make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | pushd %~dp0 4 | 5 | REM Command file for Sphinx documentation 6 | 7 | if "%SPHINXBUILD%" == "" ( 8 | set SPHINXBUILD=sphinx-build 9 | ) 10 | set SOURCEDIR=source 11 | set BUILDDIR=build 12 | 13 | if "%1" == "" goto help 14 | 15 | %SPHINXBUILD% >NUL 2>NUL 16 | if errorlevel 9009 ( 17 | echo. 18 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 19 | echo.installed, then set the SPHINXBUILD environment variable to point 20 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 21 | echo.may add the Sphinx directory to PATH. 22 | echo. 23 | echo.If you don't have Sphinx installed, grab it from 24 | echo.http://sphinx-doc.org/ 25 | exit /b 1 26 | ) 27 | 28 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 29 | goto end 30 | 31 | :help 32 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 33 | 34 | :end 35 | popd 36 | -------------------------------------------------------------------------------- /outline.md: -------------------------------------------------------------------------------- 1 | # 更新记录 2 | ### 2021-01-04更新: 3 | 4 | Chaptter4 添加实现的过程描述:改进内存隔离的好处; 5 | 6 | ### 2020-12-20更新: 7 | 8 | 将文件描述符从 Chapter7 移动到 Chapter6。 9 | 10 | ### 2020-12-02更新: 11 | 12 | 根据讨论更新了 Chapter1-Chapter7 到分割线之前的内容作为 Tutorial 的第一部分,即让系统能够将所有的资源都利用起来。第二部分则讨论如何做的更好。在 12 月 26 日之前尽可能按照大纲完成多个不同版本的 demo。 13 | 14 | [https://shimo.im/sheets/wV3VVxl04EieK3y1/MODOC](https://shimo.im/sheets/wV3VVxl04EieK3y1/MODOC)是目前的系统调用一览表,预计只需要实现 14 个系统调用就能初步满足要求。 15 | 16 | ### 2020-11-30更新: 17 | 18 | 更新了Chapter2。 19 | 20 | 合并了Chapter3/Chapter4为Chapter3,目前覆盖范围为Chapter1-Chapter5。 21 | 22 | ### lab 设计:2020-11-01 23 | 24 | #### 可能的章节与代码风格 25 | 26 | * 新 OS 实验的目的是:“**强化学生对 OS 的整体观念**”。OS的目的是满足应用需求,为此需要一定的硬件支持和自身逐步增强的功能。鼓励学生自己从头写(有参考实现)、强化整体观、step-by-step。 27 | * **整个文档的风格是应用**导向的,每个 step 的任务一定不是凭空而来、而是**应用**的需求。每一章都是为了解决一个应用具体需求而要求OS要完成的功能,这个功能需要一定的硬件支持。 28 | * 每个章节给出完整可运行且带有完整注释(可以通过 rustdoc 工具生成 html 版)的代码。 29 | * 文档中给出重要的代码片段(照顾到纸质版的读者,事实上在网页版给出代码的链接即可)而并不需要完整的代码,但是需要有完整的执行流程叙述,对于边界条件有足够的讨论。在文档中插入的代码不带有注释,而是将解释放到文档的文字部分。 30 | * 类似xv6,每一章的小节描述一项小功能是如何实现的,不同小节之间可能有一定的先后关系,也有可能是并列的。 31 | * 尽可能讲清楚设计背后的思想与优缺点。 32 | * 在讲解OS设计方面,尽量做到与语言无关。在讲解例子的时候,应该有对应的C和rust版本。 33 | * 在某些具体例子中,最好能体现rust比c强 34 | * 2020-10-28:前几章 Chapter1-4 需要等具体实现出来之后再规划章节。 35 | 36 | # 章节大纲 37 | ## Chapter0 Hello world! 之旅(偏概述) 38 | 39 | ### 主要动机: 40 | 41 | 参考 csapp 第一章,站在一个相对宏观的视角解释一个非常简单的 hello world! 程序是在哪些硬件/软件的支持下得以编译/运行起来的。 42 | 43 | helloworld.c 如何被编译器编译成执行程序,且如何被操作系统执行的。 44 | 45 | gcc 46 | 47 | strace 48 | 49 | ## Chapter1 裸机应用(优先级1) 50 | 51 | ### 主要动机 52 | 53 | 支持应用进行计算与结果输出。 54 | 55 | 在裸机上输出 Hello world,就像在其他 OS 上一样。 56 | 57 | app列表: 58 | 59 | * hello_world:输出字符串 60 | * count_sum:累加一维数组的和,并输出结果 61 | 62 | 备注:不需要输入功能 63 | 64 | ### 内核应完成功能 65 | 66 | 内存地址空间: 67 | 68 | 知道自己在内存的哪个位置。理解编译器生成的代码。 69 | 70 | init:基本初始化 71 | 72 | 主要是硬件加电后的硬件初始化,以前是OS做,后面给BIOS, bootloader等完成初步初始化。OS需要知道内存大小,IO分布。 73 | 74 | write函数:输出字符串 75 | 76 | 驱动串口的初始化,能够通过串口输出。 77 | 78 | exit函数:表明程序结束 79 | 80 | 其它(不是主要的): 81 | 82 | 在 qemu/k210 平台上基于 RustSBI 跳转到内核,打印调试信息,支持内核堆内存分配。 83 | 84 | ### 章节分布 85 | 86 | 基本上和第二版/第三版一致。注意需要考虑上面的应用和功能。 87 | 88 | ## Chapter2批处理系统(优先级1) 89 | 90 | ### 主要动机 91 | 92 | 内核不会被应用程序破坏 93 | 94 | ### 用户程序 95 | 96 | 支持应用进行计算与结果输出。在裸机上输出 Hello world,就像在其他 OS 上一样。但应用程序无法破坏内核,但能得到内核的服务。 97 | 98 | app列表: 99 | 100 | * hello_world:输出字符串。 101 | * count_sum:累加一维数组的和,并输出结果。 102 | ### 内核应完成功能 103 | 104 | 设置好内核和用户运行的栈,内核初始化完成后通过 sret 跳转到用户程序进行执行,然后在用户程序系统调用的时候完成特权级切换、上下文保存/恢复及栈的切换 105 | 106 | 按顺序加载运行多个应用程序。当应用程序出错(非法指令基于 RustSBI 不容易完成,比如访问非法的物理地址)之后直接杀死应用程序并切换到下一个。 107 | 108 | ### 新增系统调用 109 | 110 | * sys_write:向串口写 111 | * sys_exit: 表明任务结束。 112 | ### 实现备注 113 | 114 | 将编译之后的用户镜像和内核打包到一起放到内存上 115 | 116 | 分离用户和内核特权级,保护OS,用户需要请求内核提供的服务 117 | 118 | ## 119 | ## Chapter3 分时多任务系统之一非抢占式调度(优先级1) 120 | 121 | ### 主要动机 122 | 123 | 提高整个应用的CPU利用率 124 | 125 | 多任务,因此需要实现任务切换,可采用如下方法: 126 | 127 | * 批处理:在内存中放多个程序,执行完一个再执行下一个。当执行IO操作时,采用的是忙等的方式,效率差。 128 | * 非抢占切换:CPU和I/O设备之间速度不匹配矛盾,程序之间的公平性。当一个程序主动要求暂停或退出时,换另外一个程序执行CPU计算。 129 | 130 | *>> 这时,可能需要引入中断(但中断不是本章主要的内容,如果不引入更好)。* 131 | 132 | ### 用户程序 133 | 134 | 两个程序放置在一个不同的固定的物理地址上(这样不需要页表机制等虚存能力),完成的功能为:一个程序完成一些计算&输出,主动暂停,OS切换到另外一个程序执行,交替运行。 135 | 136 | * count_multiplication:一维数组的乘法,并输出结果 137 | * count_sum:累加一维数组的和,并输出结果 138 | * [wyf 的具体实现]三个输出小程序,详见[here](https://github.com/rcore-os/rCore-Tutorial-v3/tree/ch3-coop/user/src/bin) 139 | ### 内核应完成功能 140 | 141 | 实现通过 sys_yield 交出当前任务的 CPU 所有权,通过 sys_exit 表明任务结束。需要为每个任务分配一个用户栈和内核栈,且需要实现类似 switch 用来任务切换的函数。 142 | 143 | * sys_yield:让出CPU 144 | * sys_exit:退出当前任务并让出 CPU 145 | ### 实现备注 146 | 147 | 重点是实现switch 148 | 149 | 当所有任务运行结束后退出内核 150 | 151 | ## Chapter3 分时多任务系统之二 抢占式调度(优先级1) 152 | 153 | ### 主要动机 154 | 155 | 进一步提高整个应用的CPU利用率/交互性与任务之间的公平性 156 | 157 | 因此需要实现强制任务切换,并引入中断,可采用如下方法: 158 | 159 | * 时钟中断:基于时间片进行调度 160 | * (不在这里引入)串口中断:在发出输出请求后,不是轮询忙等,而是中断方式响应 161 | ### 用户程序 162 | 163 | * [wyf 的具体实现]三个计算质数幂次的小程序,外加一个 sleep 的程序。[here](https://github.com/rcore-os/rCore-Tutorial-v3/tree/ch3/user/src/bin) 164 | ### 内核应完成功能 165 | 166 | 实现时钟/串口中断处理,以及基于中断的基本时间片轮转调度 167 | 168 | ### 新增系统调用 169 | 170 | * sys_get_time:返回当前的 CPU 时钟周期数 171 | ## Chapter4 内存隔离安全性:地址空间(优先级1) 172 | 173 | ### 主要动机 174 | 175 | * 更好地支持应用(包括内核)的动态内存需求。首先:在内核态实现动态内存分配(这是物理内存),这样引入了堆的概念 176 | * 更好地支持在内核中对非法地址的访问的检查。在内核态实现页表机制,这样内核访问异常地址也能及时报警。 177 | * 提高应用间的安全性(通过页机制实现隔离) 178 | * 附带好处:应用程序地址空间可以相同,便于应用程序的开发 179 | ### 用户程序 180 | 181 | 应用程序与上一章基本相同,只不过应用程序的地址空间起始位置应该相同。而且这一章需要将 ELF 链接进内核而不是二进制镜像。 182 | 183 | 特别的,可以设置访问其他应用程序地址空间或是访问内核地址空间的应用程序,内核会将其杀死。 184 | 185 | 在用户库使用 sbrk 申请动态分配空间而不是放在数据段中。 186 | 187 | ### 内核应完成功能 188 | 189 | * 内核动态内存分配器(对于 Rust 而言,对于 C 仍可以考虑静态分配) 190 | * 物理页帧分配器 191 | * 页表机制,特别是用户和内核地址空间的隔离(参考 xv6) 192 | * ELF 解析和加载(在内核初始化的时候完成全部的地址空间创建和加载即可) 193 | ### 新增系统调用 194 | 195 | * sys_sbrk:拓展或缩减当前应用程序的堆空间大小 196 | ### 建议实现过程: 197 | 198 | 1. 在Chapter1的基础上实现基本的物理内存管理机制,即连续内存的动态分配。 199 | 2. 在Chapter1的基础上实现基本的页表机制。 200 | 3. 然后再合并到Chapter3上。 201 | ## Chapter5 进程及重要系统调用(优先级1) 202 | 203 | ### 主要动机 204 | 205 | 应用以进程的方式进行运行,简化了应用开发的负担,OS也更好管理 206 | 207 | 引入重要的进程概念,整合Chapt1~4的内容抽象出进程,实现一系列相关机制及 syscall 208 | 209 | ### 用户程序 210 | 211 | shell程序 user_shell以及一些相应的测试 212 | 213 | ### 内核应完成功能 214 | 215 | 实现完整的子进程机制,初始化第一个用户进程 initproc。 216 | 217 | ### 新增系统调用 218 | 219 | * sys_fork 220 | * sys_wait(轮询版) 221 | * sys_exec 222 | * sys_getpid 223 | * sys_yield更新 224 | * sys_exit 更新 225 | * sys_read:终端需要从串口读取命令 226 | ## Chapter6 文件系统与进程间通信(优先级1) 227 | 228 | ### 主要动机 229 | 230 | 进程之间需要进行一些协作。本章主要是通过管道进行通信。 231 | 232 | 同时,需要引入文件系统,并通过文件描述符来访问对应类型的 Unix 资源。 233 | 234 | ### 用户程序 235 | 236 | 简单的通过 fork 和子进程共享管道的测试; 237 | 238 | 【可选】强化shell程序的功能,支持使用 | 进行管道连接。 239 | 240 | ### 内核应完成功能 241 | 242 | 实现管道。 243 | 244 | 将字符设备(标准输入/输出)和管道封装为通过文件描述符访问的文件。 245 | 246 | ### 新增系统调用 247 | 248 | * sys_pipe:目前对于管道的 read/write 只需实现轮询版本。 249 | * sys_close:作用是关闭管道 250 | ## Chapter7 数据持久化(优先级1) 251 | 252 | ### 主要动机 253 | 254 | 实现数据持久化存储。 255 | 256 | ### 用户程序 257 | 258 | 多种不同大小的文件读写。 259 | 260 | ### 内核应完成功能 261 | 262 | 实现另一种在块设备上持久化存储的文件。 263 | 264 | 文件系统不需要实现目录。 265 | 266 | ### 新增系统调用 267 | 268 | * sys_open:创建或打开一个文件 269 | # ----------------------------分割线------------------------------------------------- 270 | 271 | ## Chapter6 单核同步互斥(优先级1,需要划分为单核/多核两部分) 272 | 273 | ### 主要动机: 274 | 275 | 应用之间需要在操作系统的帮助下有序共享资源(如串口,内存等)。 276 | 277 | 解释内核中已有的同步互斥问题,并实现阻塞机制。 278 | 279 | ### 内核应完成功能: 280 | 281 | 实现死锁检测机制,并基于阻塞机制实现 sys_sleep 和 sys_wait 以及 sys_kill 282 | 283 | ### 新增系统调用: 284 | 285 | sys_sleep 以及 sys_wait/sys_kill 的更新 286 | 287 | ### 章节分布: 288 | 289 | #### 基于原子指令实现自旋锁 290 | 291 | * 讨论并发冲突的来源(单核/多核) 292 | * 关中断/自旋/自旋关中断锁各自什么情况下能起作用,在课上还讲到一种获取锁失败直接 yield 的锁 293 | * 原子指令与内存一致性模型简介 294 | * 具体实现 295 | * 需要说明的是,课上的锁是针对于同一时刻只能有一个进程处于临界区之内。但是 Rust 风格的锁,也就是 Mutex 更加类似于一个管程(尽管 Rust 语言并没有这个概念),它用来保护一个数据结构,保证同一时间只有一个进程对于这个数据结构进行操作,自然保证了一致性。而 xv6 里面的锁只能保护临界区,相对而言对于数据结构一致性的保护就需要更加复杂的讨论。 296 | #### 死锁检测 297 | 298 | #### 阻塞的同步原语:条件变量 299 | 300 | 简单讨论一下其他的同步原语。 301 | 302 | * 课上提到的信号量和互斥量(后者是前者的特例)保护的都是某一个临界区 303 | #### 基于条件变量实现 sys_sleep 304 | 305 | #### 基于条件变量重新实现 sys_wait 306 | 307 | #### 更新 sys_kill 使得支持 kill 掉正在阻塞的进程 308 | 309 | ## ChapterX IPC(优先级1) 310 | 311 | ### 主要动机: 312 | 313 | 应用之间需要交换信息 314 | 315 | ### 内核应完成功能: 316 | 317 | * pipe 318 | * shared mem 319 | ### 新增系统调用: 320 | 321 | ## Chapter8 设备驱动(优先级2) 322 | 323 | ### 主要动机: 324 | 325 | 应用可以把I/O 设备用起来。 326 | 327 | ### 内核应完成功能: 328 | 329 | 实现块设备驱动和串口驱动,理解同步/异步两种驱动实现方式 330 | 331 | #### 背景知识:设备驱动、设备寄存器、轮询、中断 332 | 333 | #### 设备树(可选) 334 | 335 | #### 实现 virtio_disk 块设备的块读写(同步+轮询风格) 336 | 337 | #### 实现 virtio_disk 块设备的块读写(异步+中断风格) 338 | 339 | #### 实现串口设备的异步输入和同步输出 340 | 341 | * 参考 xv6,可以在内核里面维护一个 FIFO,这样即使串口本身没有 FIFO 也可以 342 | ## Chapter9 Unix 资源:文件(优先级1) 343 | 344 | ### 主要动机: 345 | 346 | 应用可以通过单一接口(文件)访问磁盘来保存信息和访问其他外设 347 | 348 | Unix 万物皆文件,将文件作为进程可以访问的内核资源单位 349 | 350 | ### 内核应完成功能: 351 | 352 | 支持三种不同的 Unix 资源:字符设备(串口)、块设备(文件系统)、管道 353 | 354 | ### 新增系统调用: 355 | 356 | sys_open/sys_close 357 | 358 | ### 背景知识:Unix 万物皆文件/进程对于文件的访问方式 359 | 360 | #### file 抽象接口 361 | 362 | * 支持 read/write 两种操作,表示 file 到地址空间中一块缓冲区的读写操作 363 | #### 字符设备路线 364 | 365 | * 直接将串口设备驱动封装一下即可。 366 | #### 文件系统路线 367 | 368 | * 分成多个子章节,等实现出来之后才知道怎么写 369 | #### 管道路线 370 | 371 | * 一个非常经典的读者/写者问题。 372 | ### ChapterX 虚存管理(优先级2) 373 | 374 | ### 主要动机: 375 | 376 | 提高应用执行的效率(侧重内存) 377 | 378 | - 支持物理内存不够的情况 379 | 380 | - copy on write 381 | 382 | ### 内核应完成功能: 383 | 384 | ### 新增系统调用: 385 | 386 | 387 | 388 | ### Chapter10 多核(可选) 389 | 390 | ### 主要动机: 391 | 392 | 提高应用执行的并行执行效率(侧重多处理器) 393 | 394 | ### 内核应完成功能: 395 | 396 | ### 新增系统调用: 397 | 398 | #### 多核启动与 IPI 399 | 400 | #### 多核调度 401 | 402 | ### Chapter11多核下的同步互斥(可选) 403 | 404 | ### 主要动机: 405 | 406 | 提高应用并行执行下的正确性(侧重多处理器) 407 | 408 | ### 内核应完成功能: 409 | 410 | ### 新增系统调用: 411 | 412 | #### 多核启动与 IPI 413 | 414 | #### 多核调度 415 | 416 | ## Appendix A Rust 语言快速入门与练习题 417 | 418 | ## Appendix B 常见构建工具的使用方法 419 | 420 | 比如 Makefile\ld 等。 421 | 422 | ## Appendix C RustSBI 与 Kendryte K210 兼容性设计 423 | 424 | ## 其他附录… 425 | 426 | -------------------------------------------------------------------------------- /puppeteerConfigFile.json: -------------------------------------------------------------------------------- 1 | { 2 | "executablePath": "/usr/bin/google-chrome" 3 | } 4 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | alabaster==0.7.13 2 | Babel==2.11.0 3 | certifi==2022.12.7 4 | charset-normalizer==2.1.1 5 | docutils==0.16 6 | idna==3.4 7 | imagesize==1.4.1 8 | jieba==0.42.1 9 | Jinja2==3.1.2 10 | MarkupSafe==2.1.1 11 | packaging==23.0 12 | Pygments==2.14.0 13 | pyparsing==3.0.9 14 | pytz==2022.7 15 | requests==2.28.2 16 | snowballstemmer==2.2.0 17 | Sphinx==4.3.2 18 | sphinx-comments==0.0.3 19 | sphinx-rtd-theme==1.2.0rc2 20 | sphinx-tabs==3.2 21 | sphinxcontrib-applehelp==1.0.2 22 | sphinxcontrib-devhelp==1.0.2 23 | sphinxcontrib-htmlhelp==2.0.0 24 | sphinxcontrib-jsmath==1.0.1 25 | sphinxcontrib-qthelp==1.0.3 26 | sphinxcontrib-serializinghtml==1.1.5 27 | urllib3==1.26.14 28 | furo==2022.6.21 29 | sphinxcontrib-mermaid==0.7.1 -------------------------------------------------------------------------------- /scripts/deploy.yml.with-nodejs-chrome: -------------------------------------------------------------------------------- 1 | name: Deploy 2 | 3 | on: 4 | push: 5 | branches: [main, dev] 6 | 7 | jobs: 8 | deploy-doc: 9 | runs-on: ubuntu-latest 10 | 11 | steps: 12 | - uses: actions/checkout@v2 13 | with: 14 | submodules: "true" 15 | - uses: actions/setup-python@v2 16 | with: 17 | python-version: "3.10" 18 | - name: Install dependencies 19 | run: pip install -r requirements.txt 20 | 21 | - name: install chrome 22 | run: apt-get update \ 23 | && apt-get install -y wget gnupg \ 24 | && wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - \ 25 | && sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list' \ 26 | && apt-get update \ 27 | && apt-get install -y google-chrome-stable fonts-ipafont-gothic fonts-wqy-zenhei fonts-thai-tlwg fonts-kacst fonts-freefont-ttf libxss1 \ 28 | --no-install-recommends \ 29 | && rm -rf /var/lib/apt/lists/* 30 | 31 | - name: Use Node.js 32 | uses: actions/setup-node@v2 33 | with: 34 | node-version: "16.x" 35 | 36 | - name: Install dependencies 37 | run: npm install -g @mermaid-js/mermaid-cli 38 | 39 | - name: build doc 40 | run: make html 41 | 42 | - name: create .nojekyll 43 | run: touch build/html/.nojekyll 44 | 45 | - name: Push to gh-pages 46 | uses: peaceiris/actions-gh-pages@v3 47 | with: 48 | github_token: ${{ secrets.GITHUB_TOKEN }} 49 | publish_dir: ./build/html 50 | -------------------------------------------------------------------------------- /scripts/fix-comments.py: -------------------------------------------------------------------------------- 1 | # See #91. 2 | # Solution: if selector div.section cannot be found in a page, changing the pattern from div:section to 3 | # div > section can be a reasonable idea after observation. 4 | import os 5 | html_list = [] 6 | def collect_html(path): 7 | for item in os.listdir(path): 8 | new_path = path + '/' + item 9 | if os.path.isdir(new_path): 10 | collect_html(new_path) 11 | else: 12 | _, ext = os.path.splitext(new_path) 13 | if ext == '.html': 14 | html_list.append(new_path) 15 | 16 | collect_html('build/html') 17 | for html_file in html_list: 18 | html_content = "" 19 | with open(html_file, 'r') as f: 20 | html_content_lines = f.readlines() 21 | for line in html_content_lines: 22 | html_content += line 23 | if html_content.find('