EE488: Kernel Design, Fall 2020

Project 1: in (warm-up)

Due: Sep. 14, 2020, 11:59 pm (submission: by email) Submit a report to TA: Joontaek Oh ( email: [email protected] ) Name your file with “hw1_[your studentid]”. ex: hw1_2019031234.

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 . Starting a kernel follows the similar 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 steps associated with loading the kernel and the parameters that are passed to the kernel for starting the OS.

Steps 1 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 $ ... gcc -O -nostdinc -I. - bootmain.c gcc -nostdinc -I. -c bootasm. 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 , 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 _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 Foundation, Inc. License GPLv3+: GNU GPL version 3 or later This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. "show copying” and "show warranty" for details. This GDB was configured as "x86_64-linux-".

Type "show configuration" for configuration details. For bug reporting instructions, please see: . Find the GDB manual and other documentation resources online at: . 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 “ 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 , 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’. 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 bootblock.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.

• 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. the instruction which initializes the stack pointer register ($esp).

• Execute the bootmain.c line by line and examine the contents of the stack. • Analyze the instructions of bootmain in bootblock.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 . Please refer to Reference page for x86 assembly language.