Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Miykael_xxm
RCore Tutorial Book V3
提交
936c22ec
R
RCore Tutorial Book V3
项目概览
Miykael_xxm
/
RCore Tutorial Book V3
与 Fork 源项目一致
Fork自
rcore-os / RCore Tutorial Book V3
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
RCore Tutorial Book V3
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
936c22ec
编写于
1月 02, 2021
作者:
Y
Yifan Wu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Upload ch3.1.
上级
362d3295
变更
38
展开全部
隐藏空白更改
内联
并排
Showing
38 changed file
with
457 addition
and
50 deletion
+457
-50
docs/_sources/chapter3/1multi-loader.rst.txt
docs/_sources/chapter3/1multi-loader.rst.txt
+114
-1
docs/_sources/chapter3/index.rst.txt
docs/_sources/chapter3/index.rst.txt
+8
-1
docs/appendix-a/index.html
docs/appendix-a/index.html
+1
-1
docs/appendix-b/index.html
docs/appendix-b/index.html
+1
-1
docs/appendix-c/index.html
docs/appendix-c/index.html
+1
-1
docs/chapter1/1app-ee-platform.html
docs/chapter1/1app-ee-platform.html
+1
-1
docs/chapter1/2remove-std.html
docs/chapter1/2remove-std.html
+1
-1
docs/chapter1/3minimal-rt.html
docs/chapter1/3minimal-rt.html
+1
-1
docs/chapter1/4load-manually.html
docs/chapter1/4load-manually.html
+1
-1
docs/chapter1/5sbi-print.html
docs/chapter1/5sbi-print.html
+1
-1
docs/chapter1/6practice.html
docs/chapter1/6practice.html
+1
-1
docs/chapter1/index.html
docs/chapter1/index.html
+1
-1
docs/chapter2/1rv-privilege.html
docs/chapter2/1rv-privilege.html
+1
-1
docs/chapter2/2application.html
docs/chapter2/2application.html
+1
-1
docs/chapter2/3batch-system.html
docs/chapter2/3batch-system.html
+1
-1
docs/chapter2/4trap-handling.html
docs/chapter2/4trap-handling.html
+3
-3
docs/chapter2/index.html
docs/chapter2/index.html
+1
-1
docs/chapter3/1multi-loader.html
docs/chapter3/1multi-loader.html
+167
-6
docs/chapter3/2task-switching.html
docs/chapter3/2task-switching.html
+2
-2
docs/chapter3/3multiprogramming.html
docs/chapter3/3multiprogramming.html
+2
-2
docs/chapter3/4time-sharing-system.html
docs/chapter3/4time-sharing-system.html
+2
-2
docs/chapter3/index.html
docs/chapter3/index.html
+10
-4
docs/chapter4/index.html
docs/chapter4/index.html
+1
-1
docs/chapter5/index.html
docs/chapter5/index.html
+1
-1
docs/chapter6/index.html
docs/chapter6/index.html
+1
-1
docs/chapter7/index.html
docs/chapter7/index.html
+1
-1
docs/chapter8/index.html
docs/chapter8/index.html
+1
-1
docs/collaboration.html
docs/collaboration.html
+1
-1
docs/genindex.html
docs/genindex.html
+1
-1
docs/index.html
docs/index.html
+1
-1
docs/objects.inv
docs/objects.inv
+0
-0
docs/quickstart.html
docs/quickstart.html
+1
-1
docs/rest-example.html
docs/rest-example.html
+1
-1
docs/search.html
docs/search.html
+1
-1
docs/searchindex.js
docs/searchindex.js
+1
-1
docs/terminology.html
docs/terminology.html
+1
-1
source/chapter3/1multi-loader.rst
source/chapter3/1multi-loader.rst
+114
-1
source/chapter3/index.rst
source/chapter3/index.rst
+8
-1
未找到文件。
docs/_sources/chapter3/1multi-loader.rst.txt
浏览文件 @
936c22ec
...
...
@@ -2,5 +2,118 @@
=====================================
在本章的引言中我们提到每个应用都需要按照它的编号被分别加载到内存中不同的位置。本节我们就来介绍它是如何实现的。
更具体来说,
与第二章相同,所有应用的 ELF 都经过 strip 丢掉所有 ELF header 和符号变为二进制镜像文件,随后以同样的格式通过
``link_user.S`` 在编译的时候直接链接到内核的数据段中。不同的是,我们对相关模块进行了调整:在第二章中
应用的加载和进度控制都交给 ``batch`` 子模块,而在第三章中我们将应用的加载这部分功能分离出来在 ``loader``
子模块中实现,应用的执行和切换则交给 ``task`` 子模块。
应用的加载方式也和上一章不同。上一章的时候所有应用都被加载到一个固定的物理地址,也是因为这个原因,内存中同时
最多只能驻留一个应用,当它运行完毕或者出错退出的时候由 ``batch`` 子模块加载一个新的应用来替换掉它。本章中,
所有的应用在内核初始化的时候就一并被加载到内存中。为了避免覆盖,它们自然需要被加载到不同的物理地址。这是通过
调用 ``loader`` 子模块的 ``load_apps`` 函数实现的:
.. code-block:: rust
:linenos:
// os/src/loader.rs
pub fn load_apps() {
extern "C" { fn _num_app(); }
let num_app_ptr = _num_app as usize as *const usize;
let num_app = get_num_app();
let app_start = unsafe {
core::slice::from_raw_parts(num_app_ptr.add(1), num_app + 1)
};
// clear i-cache first
unsafe { llvm_asm!("fence.i" :::: "volatile"); }
// load apps
for i in 0..num_app {
let base_i = get_base_i(i);
// clear region
(base_i..base_i + APP_SIZE_LIMIT).for_each(|addr| unsafe {
(addr as *mut u8).write_volatile(0)
});
// load app from data section to memory
let src = unsafe {
core::slice::from_raw_parts(
app_start[i] as *const u8,
app_start[i + 1] - app_start[i]
)
};
let dst = unsafe {
core::slice::from_raw_parts_mut(base_i as *mut u8, src.len())
};
dst.copy_from_slice(src);
}
}
可以看出,第 :math:`i` 个应用被加载到以物理地址 ``base_i`` 开头的一段物理内存上,而 ``base_i`` 的
计算方式如下:
.. code-block:: rust
:linenos:
// os/src/loader.rs
fn get_base_i(app_id: usize) -> usize {
APP_BASE_ADDRESS + app_id * APP_SIZE_LIMIT
}
我们可以在 ``config`` 子模块中找到这两个常数。从这一章开始, ``config`` 子模块用来存放内核中所有的常数。看到
``APP_BASE_ADDRESS`` 被设置为 ``0x80100000`` ,而 ``APP_SIZE_LIMIT`` 和上一章一样被设置为
``0x20000`` ,也就是每个应用二进制镜像的大小限制。因此,应用的内存布局就很明朗了——就是从
``APP_BASE_ADDRESS`` 开始依次为每个应用预留一段空间。
注意,我们需要调整每个应用被构建时候使用的链接脚本 ``linker.ld`` 中的起始地址 ``BASE_ADDRESS`` 为它实际
会被内核加载并运行的地址。也就是要做到:应用知道自己会被加载到某个地址运行,而内核也确实能做到将它加载到那个
地址。这算是应用和内核在某种意义上达成的一种协议。之所以要有这么苛刻的条件,是因为应用和内核的能力都很弱,泛用性很低。
事实上,目前我们的应用是绝对位置而并不是位置无关的,内核也没有提供相应的重定位机制。
.. note::
可以在 `这里 <https://nju-projectn.github.io/ics-pa-gitbook/ics2020/4.2.html>`_ 找到更多有关
位置无关和重定位的说明。
由于每个应用被加载到的位置都不同,也就导致它们 ``linker.ld`` 中的 ``BASE_ADDRESS`` 都是不同的。实际上,
我们写了一个脚本 ``build.py`` 而不是直接 ``cargo build`` 构建应用:
.. code-block:: python
:linenos:
# user/build.py
import os
base_address = 0x80100000
step = 0x20000
linker = 'src/linker.ld'
app_id = 0
apps = os.listdir('src/bin')
apps.sort()
for app in apps:
app = app[:app.find('.')]
lines = []
lines_before = []
with open(linker, 'r') as f:
for line in f.readlines():
lines_before.append(line)
line = line.replace(hex(base_address), hex(base_address+step*app_id))
lines.append(line)
with open(linker, 'w+') as f:
f.writelines(lines)
os.system('cargo build --bin %s --release' % app)
print('[build.py] application %s start with address %s' %(app, hex(base_address+step*app_id)))
with open(linker, 'w+') as f:
f.writelines(lines_before)
app_id = app_id + 1
它的思路很简单,在遍历 ``app`` 的大循环里面只做了这样几件事情:
- 第 16~22 行,找到 ``src/linker.ld`` 中的 ``BASE_ADDRESS = 0x80100000;`` 这一行,并将后面的地址
替换为和当前应用对应的一个地址;
- 第 23 行,使用 ``cargo build`` 构建当前的应用,注意我们可以使用 ``--bin`` 参数来只构建某一个应用;
- 第 25~26 行,将 ``src/linker.ld`` 还原。
这样,我们就说明了多个应用是如何被构建和加载的。
docs/_sources/chapter3/index.rst.txt
浏览文件 @
936c22ec
第三章:多道程序与分时多任务
第三章:多道程序与分时多任务
系统
==============================================
.. toctree::
...
...
@@ -20,6 +20,13 @@
内存的不同区域中。由于目前我们只有一个 CPU,则同一时间最多只有一个应用在执行,剩下的应用则处于就绪状态,需要内核将 CPU 分配给它们才能
开始执行。因此,我们能够看到多个应用在一个 CPU 上交替执行的现象。
.. note::
读者也许会有疑问:由于只有一个 CPU,即使这样做,同一时间最多还是只能运行一个应用,还浪费了更多的内存来把所有
的应用都加载进来。那么这样做有什么意义呢?
读者可以带着这个问题继续看下去。后面我们会介绍这样做到底能够解决什么问题。
.. _term-multiprogramming:
.. _term-time-sharing-multitasking:
...
...
docs/appendix-a/index.html
浏览文件 @
936c22ec
...
...
@@ -123,7 +123,7 @@ commentsRunWhenDOMLoaded(addUtterances);
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../quickstart.html"
>
环境配置
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter1/index.html"
>
第一章:RV64 裸机应用
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter2/index.html"
>
第二章:批处理系统
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter3/index.html"
>
第三章:多道程序与分时多任务
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter3/index.html"
>
第三章:多道程序与分时多任务
系统
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter4/index.html"
>
第四章:内存隔离安全性
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter5/index.html"
>
第五章:进程及重要系统调用
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter6/index.html"
>
第六章:文件描述符与进程间通信
</a></li>
...
...
docs/appendix-b/index.html
浏览文件 @
936c22ec
...
...
@@ -123,7 +123,7 @@ commentsRunWhenDOMLoaded(addUtterances);
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../quickstart.html"
>
环境配置
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter1/index.html"
>
第一章:RV64 裸机应用
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter2/index.html"
>
第二章:批处理系统
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter3/index.html"
>
第三章:多道程序与分时多任务
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter3/index.html"
>
第三章:多道程序与分时多任务
系统
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter4/index.html"
>
第四章:内存隔离安全性
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter5/index.html"
>
第五章:进程及重要系统调用
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter6/index.html"
>
第六章:文件描述符与进程间通信
</a></li>
...
...
docs/appendix-c/index.html
浏览文件 @
936c22ec
...
...
@@ -123,7 +123,7 @@ commentsRunWhenDOMLoaded(addUtterances);
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../quickstart.html"
>
环境配置
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter1/index.html"
>
第一章:RV64 裸机应用
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter2/index.html"
>
第二章:批处理系统
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter3/index.html"
>
第三章:多道程序与分时多任务
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter3/index.html"
>
第三章:多道程序与分时多任务
系统
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter4/index.html"
>
第四章:内存隔离安全性
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter5/index.html"
>
第五章:进程及重要系统调用
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter6/index.html"
>
第六章:文件描述符与进程间通信
</a></li>
...
...
docs/chapter1/1app-ee-platform.html
浏览文件 @
936c22ec
...
...
@@ -136,7 +136,7 @@ commentsRunWhenDOMLoaded(addUtterances);
</ul>
</li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter2/index.html"
>
第二章:批处理系统
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter3/index.html"
>
第三章:多道程序与分时多任务
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter3/index.html"
>
第三章:多道程序与分时多任务
系统
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter4/index.html"
>
第四章:内存隔离安全性
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter5/index.html"
>
第五章:进程及重要系统调用
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter6/index.html"
>
第六章:文件描述符与进程间通信
</a></li>
...
...
docs/chapter1/2remove-std.html
浏览文件 @
936c22ec
...
...
@@ -136,7 +136,7 @@ commentsRunWhenDOMLoaded(addUtterances);
</ul>
</li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter2/index.html"
>
第二章:批处理系统
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter3/index.html"
>
第三章:多道程序与分时多任务
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter3/index.html"
>
第三章:多道程序与分时多任务
系统
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter4/index.html"
>
第四章:内存隔离安全性
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter5/index.html"
>
第五章:进程及重要系统调用
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter6/index.html"
>
第六章:文件描述符与进程间通信
</a></li>
...
...
docs/chapter1/3minimal-rt.html
浏览文件 @
936c22ec
...
...
@@ -137,7 +137,7 @@ commentsRunWhenDOMLoaded(addUtterances);
</ul>
</li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter2/index.html"
>
第二章:批处理系统
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter3/index.html"
>
第三章:多道程序与分时多任务
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter3/index.html"
>
第三章:多道程序与分时多任务
系统
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter4/index.html"
>
第四章:内存隔离安全性
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter5/index.html"
>
第五章:进程及重要系统调用
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter6/index.html"
>
第六章:文件描述符与进程间通信
</a></li>
...
...
docs/chapter1/4load-manually.html
浏览文件 @
936c22ec
...
...
@@ -136,7 +136,7 @@ commentsRunWhenDOMLoaded(addUtterances);
</ul>
</li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter2/index.html"
>
第二章:批处理系统
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter3/index.html"
>
第三章:多道程序与分时多任务
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter3/index.html"
>
第三章:多道程序与分时多任务
系统
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter4/index.html"
>
第四章:内存隔离安全性
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter5/index.html"
>
第五章:进程及重要系统调用
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter6/index.html"
>
第六章:文件描述符与进程间通信
</a></li>
...
...
docs/chapter1/5sbi-print.html
浏览文件 @
936c22ec
...
...
@@ -133,7 +133,7 @@ commentsRunWhenDOMLoaded(addUtterances);
</ul>
</li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter2/index.html"
>
第二章:批处理系统
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter3/index.html"
>
第三章:多道程序与分时多任务
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter3/index.html"
>
第三章:多道程序与分时多任务
系统
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter4/index.html"
>
第四章:内存隔离安全性
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter5/index.html"
>
第五章:进程及重要系统调用
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter6/index.html"
>
第六章:文件描述符与进程间通信
</a></li>
...
...
docs/chapter1/6practice.html
浏览文件 @
936c22ec
...
...
@@ -134,7 +134,7 @@ commentsRunWhenDOMLoaded(addUtterances);
</ul>
</li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter2/index.html"
>
第二章:批处理系统
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter3/index.html"
>
第三章:多道程序与分时多任务
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter3/index.html"
>
第三章:多道程序与分时多任务
系统
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter4/index.html"
>
第四章:内存隔离安全性
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter5/index.html"
>
第五章:进程及重要系统调用
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter6/index.html"
>
第六章:文件描述符与进程间通信
</a></li>
...
...
docs/chapter1/index.html
浏览文件 @
936c22ec
...
...
@@ -131,7 +131,7 @@ commentsRunWhenDOMLoaded(addUtterances);
</ul>
</li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter2/index.html"
>
第二章:批处理系统
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter3/index.html"
>
第三章:多道程序与分时多任务
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter3/index.html"
>
第三章:多道程序与分时多任务
系统
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter4/index.html"
>
第四章:内存隔离安全性
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter5/index.html"
>
第五章:进程及重要系统调用
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter6/index.html"
>
第六章:文件描述符与进程间通信
</a></li>
...
...
docs/chapter2/1rv-privilege.html
浏览文件 @
936c22ec
...
...
@@ -131,7 +131,7 @@ commentsRunWhenDOMLoaded(addUtterances);
<li
class=
"toctree-l2"
><a
class=
"reference internal"
href=
"4trap-handling.html"
>
处理 Trap
</a></li>
</ul>
</li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter3/index.html"
>
第三章:多道程序与分时多任务
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter3/index.html"
>
第三章:多道程序与分时多任务
系统
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter4/index.html"
>
第四章:内存隔离安全性
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter5/index.html"
>
第五章:进程及重要系统调用
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter6/index.html"
>
第六章:文件描述符与进程间通信
</a></li>
...
...
docs/chapter2/2application.html
浏览文件 @
936c22ec
...
...
@@ -135,7 +135,7 @@ commentsRunWhenDOMLoaded(addUtterances);
<li
class=
"toctree-l2"
><a
class=
"reference internal"
href=
"4trap-handling.html"
>
处理 Trap
</a></li>
</ul>
</li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter3/index.html"
>
第三章:多道程序与分时多任务
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter3/index.html"
>
第三章:多道程序与分时多任务
系统
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter4/index.html"
>
第四章:内存隔离安全性
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter5/index.html"
>
第五章:进程及重要系统调用
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter6/index.html"
>
第六章:文件描述符与进程间通信
</a></li>
...
...
docs/chapter2/3batch-system.html
浏览文件 @
936c22ec
...
...
@@ -133,7 +133,7 @@ commentsRunWhenDOMLoaded(addUtterances);
<li
class=
"toctree-l2"
><a
class=
"reference internal"
href=
"4trap-handling.html"
>
处理 Trap
</a></li>
</ul>
</li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter3/index.html"
>
第三章:多道程序与分时多任务
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter3/index.html"
>
第三章:多道程序与分时多任务
系统
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter4/index.html"
>
第四章:内存隔离安全性
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter5/index.html"
>
第五章:进程及重要系统调用
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter6/index.html"
>
第六章:文件描述符与进程间通信
</a></li>
...
...
docs/chapter2/4trap-handling.html
浏览文件 @
936c22ec
...
...
@@ -72,7 +72,7 @@ commentsRunWhenDOMLoaded(addUtterances);
<link
rel=
"index"
title=
"索引"
href=
"../genindex.html"
/>
<link
rel=
"search"
title=
"搜索"
href=
"../search.html"
/>
<link
rel=
"next"
title=
"第三章:多道程序与分时多任务"
href=
"../chapter3/index.html"
/>
<link
rel=
"next"
title=
"第三章:多道程序与分时多任务
系统
"
href=
"../chapter3/index.html"
/>
<link
rel=
"prev"
title=
"实现批处理系统"
href=
"3batch-system.html"
/>
</head>
...
...
@@ -136,7 +136,7 @@ commentsRunWhenDOMLoaded(addUtterances);
</li>
</ul>
</li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter3/index.html"
>
第三章:多道程序与分时多任务
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter3/index.html"
>
第三章:多道程序与分时多任务
系统
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter4/index.html"
>
第四章:内存隔离安全性
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter5/index.html"
>
第五章:进程及重要系统调用
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter6/index.html"
>
第六章:文件描述符与进程间通信
</a></li>
...
...
@@ -894,7 +894,7 @@ S 特权级,而它希望能够切换到 U 特权级。在 RISC-V 架构中,
<div
class=
"rst-footer-buttons"
role=
"navigation"
aria-label=
"footer navigation"
>
<a
href=
"../chapter3/index.html"
class=
"btn btn-neutral float-right"
title=
"第三章:多道程序与分时多任务"
accesskey=
"n"
rel=
"next"
>
Next
<span
class=
"fa fa-arrow-circle-right"
></span></a>
<a
href=
"../chapter3/index.html"
class=
"btn btn-neutral float-right"
title=
"第三章:多道程序与分时多任务
系统
"
accesskey=
"n"
rel=
"next"
>
Next
<span
class=
"fa fa-arrow-circle-right"
></span></a>
<a
href=
"3batch-system.html"
class=
"btn btn-neutral float-left"
title=
"实现批处理系统"
accesskey=
"p"
rel=
"prev"
><span
class=
"fa fa-arrow-circle-left"
></span>
Previous
</a>
...
...
docs/chapter2/index.html
浏览文件 @
936c22ec
...
...
@@ -129,7 +129,7 @@ commentsRunWhenDOMLoaded(addUtterances);
<li
class=
"toctree-l2"
><a
class=
"reference internal"
href=
"4trap-handling.html"
>
处理 Trap
</a></li>
</ul>
</li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter3/index.html"
>
第三章:多道程序与分时多任务
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter3/index.html"
>
第三章:多道程序与分时多任务
系统
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter4/index.html"
>
第四章:内存隔离安全性
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter5/index.html"
>
第五章:进程及重要系统调用
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter6/index.html"
>
第六章:文件描述符与进程间通信
</a></li>
...
...
docs/chapter3/1multi-loader.html
浏览文件 @
936c22ec
此差异已折叠。
点击以展开。
docs/chapter3/2task-switching.html
浏览文件 @
936c22ec
...
...
@@ -123,7 +123,7 @@ commentsRunWhenDOMLoaded(addUtterances);
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../quickstart.html"
>
环境配置
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter1/index.html"
>
第一章:RV64 裸机应用
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter2/index.html"
>
第二章:批处理系统
</a></li>
<li
class=
"toctree-l1 current"
><a
class=
"reference internal"
href=
"index.html"
>
第三章:多道程序与分时多任务
</a><ul
class=
"current"
>
<li
class=
"toctree-l1 current"
><a
class=
"reference internal"
href=
"index.html"
>
第三章:多道程序与分时多任务
系统
</a><ul
class=
"current"
>
<li
class=
"toctree-l2"
><a
class=
"reference internal"
href=
"1multi-loader.html"
>
多任务加载器
</a></li>
<li
class=
"toctree-l2 current"
><a
class=
"current reference internal"
href=
"#"
>
任务切换
</a></li>
<li
class=
"toctree-l2"
><a
class=
"reference internal"
href=
"3multiprogramming.html"
>
多道程序与协作式调度
</a></li>
...
...
@@ -196,7 +196,7 @@ commentsRunWhenDOMLoaded(addUtterances);
<li><a
href=
"../index.html"
class=
"icon icon-home"
></a>
»
</li>
<li><a
href=
"index.html"
>
第三章:多道程序与分时多任务
</a>
»
</li>
<li><a
href=
"index.html"
>
第三章:多道程序与分时多任务
系统
</a>
»
</li>
<li>
任务切换
</li>
...
...
docs/chapter3/3multiprogramming.html
浏览文件 @
936c22ec
...
...
@@ -123,7 +123,7 @@ commentsRunWhenDOMLoaded(addUtterances);
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../quickstart.html"
>
环境配置
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter1/index.html"
>
第一章:RV64 裸机应用
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter2/index.html"
>
第二章:批处理系统
</a></li>
<li
class=
"toctree-l1 current"
><a
class=
"reference internal"
href=
"index.html"
>
第三章:多道程序与分时多任务
</a><ul
class=
"current"
>
<li
class=
"toctree-l1 current"
><a
class=
"reference internal"
href=
"index.html"
>
第三章:多道程序与分时多任务
系统
</a><ul
class=
"current"
>
<li
class=
"toctree-l2"
><a
class=
"reference internal"
href=
"1multi-loader.html"
>
多任务加载器
</a></li>
<li
class=
"toctree-l2"
><a
class=
"reference internal"
href=
"2task-switching.html"
>
任务切换
</a></li>
<li
class=
"toctree-l2 current"
><a
class=
"current reference internal"
href=
"#"
>
多道程序与协作式调度
</a></li>
...
...
@@ -196,7 +196,7 @@ commentsRunWhenDOMLoaded(addUtterances);
<li><a
href=
"../index.html"
class=
"icon icon-home"
></a>
»
</li>
<li><a
href=
"index.html"
>
第三章:多道程序与分时多任务
</a>
»
</li>
<li><a
href=
"index.html"
>
第三章:多道程序与分时多任务
系统
</a>
»
</li>
<li>
多道程序与协作式调度
</li>
...
...
docs/chapter3/4time-sharing-system.html
浏览文件 @
936c22ec
...
...
@@ -123,7 +123,7 @@ commentsRunWhenDOMLoaded(addUtterances);
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../quickstart.html"
>
环境配置
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter1/index.html"
>
第一章:RV64 裸机应用
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter2/index.html"
>
第二章:批处理系统
</a></li>
<li
class=
"toctree-l1 current"
><a
class=
"reference internal"
href=
"index.html"
>
第三章:多道程序与分时多任务
</a><ul
class=
"current"
>
<li
class=
"toctree-l1 current"
><a
class=
"reference internal"
href=
"index.html"
>
第三章:多道程序与分时多任务
系统
</a><ul
class=
"current"
>
<li
class=
"toctree-l2"
><a
class=
"reference internal"
href=
"1multi-loader.html"
>
多任务加载器
</a></li>
<li
class=
"toctree-l2"
><a
class=
"reference internal"
href=
"2task-switching.html"
>
任务切换
</a></li>
<li
class=
"toctree-l2"
><a
class=
"reference internal"
href=
"3multiprogramming.html"
>
多道程序与协作式调度
</a></li>
...
...
@@ -196,7 +196,7 @@ commentsRunWhenDOMLoaded(addUtterances);
<li><a
href=
"../index.html"
class=
"icon icon-home"
></a>
»
</li>
<li><a
href=
"index.html"
>
第三章:多道程序与分时多任务
</a>
»
</li>
<li><a
href=
"index.html"
>
第三章:多道程序与分时多任务
系统
</a>
»
</li>
<li>
分时多任务系统与抢占式调度
</li>
...
...
docs/chapter3/index.html
浏览文件 @
936c22ec
...
...
@@ -7,7 +7,7 @@
<meta
name=
"viewport"
content=
"width=device-width, initial-scale=1.0"
>
<title>
第三章:多道程序与分时多任务
—
rCore-Tutorial-Book-v3 0.1 文档
</title>
<title>
第三章:多道程序与分时多任务
系统
—
rCore-Tutorial-Book-v3 0.1 文档
</title>
...
...
@@ -123,7 +123,7 @@ commentsRunWhenDOMLoaded(addUtterances);
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../quickstart.html"
>
环境配置
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter1/index.html"
>
第一章:RV64 裸机应用
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter2/index.html"
>
第二章:批处理系统
</a></li>
<li
class=
"toctree-l1 current"
><a
class=
"current reference internal"
href=
"#"
>
第三章:多道程序与分时多任务
</a><ul>
<li
class=
"toctree-l1 current"
><a
class=
"current reference internal"
href=
"#"
>
第三章:多道程序与分时多任务
系统
</a><ul>
<li
class=
"toctree-l2"
><a
class=
"reference internal"
href=
"1multi-loader.html"
>
多任务加载器
</a></li>
<li
class=
"toctree-l2"
><a
class=
"reference internal"
href=
"2task-switching.html"
>
任务切换
</a></li>
<li
class=
"toctree-l2"
><a
class=
"reference internal"
href=
"3multiprogramming.html"
>
多道程序与协作式调度
</a></li>
...
...
@@ -196,7 +196,7 @@ commentsRunWhenDOMLoaded(addUtterances);
<li><a
href=
"../index.html"
class=
"icon icon-home"
></a>
»
</li>
<li>
第三章:多道程序与分时多任务
</li>
<li>
第三章:多道程序与分时多任务
系统
</li>
<li
class=
"wy-breadcrumbs-aside"
>
...
...
@@ -216,7 +216,7 @@ commentsRunWhenDOMLoaded(addUtterances);
<div
itemprop=
"articleBody"
>
<div
class=
"section"
id=
"id1"
>
<h1>
第三章:多道程序与分时多任务
<a
class=
"headerlink"
href=
"#id1"
title=
"永久链接至标题"
>
¶
</a></h1>
<h1>
第三章:多道程序与分时多任务
系统
<a
class=
"headerlink"
href=
"#id1"
title=
"永久链接至标题"
>
¶
</a></h1>
<div
class=
"toctree-wrapper compound"
>
</div>
<p>
上一章,我们实现了一个简单的批处理系统。首先,它能够自动按照顺序加载并运行序列中的每一个应用,当一个应用运行结束之后无需操作员的手动替换;
...
...
@@ -227,6 +227,12 @@ commentsRunWhenDOMLoaded(addUtterances);
相同的一块内存区域。而本章所介绍的多道程序和分时多任务系统则是在内存中同一时间可以驻留多个应用。所有的应用都是在系统启动的时候分别加载到
内存的不同区域中。由于目前我们只有一个 CPU,则同一时间最多只有一个应用在执行,剩下的应用则处于就绪状态,需要内核将 CPU 分配给它们才能
开始执行。因此,我们能够看到多个应用在一个 CPU 上交替执行的现象。
</p>
<div
class=
"admonition note"
>
<p
class=
"admonition-title"
>
注解
</p>
<p>
读者也许会有疑问:由于只有一个 CPU,即使这样做,同一时间最多还是只能运行一个应用,还浪费了更多的内存来把所有
的应用都加载进来。那么这样做有什么意义呢?
</p>
<p>
读者可以带着这个问题继续看下去。后面我们会介绍这样做到底能够解决什么问题。
</p>
</div>
<p
id=
"term-time-sharing-multitasking"
><span
id=
"term-multiprogramming"
></span><strong>
多道程序
</strong>
(Multiprogramming) 和
<strong>
分时多任务系统
</strong>
(Time-Sharing Multitasking) 对于应用的要求是不同的,因此我们分别为它们
编写了不同的应用,代码也被放在两个不同的分支上。对于它们更加深入的讲解请参考本章正文,我们在引言中仅给出运行代码的方法。
</p>
<p>
获取多道程序的代码:
</p>
...
...
docs/chapter4/index.html
浏览文件 @
936c22ec
...
...
@@ -123,7 +123,7 @@ commentsRunWhenDOMLoaded(addUtterances);
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../quickstart.html"
>
环境配置
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter1/index.html"
>
第一章:RV64 裸机应用
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter2/index.html"
>
第二章:批处理系统
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter3/index.html"
>
第三章:多道程序与分时多任务
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter3/index.html"
>
第三章:多道程序与分时多任务
系统
</a></li>
<li
class=
"toctree-l1 current"
><a
class=
"current reference internal"
href=
"#"
>
第四章:内存隔离安全性
</a><ul
class=
"simple"
>
</ul>
</li>
...
...
docs/chapter5/index.html
浏览文件 @
936c22ec
...
...
@@ -123,7 +123,7 @@ commentsRunWhenDOMLoaded(addUtterances);
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../quickstart.html"
>
环境配置
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter1/index.html"
>
第一章:RV64 裸机应用
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter2/index.html"
>
第二章:批处理系统
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter3/index.html"
>
第三章:多道程序与分时多任务
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter3/index.html"
>
第三章:多道程序与分时多任务
系统
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter4/index.html"
>
第四章:内存隔离安全性
</a></li>
<li
class=
"toctree-l1 current"
><a
class=
"current reference internal"
href=
"#"
>
第五章:进程及重要系统调用
</a><ul
class=
"simple"
>
</ul>
...
...
docs/chapter6/index.html
浏览文件 @
936c22ec
...
...
@@ -123,7 +123,7 @@ commentsRunWhenDOMLoaded(addUtterances);
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../quickstart.html"
>
环境配置
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter1/index.html"
>
第一章:RV64 裸机应用
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter2/index.html"
>
第二章:批处理系统
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter3/index.html"
>
第三章:多道程序与分时多任务
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter3/index.html"
>
第三章:多道程序与分时多任务
系统
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter4/index.html"
>
第四章:内存隔离安全性
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter5/index.html"
>
第五章:进程及重要系统调用
</a></li>
<li
class=
"toctree-l1 current"
><a
class=
"current reference internal"
href=
"#"
>
第六章:文件描述符与进程间通信
</a><ul
class=
"simple"
>
...
...
docs/chapter7/index.html
浏览文件 @
936c22ec
...
...
@@ -123,7 +123,7 @@ commentsRunWhenDOMLoaded(addUtterances);
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../quickstart.html"
>
环境配置
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter1/index.html"
>
第一章:RV64 裸机应用
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter2/index.html"
>
第二章:批处理系统
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter3/index.html"
>
第三章:多道程序与分时多任务
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter3/index.html"
>
第三章:多道程序与分时多任务
系统
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter4/index.html"
>
第四章:内存隔离安全性
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter5/index.html"
>
第五章:进程及重要系统调用
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter6/index.html"
>
第六章:文件描述符与进程间通信
</a></li>
...
...
docs/chapter8/index.html
浏览文件 @
936c22ec
...
...
@@ -123,7 +123,7 @@ commentsRunWhenDOMLoaded(addUtterances);
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../quickstart.html"
>
环境配置
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter1/index.html"
>
第一章:RV64 裸机应用
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter2/index.html"
>
第二章:批处理系统
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter3/index.html"
>
第三章:多道程序与分时多任务
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter3/index.html"
>
第三章:多道程序与分时多任务
系统
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter4/index.html"
>
第四章:内存隔离安全性
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter5/index.html"
>
第五章:进程及重要系统调用
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../chapter6/index.html"
>
第六章:文件描述符与进程间通信
</a></li>
...
...
docs/collaboration.html
浏览文件 @
936c22ec
...
...
@@ -122,7 +122,7 @@ commentsRunWhenDOMLoaded(addUtterances);
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"quickstart.html"
>
环境配置
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"chapter1/index.html"
>
第一章:RV64 裸机应用
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"chapter2/index.html"
>
第二章:批处理系统
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"chapter3/index.html"
>
第三章:多道程序与分时多任务
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"chapter3/index.html"
>
第三章:多道程序与分时多任务
系统
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"chapter4/index.html"
>
第四章:内存隔离安全性
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"chapter5/index.html"
>
第五章:进程及重要系统调用
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"chapter6/index.html"
>
第六章:文件描述符与进程间通信
</a></li>
...
...
docs/genindex.html
浏览文件 @
936c22ec
...
...
@@ -121,7 +121,7 @@ commentsRunWhenDOMLoaded(addUtterances);
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"quickstart.html"
>
环境配置
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"chapter1/index.html"
>
第一章:RV64 裸机应用
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"chapter2/index.html"
>
第二章:批处理系统
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"chapter3/index.html"
>
第三章:多道程序与分时多任务
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"chapter3/index.html"
>
第三章:多道程序与分时多任务
系统
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"chapter4/index.html"
>
第四章:内存隔离安全性
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"chapter5/index.html"
>
第五章:进程及重要系统调用
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"chapter6/index.html"
>
第六章:文件描述符与进程间通信
</a></li>
...
...
docs/index.html
浏览文件 @
936c22ec
...
...
@@ -122,7 +122,7 @@ commentsRunWhenDOMLoaded(addUtterances);
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"quickstart.html"
>
环境配置
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"chapter1/index.html"
>
第一章:RV64 裸机应用
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"chapter2/index.html"
>
第二章:批处理系统
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"chapter3/index.html"
>
第三章:多道程序与分时多任务
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"chapter3/index.html"
>
第三章:多道程序与分时多任务
系统
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"chapter4/index.html"
>
第四章:内存隔离安全性
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"chapter5/index.html"
>
第五章:进程及重要系统调用
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"chapter6/index.html"
>
第六章:文件描述符与进程间通信
</a></li>
...
...
docs/objects.inv
浏览文件 @
936c22ec
无法预览此类型文件
docs/quickstart.html
浏览文件 @
936c22ec
...
...
@@ -130,7 +130,7 @@ commentsRunWhenDOMLoaded(addUtterances);
</li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"chapter1/index.html"
>
第一章:RV64 裸机应用
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"chapter2/index.html"
>
第二章:批处理系统
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"chapter3/index.html"
>
第三章:多道程序与分时多任务
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"chapter3/index.html"
>
第三章:多道程序与分时多任务
系统
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"chapter4/index.html"
>
第四章:内存隔离安全性
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"chapter5/index.html"
>
第五章:进程及重要系统调用
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"chapter6/index.html"
>
第六章:文件描述符与进程间通信
</a></li>
...
...
docs/rest-example.html
浏览文件 @
936c22ec
...
...
@@ -123,7 +123,7 @@ commentsRunWhenDOMLoaded(addUtterances);
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"quickstart.html"
>
环境配置
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"chapter1/index.html"
>
第一章:RV64 裸机应用
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"chapter2/index.html"
>
第二章:批处理系统
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"chapter3/index.html"
>
第三章:多道程序与分时多任务
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"chapter3/index.html"
>
第三章:多道程序与分时多任务
系统
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"chapter4/index.html"
>
第四章:内存隔离安全性
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"chapter5/index.html"
>
第五章:进程及重要系统调用
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"chapter6/index.html"
>
第六章:文件描述符与进程间通信
</a></li>
...
...
docs/search.html
浏览文件 @
936c22ec
...
...
@@ -123,7 +123,7 @@ commentsRunWhenDOMLoaded(addUtterances);
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"quickstart.html"
>
环境配置
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"chapter1/index.html"
>
第一章:RV64 裸机应用
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"chapter2/index.html"
>
第二章:批处理系统
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"chapter3/index.html"
>
第三章:多道程序与分时多任务
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"chapter3/index.html"
>
第三章:多道程序与分时多任务
系统
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"chapter4/index.html"
>
第四章:内存隔离安全性
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"chapter5/index.html"
>
第五章:进程及重要系统调用
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"chapter6/index.html"
>
第六章:文件描述符与进程间通信
</a></li>
...
...
docs/searchindex.js
浏览文件 @
936c22ec
此差异已折叠。
点击以展开。
docs/terminology.html
浏览文件 @
936c22ec
...
...
@@ -123,7 +123,7 @@ commentsRunWhenDOMLoaded(addUtterances);
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"quickstart.html"
>
环境配置
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"chapter1/index.html"
>
第一章:RV64 裸机应用
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"chapter2/index.html"
>
第二章:批处理系统
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"chapter3/index.html"
>
第三章:多道程序与分时多任务
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"chapter3/index.html"
>
第三章:多道程序与分时多任务
系统
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"chapter4/index.html"
>
第四章:内存隔离安全性
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"chapter5/index.html"
>
第五章:进程及重要系统调用
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"chapter6/index.html"
>
第六章:文件描述符与进程间通信
</a></li>
...
...
source/chapter3/1multi-loader.rst
浏览文件 @
936c22ec
...
...
@@ -2,5 +2,118 @@
=====================================
在本章的引言中我们提到每个应用都需要按照它的编号被分别加载到内存中不同的位置。本节我们就来介绍它是如何实现的。
更具体来说,
与第二章相同,所有应用的 ELF 都经过 strip 丢掉所有 ELF header 和符号变为二进制镜像文件,随后以同样的格式通过
``link_user.S`` 在编译的时候直接链接到内核的数据段中。不同的是,我们对相关模块进行了调整:在第二章中
应用的加载和进度控制都交给 ``batch`` 子模块,而在第三章中我们将应用的加载这部分功能分离出来在 ``loader``
子模块中实现,应用的执行和切换则交给 ``task`` 子模块。
应用的加载方式也和上一章不同。上一章的时候所有应用都被加载到一个固定的物理地址,也是因为这个原因,内存中同时
最多只能驻留一个应用,当它运行完毕或者出错退出的时候由 ``batch`` 子模块加载一个新的应用来替换掉它。本章中,
所有的应用在内核初始化的时候就一并被加载到内存中。为了避免覆盖,它们自然需要被加载到不同的物理地址。这是通过
调用 ``loader`` 子模块的 ``load_apps`` 函数实现的:
.. code-block:: rust
:linenos:
// os/src/loader.rs
pub fn load_apps() {
extern "C" { fn _num_app(); }
let num_app_ptr = _num_app as usize as *const usize;
let num_app = get_num_app();
let app_start = unsafe {
core::slice::from_raw_parts(num_app_ptr.add(1), num_app + 1)
};
// clear i-cache first
unsafe { llvm_asm!("fence.i" :::: "volatile"); }
// load apps
for i in 0..num_app {
let base_i = get_base_i(i);
// clear region
(base_i..base_i + APP_SIZE_LIMIT).for_each(|addr| unsafe {
(addr as *mut u8).write_volatile(0)
});
// load app from data section to memory
let src = unsafe {
core::slice::from_raw_parts(
app_start[i] as *const u8,
app_start[i + 1] - app_start[i]
)
};
let dst = unsafe {
core::slice::from_raw_parts_mut(base_i as *mut u8, src.len())
};
dst.copy_from_slice(src);
}
}
可以看出,第 :math:`i` 个应用被加载到以物理地址 ``base_i`` 开头的一段物理内存上,而 ``base_i`` 的
计算方式如下:
.. code-block:: rust
:linenos:
// os/src/loader.rs
fn get_base_i(app_id: usize) -> usize {
APP_BASE_ADDRESS + app_id * APP_SIZE_LIMIT
}
我们可以在 ``config`` 子模块中找到这两个常数。从这一章开始, ``config`` 子模块用来存放内核中所有的常数。看到
``APP_BASE_ADDRESS`` 被设置为 ``0x80100000`` ,而 ``APP_SIZE_LIMIT`` 和上一章一样被设置为
``0x20000`` ,也就是每个应用二进制镜像的大小限制。因此,应用的内存布局就很明朗了——就是从
``APP_BASE_ADDRESS`` 开始依次为每个应用预留一段空间。
注意,我们需要调整每个应用被构建时候使用的链接脚本 ``linker.ld`` 中的起始地址 ``BASE_ADDRESS`` 为它实际
会被内核加载并运行的地址。也就是要做到:应用知道自己会被加载到某个地址运行,而内核也确实能做到将它加载到那个
地址。这算是应用和内核在某种意义上达成的一种协议。之所以要有这么苛刻的条件,是因为应用和内核的能力都很弱,泛用性很低。
事实上,目前我们的应用是绝对位置而并不是位置无关的,内核也没有提供相应的重定位机制。
.. note::
可以在 `这里 <https://nju-projectn.github.io/ics-pa-gitbook/ics2020/4.2.html>`_ 找到更多有关
位置无关和重定位的说明。
由于每个应用被加载到的位置都不同,也就导致它们 ``linker.ld`` 中的 ``BASE_ADDRESS`` 都是不同的。实际上,
我们写了一个脚本 ``build.py`` 而不是直接 ``cargo build`` 构建应用:
.. code-block:: python
:linenos:
# user/build.py
import os
base_address = 0x80100000
step = 0x20000
linker = 'src/linker.ld'
app_id = 0
apps = os.listdir('src/bin')
apps.sort()
for app in apps:
app = app[:app.find('.')]
lines = []
lines_before = []
with open(linker, 'r') as f:
for line in f.readlines():
lines_before.append(line)
line = line.replace(hex(base_address), hex(base_address+step*app_id))
lines.append(line)
with open(linker, 'w+') as f:
f.writelines(lines)
os.system('cargo build --bin %s --release' % app)
print('[build.py] application %s start with address %s' %(app, hex(base_address+step*app_id)))
with open(linker, 'w+') as f:
f.writelines(lines_before)
app_id = app_id + 1
它的思路很简单,在遍历 ``app`` 的大循环里面只做了这样几件事情:
- 第 16~22 行,找到 ``src/linker.ld`` 中的 ``BASE_ADDRESS = 0x80100000;`` 这一行,并将后面的地址
替换为和当前应用对应的一个地址;
- 第 23 行,使用 ``cargo build`` 构建当前的应用,注意我们可以使用 ``--bin`` 参数来只构建某一个应用;
- 第 25~26 行,将 ``src/linker.ld`` 还原。
这样,我们就说明了多个应用是如何被构建和加载的。
source/chapter3/index.rst
浏览文件 @
936c22ec
第三章:多道程序与分时多任务
第三章:多道程序与分时多任务
系统
==============================================
.. toctree::
...
...
@@ -20,6 +20,13 @@
内存的不同区域中。由于目前我们只有一个 CPU,则同一时间最多只有一个应用在执行,剩下的应用则处于就绪状态,需要内核将 CPU 分配给它们才能
开始执行。因此,我们能够看到多个应用在一个 CPU 上交替执行的现象。
.. note::
读者也许会有疑问:由于只有一个 CPU,即使这样做,同一时间最多还是只能运行一个应用,还浪费了更多的内存来把所有
的应用都加载进来。那么这样做有什么意义呢?
读者可以带着这个问题继续看下去。后面我们会介绍这样做到底能够解决什么问题。
.. _term-multiprogramming:
.. _term-time-sharing-multitasking:
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录