Project 1: Booting in xv6 (warm-up)

Due: Sep. 15, 2022, 2:30 pm (submission: by email)
Submit a report to TA: Dohyun Kim ( email: ehgus421210@kaist.ac.kr  )
Name your file with “hw1_[your studentid]”. ex: hw1_20221234.pdf

This project is to understand the boot procedure of xv6 OS. Boot the xv6 kernel and explains the contents of the stack when the kernel starts its execution. Starting a kernel follows the similar process as normal function call. Bootloader sets up a parameter for kernel and jumps to the kernel entry point. Then, the kernel starts. In this project, you are required to examine the basic steps associated with loading the kernel and the parameters that are passed to the kernel for starting the OS.

Steps 1
Clone the source code.

$ git clone git://github.com/mit-pdos/xv6-public.git
Cloning into 'xv6-public'...
...
$

Then, build the xv6 binary.

$ 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

...
$

Steps 2
Locate the kernel entry point. If you use the OS other than Linux, please refer to Website and install xv6. In the host OS, e.g. Linux, OSX or etc., use the following command and find the address of the kernel entry point.

$ nm kernel | grep _start
8010a48c D _binary_entryother_start
8010a460 D _binary_initcode_start
0010000c T _start

In this example, the address is 0x0010000c.

Steps 3
Use the command below, execute QEMU GDB.  Set the break point at the address of “start”.

$ make qemu-gdb
...

Leave make qemu-gdb running. Open a new window ( or terminal), navigate to the same directory as you have run gemu-gdb and run gdb. Set the break point at the kernel entry point you have found in step 2.

$ gdb
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying” and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word".
+ target remote localhost:26000
The target architecture is assumed to be i8086
[f000:fff0]    0xffff0:	ljmp   $0xf000,$0xe05b
0x0000fff0 in ?? ()
+ symbol-file kernel
(gdb) br * 0x0010000c
Breakpoint 1 at 0x10000c
(gdb) c
Continuing.
The target architecture is assumed to be i386
=> 0x10000c:	mov    %cr4,%eax

Breakpoint 1, 0x0010000c in ?? ()
(gdb)

Screen output may differ subject to the gdb version. The gdb stops the xv6 kernel at mov instruction. Our objective is to analyze the contents of the kernel stack.

Steps 4
Examine the contents of the registers and the contents of the stack at the kernel entry point. The gdb command “info reg” displays the contents of the registers. The gdb command ‘x’ displays the memory contents at a given address using the specified address format.  It takes the form of ‘x /[format] address’.  (http://visualgdb.com/gdbreference/commands/x ).  We examine the 24 words in the stack. In x86, a word is 4 Byte.

(gdb) info reg
...
(gdb) x/24x $esp
...
(gdb)

To Do
Explain the meaning of each values in the output of x/24x $esp. Which part of the out of x/24x $esp correponds to the kernel stack?

Hints
You can do the followings to perform this project. Before the kernel starts, the bootloader is executed. Bootloader consists of two files, bootasm.S and bootmain.c. These files are responsible for initializing the various memory contents for the kernel to start. Analyzing these two files, you can understand how the bootloader sets up the kernel to start.

  • Find the location of the start of the bootloader. Open the asm and find the location of the “start:”. The location will be 0x7c00. bootblock.asm is the result of compiling bootasm.S and bootmain.c.
  • Find the location of the kernel page table. How large is the physical memory of the (virtual) machine managed by xv6? When xv6 boots, it detects the size of physical memory and initializes the free page list.
  • Start the qemu and gdb. Set the breakpoint at the start address of the bootloader. , 0x7c00. Trace the instruction one by one. You can use si command. Locate the instruction which initializes the stack pointer register ($esp).
  • Execute the c line by line and examine the contents of the stack.
  • Analyze the instructions of bootmain in asm. What are pushed to the stack by bootmain?
  • Recall that the kernel entry point is 0x10000c. Locate the instruction that changes the $eip (instruction pointer) to 0x10000c. Explain the instruction. You can find the address of instructions in bootblock.asm.
  • Resources: Get familiarized with x86 assembly language. Please refer to Reference page for x86 assembly language.