Appendix C: Testing & Debugging

Note: Kernel and bare-metal programming is unforgiving: a single wrong address can hang or silently corrupt the emulated machine with no error message. Start early, build and test in the small increments suggested in each task’s Hints, and lean on gdb. When you’re stuck, the first question to ask is almost always “what address is this, and what does the manual say lives there?”

The QEMU & gdb cheat sheet

Running:

CommandEffect
make qemuBuild and run in QEMU; serial console attached to your terminal.
make qemu-gdbSame, but paused and waiting for gdb on port 1234.
Ctrl-a then xQuit QEMU.
Ctrl-a then cToggle to/from QEMU’s own monitor console.

Debugging (run gdb, or gdb-multiarch on Linux/WSL, in a second terminal; the provided .gdbinit connects and loads symbols automatically):

gdb commandEffect
break <symbol> / break <file>:<line>Set a breakpoint.
continue (c)Resume execution.
Ctrl-cInterrupt the running machine and return to the gdb prompt.
stepi / nextiStep one machine instruction.
info registersDump all registers.
p/x $x0Print register x0 in hex (p $x0 for decimal).
x/8xw <addr>Examine 8 words of memory in hex at <addr>.
disassembleShow the disassembly around the current instruction.

Note: If gdb warns about an add-auto-load-safe-path directive, follow the instructions in the repository’s README to allow the project’s .gdbinit.