This page gives a brief overview of the JOS environment and useful GDB and QEMU commands. Read the GDB and QEMU manuals if you need a detailed understanding of how to use them. These are powerful tools that are worth knowing how to use. Basic commands required for the assignments and projects are given in this page.
Most modern Linux distributions and BSDs have an ELF toolchain compatible with JOS. That is, the system-standard gcc, as, ld and objdump should just work. The Makefile should automatically detect this. If the makefile fails to detect your build tools, you can specify their location by adding the following line to conf/env.mk:
GCCPREFIX=
The standard version of gdb does not correctly handle the transition to long mode during JOS boot, yielding a "Packet too long" error. For debugging 64-bit code on a 32-bit platform, you need both gdb and gdb-multiarch. Below we post patched Ubuntu packages.
In lab systems, you will need to extract the package. Use dpkg -x <package> <destination> to extract the contents of the package to user-defined location. The gdb executable is located in usr/bin folder inside the destination.
Eg: dpkg -x gdb_7.7.1-0ubuntu5~14.04.2_amd64.deb $HOME/gdb_7.7 GDB exectuable can be found at $HOME/gdb_7.7/usr/bin
gdb7.2 requires python2.6 and gdb7.7 requires python3.4 to run . Download and install python3.4 as given below:
wget https://www.python.org/ftp/python/3.4.5/Python-3.4.5rc1.tar.xz tar xf Python-3.4.5rc1.tar.xz ./configure --prefix=$HOME/python3.4 --enable-shared --with-threads make make install
After installing Python3.4, set LD_LIBRARY_PATH to <destination-dir>/lib.
NOTE: If you have sudo access, you can instead use dpkg -i <package> to install gdb in /usr/bin . Note that this would replace the original gdb if anything was previously installed.
QEMU is a modern and fast PC emulator. Follow the build instructions in the link to download and build qemu.
Update QEMUPATH env variable to point to the right qemu executable, which is, <root-dir-for-qemu>/i386-softmmu/qemu-system-i386. Note that you have to specify the executable and not just the path here.
You will have to clone the git repository for your group using the command below.
git clone <link-for-the repo>
The actual link for the repo will be specified in the respective assignments/projects. After cloning the repo, do cd <repodir> and run make. You should see something like this.
make + as kern/entry.S + cc kern/init.c + cc kern/console.c + cc kern/monitor.c + cc kern/printf.c + cc lib/printfmt.c + cc lib/readline.c + cc lib/string.c + ld obj/kern/kernel + as boot/boot.S + cc -Os boot/main.c + ld boot/boot boot block is 414 bytes (max 510) + mk obj/kern/kernel.img
If you get errors like "undefined reference to `__udivdi3'", you probably don't have the 32-bit gcc multilib. If you're running Debian or Ubuntu, try installing the gcc-multilib package.)
Now, you are ready to run QEMU.
Now you're ready to run QEMU, supplying the file obj/kern/kernel.img, created above, as the contents of the emulated PC's "virtual hard disk." This hard disk image contains both our boot loader (obj/boot/boot) and our kernel (obj/kern/kernel).
make qemu
The above command executes QEMU with the options required to set the hard disk and direct serial port output to the terminal. (You could also use make qemu-nox to run QEMU in the current terminal instead of opening a new one.)
Some text should appear in the QEMU window:
Booting from Hard Disk... 6828 decimal is XXX octal! entering test_backtrace 5 entering test_backtrace 4 entering test_backtrace 3 entering test_backtrace 2 entering test_backtrace 1 entering test_backtrace 0 leaving test_backtrace 0 leaving test_backtrace 1 leaving test_backtrace 2 leaving test_backtrace 3 leaving test_backtrace 4 leaving test_backtrace 5 Welcome to the JOS kernel monitor! Type 'help' for a list of commands. K>
Everything after 'Booting from Hard Disk...' was printed by our skeletal JOS kernel; the K> is the prompt printed by the small monitor, or interactive control program, that we've included in the kernel. These lines printed by the kernel will also appear in the regular shell window from which you ran QEMU. Likewise, the JOS kernel will take input from both the keyboard and the serial port, so you can give it commands in either the VGA display window or the terminal running QEMU.
To verify the working of gdb with qemu, run gdb from the same directory from which you ran make. Make sure you specify path for the correct gdb that you installed above. You should now be able to debug JOS using gdb.
GDB is your friend. Use the qemu-gdb target (or its qemu-gdb-nox variant) to make QEMU wait for GDB to attach. See the GDB reference below for some commands that are useful when debugging kernels.
If you're getting unexpected interrupts, exceptions, or triple faults, you can ask QEMU to generate a detailed log of interrupts using the -d argument.
GDB also lets you debug user environments, but there are a few things you need to watch out for, since GDB doesn't know that there's a distinction between multiple user environments, or between user and kernel.
You can start JOS with a specific user environment using make run-name (or you can edit kern/init.c directly). To make QEMU wait for GDB to attach, use the run-name-gdb variant.
You can symbolically debug user code, just like you can kernel code, but you have to tell GDB which symbol table to use with the symbol-file command, since it can only use one symbol table at a time. The provided .gdbinit loads the kernel symbol table, obj/kern/kernel. The symbol table for a user environment is in its ELF binary, so you can load it using symbol-file obj/user/name. Don't load symbols from any .o files, as those haven't been relocated by the linker (libraries are statically linked into JOS user binaries, so those symbols are already included in each user binary). Make sure you get the right user binary; library functions will be linked at different EIPs in different binaries and GDB won't know any better!
Since GDB is attached to the virtual machine as a whole, it sees clock interrupts as just another control transfer. This makes it basically impossible to step through user code because a clock interrupt is virtually guaranteed the moment you let the VM run again. The stepi command works because it suppresses interrupts, but it only steps one assembly instruction. Breakpoints generally work, but watch out because you can hit the same EIP in a different environment (indeed, a different binary altogether!).
When building JOS, the makefile also produces some additional output files that may prove useful while debugging:
See the GDB manual for a full guide to GDB commands. Here are some particularly useful commands for this course, some of which don't typically come up outside of OS development.
QEMU represents each virtual CPU as a thread in GDB, so you can use all of GDB's thread-related commands to view or manipulate QEMU's virtual CPUs.
QEMU includes a built-in monitor that can inspect and modify the machine state in useful ways. To enter the monitor, press Ctrl-a c in the terminal running QEMU. Press Ctrl-a c again to switch back to the serial console.
For a complete reference to the monitor commands, see the QEMU manual. Here are some particularly useful commands:
CS =0008 10000000 ffffffff 10cf9a00 DPL=0 CS32 [-R-]
ef7c0000-ef800000 00040000 urw efbf8000-efc00000 00008000 -rwtells us that the 0x00040000 bytes of memory from 0xef7c0000 to 0xef800000 are mapped read/write and user-accessible, while the memory from 0xefbf8000 to 0xefc00000 is mapped read/write, but only kernel-accessible.
4: v=30 e=0000 i=1 cpl=3 IP=001b:00800e2e pc=00800e2e SP=0023:eebfdf28 EAX=00000005 EAX=00000005 EBX=00001002 ECX=00200000 EDX=00000000 ESI=00000805 EDI=00200000 EBP=eebfdf60 ESP=eebfdf28 ...The first line describes the interrupt. The 4: is just a log record counter. v gives the vector number in hex. e gives the error code. i=1 indicates that this was produced by an
int
instruction (versus a hardware
interrupt). The rest of the line should be self-explanatory. See
info registers for a description
of the register dump that follows.