Address: Homework: the Boot xv6
Environmental deployment
-
Copy the project to the local
use the following command in the directory 6.828:git clone git://github.com/mit-pdos/xv6-public.git
copy the project to the local. After usemake
can be. -
Use gdb debugger
open two terminals have entered the 6.828 / xv6-public directory. The first terminal uses a commandmake qemu-gdb
, a second command is usedgdb
[1] . Running inside the terminal gdb break point 0x10000c, run commands input c. And using theinfo reg
view of each register value, usedx/24x $esp
to view the contents inside the stack.
[1]:如果使用gdb调试的时候不成功,那么可以尝试在~/.gdbinit文件里面加入下面的内容:
add-auto-load-safe-path /home/(你的用户名)/6.828/xv6-public/.gdbinit
set auto-load safe-path /
Stack content analysis
By the above debugging can be obtained when executed at the 0x10000c, each register is:
eax 0x0 0
ecx 0x0 0
edx 0x1f0 496
ebx 0x10074 65652
esp 0x7bdc 0x7bdc
ebp 0x7bf8 0x7bf8
esi 0x10074 65652
edi 0x0 0
eip 0x10000c 0x10000c
eflags 0x46 [ PF ZF ]
cs 0x8 8
ss 0x10 16
ds 0x10 16
es 0x10 16
fs 0x0 0
gs 0x0 0
Inside the stack contents are as follows:
0x7bdc: 0x00007d8d 0x00000000 0x00000000 0x00000000
0x7bec: 0x00000000 0x00000000 0x00000000 0x00000000
0x7bfc: 0x00007c4d 0x8ec031fa 0x8ec08ed8 0xa864e4d0
0x7c0c: 0xb0fa7502 0xe464e6d1 0x7502a864 0xe6dfb0fa
0x7c1c: 0x16010f60 0x200f7c78 0xc88366c0 0xc0220f01
0x7c2c: 0x087c31ea 0x10b86600 0x8ed88e00 0x66d08ec0
Next, analyze the content of the stack inside.
Note: The stack grows downwards.
First of all you need to know the rules gcc function call, see: gcc x86 Calling Conventions inside "gcc x86 calling conventions" one.
In bootblock.asm in:
call bootmain
7c48: e8 ee 00 00 00 call 7d3b <bootmain>
# If bootmain returns (it shouldn't), trigger a Bochs
# breakpoint if running under Bochs, then loop.
movw $0x8a00, %ax # 0x8a00 -> port 0x8a00
7c4d: 66 b8 00 8a mov $0x8a00,%ax
Address bootmain statement calling function is 0x7c48, call bootmain the address of the next instruction is 7c4d, so when performing call bootmain, the program will 7c4d pushed onto the stack.
In bootmain function inside:
00007d3b <bootmain>:
{
7d3b: 55 push %ebp
7d3c: 89 e5 mov %esp,%ebp
7d3e: 57 push %edi
7d3f: 56 push %esi
7d40: 53 push %ebx
It can be seen that the first press-fitting register ebp, and then pressed into edi, esi, ebx.
In 7d87 place, are:
entry();
7d87: ff 15 18 00 01 00 call *0x10018
Then steering actuator entry () function.
After this one statement is finished, EIP become a 0x10000c (Why not 0x10018 I am not very clear). So the process functions performed probably the case, and now look at the contents inside the stack:
0x7bdc: 0x00007d8d 0x00000000 0x00000000 0x00000000
0x7bec: 0x00000000 0x00000000 0x00000000 0x00000000
0x7bfc: 0x00007c4d 0x8ec031fa 0x8ec08ed8 0xa864e4d0
0x7c0c: 0xb0fa7502 0xe464e6d1 0x7502a864 0xe6dfb0fa
0x7c1c: 0x16010f60 0x200f7c78 0xc88366c0 0xc0220f01
0x7c2c: 0x087c31ea 0x10b86600 0x8ed88e00 0x66d08ec0
You can see, there are a number of 7c4d at 0x7bfc, can determine this is to return the call bootmain pressed into the address, the rightmost 7dec the line that is a ebp value because after entering bootmain function first pushed is the value of% ebp.
In addition, bootmain function which can be seen:
entry();
7d87: ff 15 18 00 01 00 call *0x10018
7d8d: eb d5 jmp 7d64 <bootmain+0x29>
entry () function returns the address 0x7d8d, can be obtained leftmost stack entry that is inside the row 7bdc return address (). In summary, you could receive a stack frame following function:
+-----------+ ---0x7c00
|0x7c4d | ---0x7bfc(bootmain返回地址)
|0x0000 | ---0x7bf8(bootmain的ebp值)
|0x0000 | ---0x7bf4
|0x0000 | ---0x7bf0
|0x0000 | ---0x7bec
|0x0000 | ---0x7be8
|0x0000 | ---0x7be4
|0x0000 | ---0x7be0
|0x7d8d | ---0x7bdc(entry的返回地址)(当前的%esp指向这里,使用info reg即可查看)
| | ---0x7bd8
| |
| |
| |
Use info reg
get:
eax 0x0 0
ecx 0x0 0
edx 0x1f0 496
ebx 0x10074 65652
esp 0x7bdc 0x7bdc
ebp 0x7bf8 0x7bf8
esi 0x10074 65652
edi 0x0 0
eip 0x10000c 0x10000c
eflags 0x46 [ PF ZF ]
cs 0x8 8
ss 0x10 16
ds 0x10 16
es 0x10 16
fs 0x0 0
gs 0x0 0
Can be clearly seen, the current ebp (which function entry) points to the ebp boomain, bootmain ebp points of 0x0.
0x7c00 stack from the beginning, because bootasm.S in:
# Set up the stack pointer and call into C.
movl $start, %esp
call bootmain
Bootmain before calling the function, already set the stack ($ start value of 0x7c00).