think of user program as a potential malicious adversary
With exceptions that relate to a specific segment, the processor pushes an error code onto the stack of the exception handler (whether procedure or task). The error code has the format shown in Figure 9-7 . The format of the error code resembles that of a selector; however, instead of an RPL field, the error code contains two one-bit items:
page fault 的 error code 与其他异常的 error code 不同,格式如下:
此处需要调试 xv6 代码,调试方法详见:http://blog.csdn.net/fantasy_wxe/article/details/7607646
1、在一个终端下 make qemu-gdb
2、在另一个终端下 gdb kernel
刚刚发现其实在yale的课程中也有介绍:http://zoo.cs.yale.edu/classes/cs422/2011/lec/l2-hw
然后我们就可以调试 xv6 代码啦~~
Lec8里面有如下任务:
让我们一一来完成:
如果我们一开始就去查看 IDT 内容,会发现全是 0,这是因为系统还未初始化,那么我们就在 exec 处设置断点,然后运行到此处,根据 yale 上的讲义:At this point, the machine is running in 32-bit mode, the xv6 kernel has initialized itself, and it is just about to load and execute its first user-mode process, the /init program.
此时系统初始化完成,我们可以开始了
首先是 print idt[0x40]:
观察 idt[0x40],发现 tpye = 15,表示为 trap,其次 dpl = 3,然后我又观察了其他的,发现它们的 cs 都为 8,也即后三位都是0,说明其使用 GDT 查表,当前代码在 kernel 状态,并且 OFFSET 逐渐增加,这与我们的理解相符。但是 type 说明其他的中断类型均为 intertupt,而且 dpl 都是 0 ,特别是 breakpoint 的 dpl 也是 0,这就与我们在 JOS 里的认识不同了。查看一下 idt 的设置:
原来是这样啊~
依据提示,在 vector64 设置断点:
再单步执行到 pushl %esp:
通过对比 trapframe 结构:
前两个 0x00000000、0x00000000 分别对应 edi 和 esi,依次类推。trapno = 0x40,err = 0x0。
继续作答:
对比之后发现完全一样。。
此时对比之前,发现 eax 由原来的 0x7 变成 0x0,eip 由原来的 0x13 变为 0x0,esp 有原来的 0xff4 变为 0x2fe4。
至于原因吗,现在还不知道。。
关于除0的问题,与之前 Lab3 里的题目类似,由于我们将除0 handler 的 dpl 设置为 0,所以在用户模式下会在进除0 handler 的过程中出现权限保护的异常,若是在 kernel 模式下,则会正常进入除0 handler。
断点设在 vector32,但是程序却停在在 vector64 处。原理神马的不懂。。