MIT6.828 HW1 Boot xv6

环境

ubuntu 20.04 64位系统

本次作业的地址:homework
MIT6.828地址:MIT6.828-2018-fall

正文

如果做过前面lab1的老铁一定感觉lab1的内容之多,后面做起来也不容易,相对而言,这一份作业就没那么困难了,这次作业主要做的是调试,不需要写代码。

准备工作
这次使用的代码是xv6,而不是之前lab1的代码,所以需要重新从github拉下来:

git clone git://github.com/mit-pdos/xv6-public.git

然后make一下,这里为就用下mit的例子:

$ cd xv6-public
$ make
...
gcc -O -nostdinc -I. -c bootmain.c
gcc -nostdinc -I. -c bootasm.S
ld -m    elf_i386 -N -e start -Ttext 0x7C00 -o bootblock.o bootasm.o bootmain.o
objdump -S bootblock.o > bootblock.asm
objcopy -S -O binary -j .text bootblock.o bootblock
..

好了,万事俱备只欠东风。
打开两个terminal,一个先收入make qemu-gdb,一个输入make gdb就行,不过这里官方给的代码有一点小错误,直接输入make gdb是出错的,所以我们在xv6的Makefile里面任选一行,加入以下内容:

修复Makefile的问题

这样一来应该可以运行make gdb了。
接下来继续回到作业的内容,首先使用命令:

nm kernel | grep _start

接着我们得到以下的内容:


输出的结果

我们看到内核的起始地址在0x10000c,所以我们在这里打一个断点,然后看看此时在栈内的内容,注意作业并没有要求我们解释栈当中所有的内容,并且尝试解释这些内容是什么意思,下面在我的机子上实验的内容:
栈内的内容

先回想以下,0x10000c这个地址内核执行的第一句代码的地址,所以说我们在前面栈的内容都是由引导程序在执行的时候压入的。在想想,结合一下以前面的lab1,我们通过call指令跳转到了内核当中执行,在bootmain.c当中的代码,下面的代码对应的汇编是call 0x10018:

  entry = (void(*)(void))(elf->entry);
  entry();

这两句代码帮我们跳转到了内核的当中,因为call的执行都会将下依据需要执行的指令压入到栈,所以0x000_7d97就是call下一条语句的代码的,在bootmain.asm当中发现,内容确实如此:

0x00009d97

确实对了,好像接下来一堆0x0不知道怎么来的,暂且不理会,在bootmain.S当中,有以下两条语句:

  movl    $start, %esp
  call    bootmain

start标号的地址在0x7c00,所以我们看下0x7c00开始的地址内容,如下:

0x7c00

和上面对照一下,0x8ec0_31fa在哪,可以看到0x8ec0_31fa后面紧跟着的就是0x7c4d,在bootmian.asm看一下,结果如下:
0x7c4d

原来又是下一条代码的地址,和之前那个比起来没什么花样。因为我们在bootmain.S当中对edi等寄存器都设置为0,所以在call bootmain的时候压入了这些寄存器的值,所以压入了一大堆的0。好了我们已经把栈当中的内容都解释清楚了。
来到本次作业的Exercise,我没有完全按照作业的问题顺序来作实验,因为上面的问题搞清楚了,exercise的几个小问题都很简单:

  1. 将断点设置在0x7c00,逐步调试,在那里初始化了栈?
  2. 逐步执行call bootmain,现在栈里面有什么?
  3. bootmain.asm当中第一条对栈做了什么操作?仔细查看bootmain.asm
  4. call 0x10000c做了对栈做了什么呢?

这几个问题确实很简单,直接放在一起回答,我们call bootmain上一句代码初始化了栈,在calll bootmain后,我们在栈内压入了0x7c4d,经过之前的C calling convention学习,我们知道了调用函数的时候先要执行push %ebp,所以bootmain.asm当中第一局指令压入了ebp。在call 0x10000c的时候,我们又压入了0x7d97

PS:不知道各位是否还记得lab1 part3 最后一个循环的条件,while(*ebp != 0x0),通过上面的实验,我们看到了我们在栈内压入了ebp,此时ebp = 0x0,循环条件就是从这里的得到的,不得不说,MIT的代码还是写的很好的,我们也逐渐感受到了它的巧妙。

本次的作业就做完了,还是比较简单的,稍微调试一下就知道所有问题的答案了,奥利给!

你可能感兴趣的:(MIT6.828 HW1 Boot xv6)