Jason Xu 9c5c2813a0 Update QEMU command in all README and Makefile | 2 years ago | |
---|---|---|
.. | ||
Makefile | 5 years ago | |
Makefile.clang | 2 years ago | |
Makefile.gcc | 2 years ago | |
OLVASSEL.md | 2 years ago | |
README.md | 2 years ago | |
dbg.c | 6 years ago | |
dbg.h | 6 years ago | |
disasm.h | 5 years ago | |
gpio.h | 6 years ago | |
kernel8.img | 3 years ago | |
link.ld | 6 years ago | |
main.c | 6 years ago | |
mbox.c | 6 years ago | |
mbox.h | 6 years ago | |
sprintf.c | 6 years ago | |
sprintf.h | 6 years ago | |
start.S | 3 years ago | |
uart.c | 3 years ago | |
uart.h | 6 years ago |
Let's rock by implementing an interactive debugger in our exception handler! :-) Now that we have printf(), it shouldn't be hard. (For a more roboust multiplatform library, see mini debugger.)
$ qemu-system-aarch64 -M raspi3b -kernel kernel8.img -serial stdio
Synchronous: Breakpoint instruction
> x
0007FFF0: 13 60 09 00 00 00 00 00 24 10 20 3F 00 00 00 00 .`......$. ?....
> i x30 x30+64
00080804: D2800000 movz x0, #0x0
00080808: 94003D1C bl 0x8FC78
0008080C: 94003ECF bl 0x90348
00080810: D69F03E0 eret
00080814: D503201F 27 x nop
>
A very minimal and simple debugger (~300 lines in C).
breakpoint
a newly defined keyword. We can use this anywhere in our code where we want to invoke the debugger
dbg_decodeexc()
similar to exc_handler in tutorial 11, decodes the cause of the exception and prints it
dbg_getline()
yep, another low level library we're missing. We need a way to allow the user to edit command line
and return it as a string when he/she presses Enter. A minimal implementation, as usual
dbg_getoffs()
this function parses the command line for arguments. Accepts hex, decimal number in
"register+/-offset" format
dbg_main()
the main loop of the debugger.
Because it's small (~64k), yet supports all ARMv8.2 instructions, only depends on sprintf() (which we have now), I decided to use the Universal Disassembler for this tutorial. If you don't want to compile a disassembler into your debugger, simply set the DISASSEMBLER define 0 in top of dbg.c.
Our _vector
table looks different. We have to save registers in memory with dbg_saveregs
, print out
the cause of the exception, and call our mini-debugger's main loop.
We'll test our shiny new breakpoint
keyword in C.