# 实验说明 ## 实验难度 每个实验都具有相应的难度 - Easy:不到一个小时。这些锻炼通常是为后续锻炼做的热身运动。 - Moderate:1-2小时。 - Hard:超过2个小时。这些练习通常不需要很多代码,但是代码很难正确。 实验往往不需要很多行代码(几十到几百行) ,但是代码在概念上很复杂,而且细节往往很重要。所以,在你写任何代码之前,一定要完成实验室指定的阅读,通读相关文件,查阅文档(RISC-V手册等存放在了[参考页面](https://pdos.csail.mit.edu/6.828/2020/reference.html)上)。只有当你确定掌握了任务和解决方案,再开始编码。当你开始编写代码的时候,一小步一小步地实现你的解决方案(作业通常会建议如何将问题分解为更小的步骤),并且在继续下一个步骤之前测试每个步骤是否正常工作。 ## 调试技巧 确保你理解了c和指针。Kernighan和Ritchie的《c程序设计语言》一书对C语言进行了简要的描述。这里有一些有用的指针练习。除非你已经完全掌握了C语言,不要跳过或略读上面的指针练习。如果你不能真正理解C语言中的指针,你将在实验室中遭受难以言喻的痛苦,然后最终以一种艰难的方式来理解它们。相信我们,你不会想知道什么是“艰难的路”的。 一些常见的习惯用法特别值得记住: - 如果`int *p = (int*)100`,那么`(int)p + 1`及`(int)(p + 1)`是不同的数字,第一个是101,但第二个是104。当向指针添加一个整数时,如第二种情况,整数被隐式地乘以指针指向的对象的大小。 - `p[i]`被定义为与`*(p+i)`相同,指向内存中p指向的第i个对象,当对象大于1字节时,上面所说的加法规则有利于此定义工作 虽然大多数C程序不需要在指针和整数之间进行强制转换,但操作系统经常需要这样做。每当您看到一个包含内存地址的加法时,问问自己它是整数加法还是指针加法,并确保所添加的值是否适当地相乘。 - 如果你有一个部分工作的练习,请通过提交代码来检查你的进度。如果您稍后破坏了某些东西,那么您可以回滚到您的检查点,然后以较小的步骤继续前进。要了解关于Git的更多信息,请查看[Git用户手册](http://www.kernel.org/pub/software/scm/git/docs/user-manual.html),或者您可能会发现这个[面向计算机科学家的Git概述](http://eagain.net/articles/git-for-computer-scientists/)非常有用。 - 如果您没有通过测试,确保您了解为什么您的代码没有通过测试。插入打印(printf)语句,直到您理解正在发生的事情。 - 您可能会发现您的print语句可能会产生许多您想要搜索的输出;其中一种方法是在`script`内部运行`make qemu`(在您的机器上运行`man script`),它将所有控制台输出记录到一个文件中,然后您可以搜索该文件。别忘了退出`script`。 - 在许多情况下,print语句就足够了,但有时能够单步遍历一些汇编代码或检查堆栈上的变量是有帮助的。要在xv6中使用gdb,请在一个窗口中运行`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文件。) - 如果内核崩溃,它将打印一条错误消息,列出崩溃时程序计数器的值;您可以进行搜索`kernel.asm`找出程序计数器崩溃时在哪个函数中,或者可以运行`addr2line -e kernel/kernel pc-value`(有关详细信息,请运行`man addr2line`)。如果要获取回溯,请使用gdb重新启动:在一个窗口中运行'`make qemu-gdb`',在另一个窗口中运行gdb(或`riscv64-linux-gnu-gdb`),在`panic`中设置断点(“`b panic`”),后跟“`c`”(continue)。当内核到达断点时,键入“bt”以获取回溯跟踪。 - 如果您的内核挂起(例如,由于死锁)或无法进一步执行(例如,由于在执行内核指令时出现页面错误),您可以使用gdb查找挂起的位置。在一个窗口中运行“ `make qemu-gdb`”,在另一个窗口中运行 `gdb` (`riscv64-linux-gnu-gdb`) ,后跟“`c`”(continue)。当内核出现挂起时,在 `qemu-gdb` 窗口中按 `Ctrl-C` 并键入“`bt`”以获得回溯跟踪。 - qemu有一个“监视器”,允许您查询模拟机器的状态。您可以通过键入`+a c`(c表示控制台)来获得它。一个特别有用的monitor命令`是info mem`,用于打印页表。您可能需要使用`cpu`命令来选择`info mem`查看哪一个核心,或者可以使用`make CPUS=1 qemu`启动qemu,以使其只有一个核心。 花时间学习上述工具是非常值得的