HW1 boot xv6
Boot xv6
1、拉取 xv6 源代码文件
1 |
|
2、编译 xv6
1 |
|
Finding and breaking at an address
1、找到内核的入口点的地址,即 _start 的地址
1 |
|
在这个例子中,地址是 0x0010000c
2、在 QEMU-GDB 内跑内核代码,并且设置刚刚找到的断点
1 |
|
并且在另外一个 shell 中,使用 gdb,并且输入target remote:26000
连接上qemu进行调试,通过添加断点,我们可以让 qemu 执行停在内核的入口地址处。
Exercise:What is on the stack
当我们在断点 0x0010000c 处查看寄存器和 stack 内的内容:
1 |
|
我们可以关注一下一些我们处理过的寄存器,一个是和堆栈相关的寄存器 %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/