# Guidance

## 作业难度

每一个作业都指示它的难度：

* 容易：小于1小时。这些实验是以后面练习提供的经典热身练习
* 中等：1\~2小时
* 困难：多于2小时。通常这些练习不要求写很多代码，但是这些代码很难完全正确

这些时间是对我们粗略的估计。对于一些可选的任务，我们没有进行估计，这是一个疯狂的猜测。如果您发现自己在一项任务上花费的时间比我们预期的要多，请联系我们

一般练习不要求写很多行代码（十行至几百行），但代码在概念上是很复杂，而且细节往往很重要。因此，在编写任何代码之前，请阅读实验指定的相关文件，查阅文档。只有当你充分理解任务和解决方案时，才开始编码。以小步骤实施解决方案（通常作业是建议将大问题拆分成较小问题）并在继续下一个步骤之前测试每个步骤是否有效。

## 调试技巧

这是一些调试解决方案的技巧

* 确保理解C与指针, Kernighan and Ritchie编写"The C programming language (second edition)" 是简明描述C。这里有一些有用的[指针练习](https://pdos.csail.mit.edu/6.828/2019/lec/pointers.c)，除非你已纪彻底掌握c，否则不要跳过上面指针的练习。如果你没有真正理解C语言的指针，在实验中你将遭受无穷的痛苦，然后最终通过艰难路程才能理解。相信我们，如果你不想要走此艰难路程

  一些指针常用的风格，推荐记住：

  * 如果`int *p = (int*)100`，则 `(int)p + 1` 和 `(int)(p + 1)` 是不同的：第一个是 101，但是第二个是 104。当一个指针加上一个整数，如第二种情况，整数 乘以 指针指向的对象的大小
  * `p[i]` 与`*(p+i)`是相同的，指`p`指向的内存中的第`i`个对象
  * `&p[i]`与`(p+i)`是相同的，指`p`指向的内存中第`i`个对象的地址

  尽管大多数 C 程序不需要在指针和整数之间进行转换，但操作系统经常这样做。每当你看到一个涉及内存地址的加法时，问问自已，是整数加法？还是指针加法？并确保执行加法后的值是否有效。
* 如果你的练习有一部分是正常工作，可以通过提交代码来检查你的进度。如果后面你有新的想法，你能同滚到上一个提交点以更小的步骤来验证。想要学习更多Git操作，看[Git user's manual](http://www.kernel.org/pub/software/scm/git/docs/user-manual.html)或你能发现[CS-oriented overview of Git](http://eagain.net/articles/git-for-computer-scientists/)的用法
* 如果你测试失败，先确定测试失败的原因。可以通过插入打印语句，直至理解失败原因。
* 你可能会发现打印语句产生许多的输出；如果想要搜索，可以在`script`中运行`make qemu`，它将控制台所有日志都输出到一个文件中，然后你可以搜索该文件（不要忘记退出`script`）
* 在许多情况下，打印语句就足够了，但是有时候单步执行一些汇编代码或检查变量是有用的。想调试 xv6 ，在一个终端中运行 `make qemu-gdb`，在另一个终端中运行`gdb`或 `riscv64-linux-gnu-gdb`，设置一个断点，然后执行`c`或`continue`， xv6会运行到断点为止。（有关GDB 用法，参考 [GNU 调试器](https://pdos.csail.mit.edu/6.828/2019/lec/gdb_slides.pdf)）
* 如果你想要查看通过编译器生成的内核汇编指令，或 查看指定内核地址的指令，可以查看`kernel.asm`文件，此文件是通过`Makefile`在编译内核时生成的（`Makefile`也为所有用户程序生成`.asm`文件）
* 如果内核`panics`，它将打印错误消息，列出`crashed`时的`PC`值，你能够在`kernel.asm`查找`PC`所在的函数，或者你可以运行`addr2line -e kernel/kernel pc-value`。如果你想要获得函数回溯，重新启动 gdb ：在一个终端中运行`make qemu-gdb`，在另一个终端中运行`gdb`或`riscv64-linux-gnu-gdb`，在`panic`中设置断点（`b panic`），然后执行`c`或`continue`。当内核到达断点时，执行`bt`获取函数回溯
* 如果内核`hangs`（例如：死锁）或 无法继续执行（例如：执行内核指令时出现`page fault`），你能够使用`gdb`找出原因。在一个终端中运行`make qemu-gdb`，在另一个终端中运行`gdb`或`riscv64-linux-gnu-gdb`，然后执行`c`或`continue`。当内核`hang`时，在`qemu-gdb`终端中按`Ctrl-C`并执行`bt`以获取函数回溯。
* `qemu`有一个`monitor`，可以让你查询模拟器的状态，可以通过执行`control-a c` 来获得(the "c" is for console).。一个特别有用的`monitor`命令是`info mem`来打印页表。你可能需要使用`cpu`命令来选择查看哪一个`core`的`info mem` 或者 在启动`qemu`时，使用`make CPUS=1` 让其只有一个`core`。

花时间学习上述工具是非常值得的


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://vernon2gb.gitbook.io/notes/mit_6s081/labs/guidance.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
