This lecture is the introduction to xv6, our re-implementation of Unix v6. Read the source code in the assigned files. You won't have to understand the details yet; we will focus on how the first user-level process comes into existence after the computer is turned on.
Hand-In Procedure
You are to turn in this homework during lecture. Please write up your answers to the exercises below and hand them in to a 6.828 staff member at the beginning of lecture.
Assignment:
Fetch and un-tar the xv6 source:
sh-3.00$ wget http://pdos.csail.mit.edu/6.828/2007/src/xv6-rev1.tar.gz sh-3.00$ tar xzvf xv6-rev1.tar.gz xv6/ xv6/asm.h xv6/bio.c xv6/bootasm.S xv6/bootmain.c ... $Build xv6:
$ cd xv6 $ make gcc -O -nostdinc -I. -c bootmain.c gcc -nostdinc -I. -c bootasm.S ld -N -e start -Ttext 0x7C00 -o bootblock.o bootasm.o bootmain.o objdump -S bootblock.o > bootblock.asm objcopy -S -O binary bootblock.o bootblock ... $Find the address of the
main
function by
looking in kernel.asm
:
% grep main kernel.asm ... 00102454 <mpmain>: mpmain(void) 001024d0 <main>: 10250d: 79 f1 jns 102500 <main+0x30> 1025f3: 76 6f jbe 102664 <main+0x194> 102611: 74 2f je 102642 <main+0x172>In this case, the address is
001024d0
.
Run the kernel inside Bochs, setting a breakpoint
at the beginning of main
(i.e., the address
you just found).
$ make bochs if [ ! -e .bochsrc ]; then ln -s dot-bochsrc .bochsrc; fi bochs -q ======================================================================== Bochs x86 Emulator 2.2.6 (6.828 distribution release 1) ======================================================================== 00000000000i[ ] reading configuration from .bochsrc 00000000000i[ ] installing x module as the Bochs GUI 00000000000i[ ] Warning: no rc file specified. 00000000000i[ ] using log file bochsout.txt Next at t=0 (0) [0xfffffff0] f000:fff0 (unk. ctxt): jmp far f000:e05b ; ea5be000f0 (1) [0xfffffff0] f000:fff0 (unk. ctxt): jmp far f000:e05b ; ea5be000f0 <bochs>Look at the registers and the stack contents:
<bochs> info reg ... <bochs> print-stack ... <bochs>Which part of the stack printout is actually the stack? (Hint: not all of it.) Identify all the non-zero values on the stack.
Turn in: the output of print-stack with the valid part of the stack marked. Write a short (3-5 word) comment next to each non-zero value explaining what it is.
Now look at kernel.asm for the instructions in main that read:
10251e: 8b 15 00 78 10 00 mov 0x107800,%edx 102524: 8d 04 92 lea (%edx,%edx,4),%eax 102527: 8d 04 42 lea (%edx,%eax,2),%eax 10252a: c1 e0 04 shl $0x4,%eax 10252d: 01 d0 add %edx,%eax 10252f: 8d 04 85 1c ad 10 00 lea 0x10ad1c(,%eax,4),%eax 102536: 89 c4 mov %eax,%esp(The addresses and constants might be different on your system, and the compiler might use
imul
instead of the lea,lea,shl,add,lea
sequence.
Look for the move into %esp
).
Which lines in main.c
do these instructions correspond to?
Set a breakpoint at the first of those instructions and let the program run until the breakpoint:
<bochs> vb 0x8:0x10251e <bochs> s ... <bochs> c (0) Breakpoint 2, 0x0010251e (0x0008:0x0010251e) Next at t=1157430 (0) [0x0010251e] 0008:0x0010251e (unk. ctxt): mov edx, dword ptr ds:0x107800 ; 8b1500781000 (1) [0xfffffff0] f000:fff0 (unk. ctxt): jmp far f000:e05b ; ea5be000f0 <bochs>(The first
s
command is necessary
to single-step past the breakpoint at main, otherwise c
will not make any progress.)
Inspect the registers and stack again
(info reg
and print-stack
).
Then step past those seven instructions
(s 7
)
and inspect them again.
Convince yourself that the stack has changed correctly.
Turn in: answers to the following questions.
Look at the assembly for the call to
lapic_init
that occurs after the
the stack switch. Where does the
bcpu
argument come from?
What would have happened if main
stored bcpu
on the stack before those four assembly instructions?
Would the code still work? Why or why not?