Here are a few debugging strategies you can use to debug your kernel.
Qemu is a good first test to see if what you implemented might work but Qemu also emulates most devices lazily. This means it won’t tell you if your note initializing your serial or your CD-ROM driver properly, for example.
Bochs is another alternative for testing your kernel. It is an x86 emulator that does a very precise emulation of the devices, and it will tell you if what you are doing is wrong.
Simple configuration file
Here is a simple configuration file (
.bochsrc) you can use to debug k:
# # start a fancy GUI # display_library: x, options="gui_debug" # Have a sane clock clock: sync=realtime # # start a GDB server # gdbstub: enabled=1, port=1234, text_base=0, data_base=0, bss_base=0 # configure the disk drive ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14 ata0-master: type=cdrom, path="k.iso", status=inserted boot: cdrom # write serial logs to stdout com1: enabled=1, mode=file, dev=/dev/stdout # log: out.log # #debugger_out: /dev/stdout # # super userful option here, you can find all modules here http://bochs.sourceforge.net/doc/docbook/user/howto.html#LOGOPTS-BY-DEVICE # # cpu0 and harddrv are the most useful # debug: action=ignore, harddrv=report, hdimage=report # info: action=report # error: action=report # panic: action=ask
All you have to do is put the configuration file at the root of your project,
bochs, without arguments, and press Enter in the menu it will show you.
Did you check you segment selectors ?
Most of the problems you will encounter at the beginning of the project comes from your memory setup. Double or triple-check the values of your segment selectors, GDTR, and GDT entries.
Learn to use gdb
On Qemu, you can combine two options to launch gdb:
-S: pauses the execution right at the beginning (before GRUB)
-s: launches a gdb server you can connect to
To connect to the gdb server:
~/repo/k > gdb k/k (gdb) target remote localhost:1234 # or use the shorter version (gdb) tar rem :1234
Putting this in a gdb script might be a good idea..
More advanced use
Qemu and Bochs can both run a gdb server in the background for you to debug your
kernel, so use them ! Even after you jump to userland (where gdb can not
understand the addresses because of the segmentation), you can still find out
where are you in your code, or your roms’ (
objdump -D may be of use for that).
After jumping to userland, some simple pointer arithmetics using your segment’s
base addresses may help you.
x) command may especially be useful, for example to dump your
In some cases, the
record command of gdb may help you to understand what your
code is doing. Using it will allow you to use the
reverse-* variants of
Displaying assembly code and registers in gdb
To have the assembly code of your program and the registers at the same time in tui mode, do the following, in this order:
layout asm layout reg
If gdb throw some errors at you
Make sure of the following:
- You use
qemu-system-x86_64. We are in 32 bits, so use the
- When using gdb, you can’t use the
-enable-kvmoption of qemu.