uCore-Tutorial-Guide-2023S/source/chapter3/5exercise.rst

151 lines
6.3 KiB
ReStructuredText
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

chapter3练习
=======================================
- 本节难度:编程试水
本章任务
-----------------------------------------------------
- 注意本节任务最终对应一次 lab 提交。
- 老规矩,先 `make test BASE=1` 看下啥情况。
- 理解框架的多任务加载机制,了解此时用户和内核的大概内存布局。在此基础上,实现本章编程作业 sys_task_info。
- 最终,完成实验报告并 push 你的 ch3 分支到远程仓库。push 代码后会自动执行 CI代码给分以 CI 给分为准。
获取任务信息
++++++++++++++++++++++++++
ch3 中,我们的系统已经能够支持多个任务分时轮流运行,我们希望引入一个新的系统调用 ``sys_task_info`` 以获取任务的信息,定义如下:
.. code-block:: C
int sys_task_info(TaskInfo *ti);
- syscall ID: 410
- 查询当前正在执行的任务信息,任务信息包括任务控制块相关信息(任务状态)、任务使用的系统调用次数、任务总运行时长。
.. code-block:: C
struct TaskInfo {
TaskStatus status;
unsigned int syscall_times[MAX_SYSCALL_NUM];
int time;
};
- 参数:
- ti: 待查询任务信息
- 返回值执行成功返回0错误返回-1
- 说明:
- 相关结构已在框架中给出,只需添加逻辑实现功能需求即可。
- 在我们的实验中,系统调用号一定小于 500所以直接使用一个长为 ``MAX_SYSCALL_NUM=500`` 的数组做桶计数。
- 我们约定调用 sys_task_info 时对本次系统调用也进行计数,因此返回的 syscall_times 中对 sys_task_info 的计数一定不会是 0。
- 简单起见运行时间 time 返回系统调用时刻距离任务首次被调度时刻的时长即可;一种更有意义但是难度稍微高一些的做法是返回任务处于 Running 状态的运行时长:包含用户态时间和内核态时间,不包含调度到其他任务的时间。你可以思考下后者如何实现,但是为了通过测例建议使用前者(即考虑 real time
- 我们约定 time 的单位是 ms为了得到时间可以使用 `get_cycle` 配合 CPU_FREQ参考系统调用中 `sys_gettimeofday` 的实现或许会对你有所启发。
- 由于查询的是当前任务的状态,因此 TaskStatus 一定是 Running。助教起初想设计根据任务 id 查询,但是既不好定义任务 id 也不好写测例,遂放弃 QAQ
- 提示:
- 大胆修改已有框架!除了配置文件,你几乎可以随意修改已有框架的内容。
- 程序运行时间可以通过调用 ``get_time()`` 获取。
- 系统调用次数可以考虑在进入内核态系统调用异常处理函数之后,进入具体系统调用函数之前维护。
- 阅读 proc 的实现,思考如何维护内核控制块信息(可以在控制块可变部分加入其他需要的信息)。
实验要求
+++++++++++++++++++++++++++++++++++++++++
- 完成分支: ch3。
- 实验目录要求
.. code-block::
├── os(内核实现)
│   └── ...
├── reports (不是 report)
│   ├── lab1.md/pdf
│   └── ...
├── ...
- 通过所有测例:
CI 使用的测例与本地相同测试中user 文件夹及其它与构建相关的文件将被替换,请不要试图依靠硬编码通过测试。
.. note::
你的实现只需且必须通过测例,建议读者感到困惑时先检查测例。
.. ch3问答作业::
.. 实验结果
+++++++++++++++++++++++++++++++++++++++++
本实验采用了github classroom的自动评分功能完成实验提交git push后会触发自动测试实验测试结果可以在在线统计<https://ucore-rv-64.github.io/classroom-grading/>中查看。
问答作业
--------------------------------------------
1. 正确进入 U 态后,程序的特征还应有:使用 S 态特权指令,访问 S 态寄存器后会报错。请同学们可以自行测试这些内容(参考 `前三个测例 <https://github.com/LearningOS/uCore-Tutorial-Test-2023S/tree/main/src>`_ ,描述程序出错行为,同时注意注明你使用的 sbi 及其版本。
2. 请结合用例理解 `trampoline.S <https://github.com/LearningOS/uCore-Tutorial-Code-2023S/blob/ch3/os/trampoline.S>`_ 中两个函数 `userret``uservec` 的作用,并回答如下几个问题:
1. L79: 刚进入 `userret` 时,`a0``a1` 分别代表了什么值。
2. L87-L88: `sfence` 指令有何作用?为什么要执行该指令,当前章节中,删掉该指令会导致错误吗?
.. code-block:: assembly
csrw satp, a1
sfence.vma zero, zero
3. L96-L125: 为何注释中说要除去 `a0`?哪一个地址代表 `a0`?现在 `a0` 的值存在何处?
.. code-block:: assembly
# restore all but a0 from TRAPFRAME
ld ra, 40(a0)
ld sp, 48(a0)
ld t5, 272(a0)
ld t6, 280(a0)
4. `userret`:中发生状态切换在哪一条指令?为何执行之后会进入用户态?
5. L29 执行之后a0 和 sscratch 中各是什么值,为什么?
.. code-block:: assembly
csrrw a0, sscratch, a0
6. L32-L61: 从 trapframe 第几项开始保存?为什么?是否从该项开始保存了所有的值,如果不是,为什么?
.. code-block:: assembly
sd ra, 40(a0)
sd sp, 48(a0)
...
sd t5, 272(a0)
sd t6, 280(a0)
7. 进入 S 态是哪一条指令发生的?
8. L75-L76: `ld t0, 16(a0)` 执行之后,`t0`中的值是什么,解释该值的由来?
.. code-block:: assembly
ld t0, 16(a0)
jr t0
.. ch3报告要求::
报告要求
-------------------------------
- 简单总结你实现的功能200字以内不要贴代码
- 完成问答题。
- 推荐markdown文档格式。
- 加入 :doc:`/honorcode` 的内容。否则你的提交将视作无效本次实验的成绩将按“0”分计。
- CI 网站提交,注明姓名学号。
- 注意目录要求,报告命名 ``lab1.md````lab1.pdf``,位于 ``reports`` 目录下。命名错误视作没有提交。后续实验同理。
- (optional) 你对本次实验设计及难度/工作量的看法,以及有哪些需要改进的地方,欢迎畅所欲言。
.. warning::
请勿抄袭,报告会进行抽样查重!