Add some documention on how to use seL4 debugging
Change-Id: I8bf75fc3b21c72e54dc567ccc9d53731184fc124
diff --git a/KataGdbUserSpaceDebugging.md b/KataGdbUserSpaceDebugging.md
new file mode 100644
index 0000000..a360ee0
--- /dev/null
+++ b/KataGdbUserSpaceDebugging.md
@@ -0,0 +1,123 @@
+# How to Use GDB with Renode to Debug seL4 Threads with Symbols
+
+## High-Level Usage
+
+The method for debugging seL4 threads with Renode is relatively simple, and
+involves the usual suspects of `m simulate-debug` and `kgdb.sh`, but the
+interface through GDB has changed slightly. In general, a debugging session now
+looks like the following:
+
+On one terminal, start an instance of Renode:
+```bash
+source build/setup.sh
+m simulate-debug
+```
+
+Once Renode has started and starts outputting green debug logs, in another
+terminal start up GDB with:
+```bash
+kgdb.sh
+```
+
+At this point, GDB should connect to the running Renode instance started by
+`simulate-debug`, and you'll see something equivalent to the following (output
+is not exact -- symbol reading may differ):
+
+```
+ghost:~/$ kgdb.sh
+Source directories searched: /usr/local/google/home/jtgans/shodan/sw/tock:$cdir:$cwd
+Reading symbols from out/shodan_boot_rom/build-out/multihart_boot_rom/multihart_boot_rom_sim_verilator.elf...
+add symbol table from file "out/shodan_boot_rom/build-out/multihart_boot_rom/multihart_boot_rom_sim_verilator.elf"
+Reading symbols from out/shodan_boot_rom/build-out/multihart_boot_rom/multihart_boot_rom_sim_verilator.elf...
+add symbol table from file "out/matcha/riscv32imc-unknown-none-elf/debug/matcha_platform"
+Reading symbols from out/matcha/riscv32imc-unknown-none-elf/debug/matcha_platform...
+add symbol table from file "out/matcha/riscv32imc-unknown-none-elf/debug/matcha_app"
+Reading symbols from out/matcha/riscv32imc-unknown-none-elf/debug/matcha_app...
+Remote debugging using localhost:3333
+warning: multi-threaded target stopped without sending a thread-id, using first non-exited thread
+0x20007b4a in tock_cells::map_cell::MapCell<kernel::callback::AppId>::is_some<kernel::callback::AppId> (self=0x10005af4 <matcha_platform::reset_handler::BUF>)
+ at /usr/local/google/home/jtgans/shodan/sw/tock/libraries/tock-cells/src/map_cell.rs:47
+47 self.occupied.get()
+(gdb)
+```
+
+At this point, GDB has stopped the simulator, giving you a chance to set
+breakpoints and examine the system.
+
+`kgdb.sh` will automatically load symbols on the seL4 side, based upon their
+thread names, so there is no need to manually find the associated symbol file
+and load it with the correct offsets. It may be necessary to switch symbol
+tables, which can easily be done using `sel4 switch-symbols <threadname>`, which
+will automatically load them with the appropriate offsets.
+
+In this environment, there are two sets of breakpoints that can be used:
+standard gdb `break`-style breakpoints, and renode-side `sel4 break`
+breakpoints. The former work within the currently executing thread and can be
+used for "local" breaks inside of a thread, whereas the latter can be set in any
+thread that was previously discovered by the Renode extension.
+
+Once you've setup your breakpoints using `sel4 break`, you'll need to tell
+Renode to enable breakpoints as well with `sel4 breakpoints-enabled True`, and
+then `continue`. For example, consider this debugging session:
+
+```
+<assuming cpu1 is halted and gdb is waiting at a prompt>
+
+(gdb) # Wait until 'rootserver' thread is set up in seL4
+(gdb) sel4 wait-for-thread rootserver
+
+(gdb) # rootserver thread is now the symbol "main" in the thread/program, so we
+(gdb) # can break on stopped and associated symbols are loaded.
+(gdb) sel4 break rootserver main
+
+(gdb) # Enable extension breakpoints (it's disabled by default as it's pretty
+(gdb) # performance-heavy as Renode has to break on every context-switch)
+(gdb) sel4 breakpoints-enabled True
+(gdb) c
+
+(gdb) # We are in capdl-loader main() function, disable extension breakpoints
+(gdb) sel4 breakpoints-enabled False
+
+(gdb) # As we are in capdl-loader thread and proper symbols are loaded, all commands
+(gdb) # like break are working correctly
+(gdb) b init_system
+(gdb) c
+```
+
+## Theory of Operation
+
+The kgdb.sh / Renode symbol lookup mechanism is composed of two parts: a custom
+Renode extension in `sim/config/shodan_infrastructure/seL4Extensions.cs` and a
+custom GDB extension in `sim/config/gdbscript.py`. `kgdb.sh` is a simple bash
+script that starts GDB and connects to the appropriate remote with the extension
+loaded.
+
+The Renode extension tracks the VSpace setup for each thread and translates
+virtual addresses to physical addresses. Without this work symbols may be
+incorrectly resolved because every VSpace memory range starts at 0.
+
+In addition, the extension provides commands to Renode to add debugging hooks to
+an execution, all prefixed with the subcommand `seL4` (case matters at the
+Renode prompt!). In our simulation config, Renode is configured to start the
+seL4 extension on cpu1 using the `cpu1 CreateseL4` command.
+
+The GDB extension provides a matching set of wrappers via the `sel4` command
+prefix to examine the simulator state and take a look at threads in the system.
+
+Both extensions provide built in help at their respective command lines, but
+suffice it to say, the GDB extension is essentially just an automation mechanism
+to load in symbols for the current thread context from disk when the Renode
+extension detects a context switch.
+
+During debugging, not all symbols will be loaded in GDB at the start, so it can
+be helpful to use `sel4 wait-for-thread <threadname>` to tell Renode to break
+execution upon entry of the given thread. When the break occurs, Renode will
+instruct GDB to load the correct symbol table, and then symbols can be resolved
+for later breakpoints, etc.
+
+To set a breakpoint for a thread that is not the current context, use the `sel4
+break <threadname> <symbol>` command. This will instruct Renode to load the
+appropriate symbol table and break at the right place once that thread is
+running. If, however, you need to set a breakpoint in the current thread
+context, it's fine to use `break` as normal, since the symbols for the current
+thread should be loaded.