HW1 boot xv6

Boot xv6

1、拉取 xv6 源代码文件

1
2
3
mkdir 6.828
cd 6.828
git clone git://github.com/mit-pdos/xv6-public.git

2、编译 xv6

1
2
cd xv6-public
make

Finding and breaking at an address

1、找到内核的入口点的地址,即 _start 的地址

1
nm kernel | grep _start

在这个例子中,地址是 0x0010000c

_start

2、在 QEMU-GDB 内跑内核代码,并且设置刚刚找到的断点

1
make qemu-gdb

并且在另外一个 shell 中,使用 gdb,并且输入target remote:26000连接上qemu进行调试,通过添加断点,我们可以让 qemu 执行停在内核的入口地址处。

breakpoint at 0x0010000c

Exercise:What is on the stack

当我们在断点 0x0010000c 处查看寄存器和 stack 内的内容:

1
2
3
4

info reg
x/24x $esp

我们可以关注一下一些我们处理过的寄存器,一个是和堆栈相关的寄存器 %esp%eip,在源代码中,从 bootasm.S 中设置堆栈为 C 语言建立堆栈开始,xv6 将堆栈的上限设置为 0x7c00,堆栈从 0x7c00 增长到了 0x7bdc 的位置,同时 %ebp 保存了上一次压栈的位置 0x7bf8,由于此时打了断点,可以看到 %eip 寄存器的值刚好指向 0x10000c 的位置。由于此时运行 boot loader 进入实模式,此时的 %eflags 寄存器的权限处于最高权限,代码段寄存器 %cs 的值,正好是 kernel.ld 中的 0x80100000 中的 0x8,此时数据段寄存器 %ds 正好指向对其过后的 0x10,然后是控制寄存器 %cr0 开起 32-bit 模式。以上寄存器的值符合运行的实际逻辑,压栈的大小,得去分析指令的条数来验证,这里没有验证,计算起来好复杂,反正是对的。

寄存器值

然后,我们就实际来看一看堆栈里边儿的内容吧。堆栈里的内容,我们可以通过单条指令执行来查看。

堆栈内容


HW1 boot xv6
https://www.bencorn.com/2021/08/12/HW1-boot-xv6/
作者
Bencorn
发布于
2021年8月12日
许可协议