chapter3练习

  • 本节难度:编程试水

本章任务

  • 注意本节任务最终对应一次 lab 提交。

  • 老规矩,先 make test BASE=1 看下啥情况。

  • 理解框架的多任务加载机制,了解此时用户和内核的大概内存布局。在此基础上,实现本章编程作业 sys_trace

  • 不再加 BASE=1,直接运行 make test 来验证你的完成情况。

  • 最终,完成实验报告并 push 你的 ch3 分支到远程仓库。push 代码后会自动执行 CI,代码给分以 CI 给分为准。

获取任务信息

ch3 中,我们的系统已经能够支持多个任务分时轮流运行,我们希望引入一个新的系统调用 sys_trace (syscall ID: 410)用来追踪当前任务系统调用的历史信息、并进行任务内存的读写。定义如下:

int sys_trace(int trace_request, unsigned long id, uint8_t data);
  • syscall ID: 410

  • 调用规范:
    • 这个系统调用有三种功能,根据 trace_request 的值不同,执行不同的操作:

    • 如果 trace_request 为 0,则 id 应被视作 uint8_t * ,表示读取当前任务 id 地址处一个字节的无符号整数值。此时应忽略 data 参数。返回值为 id 地址处的值。

    • 如果 trace_request 为 1,则 id 应被视作 uint8_t * ,表示写入 data (作为 uint8_t,即只考虑最低位的一个字节)到该用户程序 id 地址处。返回值应为0。

    • 如果 trace_request 为 2,表示查询当前任务调用编号为 id 的系统调用的次数,返回值为这个调用次数。 本次调用也计入统计

    • 否则,忽略其他参数,返回值为 -1。

  • 说明:
    • uint8_t 是C语言中的标准类型,表示一个无符号的8位整数。在代码中你可能需要使用 uint8 替代。

    • 你可能会注意到,这个调用的读写并不安全,使用不当可能导致崩溃。这是因为在下一章节实现地址空间之前,系统中缺乏隔离机制。所以我们 不要求你实现安全检查机制,只需通过测试用例即可

    • 你还可能注意到,这个系统调用读写本任务内存的功能并不是很有用。这是因为作业的灵感来源 syscall 主要依靠 trace 功能追踪其他任务的信息,但在本章节我们还没有进程、线程等概念,所以简化了操作,只要求追踪自身的信息。

提示

  • 大胆修改已有框架!除了配置文件,你几乎可以随意修改已有框架的内容。

  • 系统调用次数可以考虑在进入内核态系统调用异常处理函数之后,进入具体系统调用函数之前维护。

  • 阅读 proc 的实现,思考如何维护内核控制块信息(可以在控制块可变部分加入其他需要的信息)。

实验要求

  • 完成分支: ch3。

  • 实验目录要求

├── os(内核实现)
│   └── ...
├── reports (不是 report)
│   ├── lab1.md/pdf
│   └── ...
├── ...
  • 通过所有测例:

    CI 使用的测例与本地相同,测试中,user 文件夹及其它与构建相关的文件将被替换,请不要试图依靠硬编码通过测试。

注解

你的实现只需且必须通过测例,建议读者感到困惑时先检查测例。

问答作业

  1. 正确进入 U 态后,程序的特征还应有:使用 S 态特权指令,访问 S 态寄存器后会报错。请同学们可以自行测试这些内容(参考 前三个测例 ,描述程序出错行为,同时注意注明你使用的 sbi 及其版本。

  2. 请结合用例理解 trampoline.S 中两个函数 userretuservec 的作用,并回答如下几个问题:

    1. L79: 刚进入 userret 时,a0a1 分别代表了什么值。

    2. L87-L88: sfence 指令有何作用?为什么要执行该指令,当前章节中,删掉该指令会导致错误吗?

      csrw satp, a1
      sfence.vma zero, zero
      
    3. L96-L125: 为何注释中说要除去 a0?哪一个地址代表 a0?现在 a0 的值存在何处?

      # 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 中各是什么值,为什么?

      csrrw a0, sscratch, a0
      
    6. L32-L61: 从 trapframe 第几项开始保存?为什么?是否从该项开始保存了所有的值,如果不是,为什么?

      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`中的值是什么,解释该值的由来?

    ld t0, 16(a0)
    jr t0
    

报告要求

  • 简单总结你实现的功能(200字以内,不要贴代码)。

  • 完成问答题。

  • 推荐markdown文档格式。

  • 加入 荣誉准则 的内容。否则,你的提交将视作无效,本次实验的成绩将按“0”分计。

  • CI 网站提交,注明姓名学号。

  • 注意目录要求,报告命名 lab1.mdlab1.pdf,位于 reports 目录下。命名错误视作没有提交。后续实验同理。

  • (optional) 你对本次实验设计及难度/工作量的看法,以及有哪些需要改进的地方,欢迎畅所欲言。

警告

请勿抄袭,报告会进行抽样查重!