See also: Episode I
Setting up the NetBSD kernel debugging environment
NetBSD has its own kernel debugger named DDB. As the original documentation states, is useful for gathering crash tracebacks, examining the values of variables, and other minor debugging tasks, but if youre doing serious kernel hacking you will want to setup to work with the remote debugger, KGDB, instead.
There is a few HOWTOs on how to setup remote debugging for NetBSD kernel on the Internet.
The first one is the official NetBSD documentation chapter. It describes how to set up debugging using two computers connected with null-model cable.
The second one is a tutorial by Alexander Shishkin. It involves QEMU to host the debugged system, so the work can be done on a single PC. However, it uses a custom script for generating disk image with kernel and the basic userland. It looks a bit tricky.
I have wanted to use a normal system from the official distribution ISO image. Also I had only one laptop with NetBSD and QEMU was the solution. So, my way is a combination of the both methods mentioned above.
Building the kernel
Building kernel is fairly easy. All we need is just to modify the configuration to enable KGDB and to generate a full symbol table. The following steps are taken from the already referred official documentation:
# cd /usr/src/sys/arch/i386/conf # cp GENERIC DEBUGGING
DEBUGGING are build configuration files. These files determine what will be included into the kernel, which options will be enabled or disabled and so on.
GENERIC is a basic configuration file and the stock NetBSD kernel is built as
I have named a new configuration as "DEBUGGING". In the
DEBUGGING configuration file, the following lines have to be commented with the preceiding pragma (
#options DDB # in-kernel debugger #options DDB_HISTORY_SIZE=100 # enable history editing
and the following lines have to be uncommented by removing the preceiding pragma:
options KGDB # remote debugger options "KGDB_DEVNAME=\"com\"",KGDB_DEVADDR=0x3f8,KGDB_DEVRATE=9600 makeoptions DEBUG="-g" # compile full symbol table
KGDB_DEVADDR option sets the address of the serial port which will be used for debugging.
There is just a few things left to build the kernel:
# config DEBUGGING # cd ../compile/DEBUGGING # make depend # make
That is all! After the successful compilation we will get
netbsd.gdb files in the current directory. It is a new kernel and debugging symbols for GDB respectively.
Preparing the guest system
Now we need to get a basic system working in QEMU. The following commands will create a 2GB QEMU hard disk image and run the NetBSD installer for it:
$ qemu-img create netbsd.img 2G $ qemu -hda netbsd.img -cdrom i386cd-5.0.2.iso -boot d -m 196 -localtime
All QEMU options in the last command are quite straightforward, the most interesting are:
-hda-- specifies a hard disk image that we have created a step before (netbsd.img);
-cdrom-- specifies an installation CD ISO image (
i386cd-5.0.2.isoin my case)
-boot d-- tells QEMU to boot from a virtual CD-ROM instead of the hard disk image;
After the successful installation we will need to restart QEMU with some different options:
$ qemu -hda netbsd.img -boot c -m 196 -localtime \ -net user -net nic,model=rtl8139 \ -redir tcp:5555::22
-net options will enable networking in the guest. The last
-redir option will allow us to connect to the guest with
ssh via the localhost port 5555.
After the system will boot, log in as root and run
to obtain an IP address.
ping will not work, but pkgsrc will. I have installed Git and OpenSSHd.
Installation of a new kernel is quite simple. With QEMU networking the host machine usually appears as
10.0.2.2, so the kernel can be transferred with
# mv /netbsd /netbsd.old # scp email@example.com:/usr/src/sys/arch/i386/compile/DEBUGGING/netbsd /
Again, we will need to restart QEMU in a new configuration:
$ qemu -hda netbsd.img -boot c -m 196 -localtime \ -net user -net nic,model=rtl8139 \ -redir tcp:5555::22 \ -serial tcp::4444,server
The last option
-serial tcp::4444,server creates a pipe from a host's port 4444 to guest's serial port (remember KGDB options in the kernel configuration).
QEMU will start but will not launch the guest system until we connect to this port. It is time to open
(gdb) symbol-file /usr/src/sys/arch/i386/compile/DEBUGGING/netbsd.gdb (gdb) target remote :4444
QEMU window will appear and we will need to boot the guest system with a different command in the NetBSD bootloader:
After some seconds the guest system will enter an initial breakpoint and in the gdb shell we will get something like this:
0xc053556c in breakpoint () (gdb)
Great! Now everything is ready for debugging.
(to be continued)