Add a new section to the developer's handbook about kernel debugging with

Dcons.

Converted from the wiki page [1] by myself as part of Google Code-In 2011.

[1] http://wiki.freebsd.org/DebugWithDcons

Reviewed by:	gavin
Approved by:	gabor (mentor)
This commit is contained in:
Isabell Long 2012-10-04 11:04:11 +00:00
parent c82e042e6b
commit 2498002187
Notes: svn2git 2020-12-08 03:00:23 +00:00
svn path=/head/; revision=39652

View file

@ -786,6 +786,254 @@ Debugger (msg=0xf01b0383 "Boot flags requested debugger")
stack, and do a backtrace with <command>where</command>.</para>
</sect1>
<sect1 id="kerneldebug-dcons">
<title>Kernel debugging with Dcons</title>
<para>&man.dcons.4; is a very simple console driver that is
not directly connected with any physical devices. It just reads
and writes characters from and to a buffer in a kernel or
loader. Due to its simple nature, it is very useful for kernel
debugging, especially with a &firewire; device. Currently, &os;
provides two ways to interact with the buffer from outside of
the kernel using &man.dconschat.8;.</para>
<sect2>
<title>Dcons over &firewire;</title>
<para>Most &firewire; (IEEE1394) host controllers are
based on the <acronym>OHCI</acronym> specification that
supports physical access to the host memory. This means that
once the host controller is initialized, we can access the
host memory without the help of software (kernel). We can
exploit this facility for interaction with &man.dcons.4;.
&man.dcons.4; provides similar functionality as a serial
console. It emulates two serial ports, one for the console
and <acronym>DDB</acronym>, the other for
<acronym>GDB</acronym>. Because remote memory access is fully
handled by the hardware, the &man.dcons.4; buffer is
accessible even when the system crashes.</para>
<para>&firewire; devices are not limited to those
integrated into motherboards. <acronym>PCI</acronym> cards
exist for desktops, and a cardbus interface can be purchased
for laptops.</para>
<sect3>
<title>Enabling &firewire; and Dcons support on the target
machine</title>
<para>To enable &firewire; and Dcons support in the kernel of
the <emphasis>target machine</emphasis>:</para>
<itemizedlist>
<listitem>
<para>Make sure your kernel supports
<literal>dcons</literal>, <literal>dcons_crom</literal>
and <literal>firewire</literal>.
<literal>Dcons</literal> should be statically linked
with the kernel. For <literal>dcons_crom</literal> and
<literal>firewire</literal>, modules should be
OK.</para>
</listitem>
<listitem>
<para>Make sure physical <acronym>DMA</acronym> is enabled.
You may need to add
<literal>hw.firewire.phydma_enable=1</literal> to
<filename>/boot/loader.conf</filename>.</para>
</listitem>
<listitem>
<para>Add options for debugging.</para>
</listitem>
<listitem>
<para>Add <literal>dcons_gdb=1</literal> in
<filename>/boot/loader.conf</filename> if you use GDB
over &firewire;.</para>
</listitem>
<listitem>
<para>Enable <literal>dcons</literal> in
<filename>/etc/ttys</filename>.</para>
</listitem>
<listitem>
<para>Optionally, to force <literal>dcons</literal> to
be the high-level console, add
<literal>hw.firewire.dcons_crom.force_console=1</literal>
to <filename>loader.conf</filename>.</para>
</listitem>
</itemizedlist>
<para>To enable &firewire; and Dcons support in &man.loader.8;
on i386 or amd64:</para>
<para>Add
<literal>LOADER_FIREWIRE_SUPPORT=YES</literal> in
<filename>/etc/make.conf</filename> and rebuild
&man.loader.8;:</para>
<screen>&prompt.root; <userinput>cd /sys/boot/i386 && make clean && make && make install</userinput></screen>
<para>To enable &man.dcons.4; as an active low-level
console, add <literal>boot_multicons="YES"</literal> to
<filename>/boot/loader.conf</filename>.</para>
<para>Here are a few configuration examples. A sample kernel
configuration file would contain:</para>
<screen>device dcons
device dcons_crom
options KDB
options DDB
options GDB
options ALT_BREAK_TO_DEBUGGER</screen>
<para>And a sample <filename>/boot/loader.conf</filename>
would contain:</para>
<screen>dcons_crom_load="YES"
dcons_gdb=1
boot_multicons="YES"
hw.firewire.phydma_enable=1
hw.firewire.dcons_crom.force_console=1</screen>
</sect3>
<sect3>
<title>Enabling &firewire; and Dcons support on the host
machine</title>
<para>To enable &firewire; support in the kernel on the
<emphasis>host machine</emphasis>:</para>
<screen>&prompt.root; <userinput>kldload firewire</userinput></screen>
<para>Find out the <acronym>EUI64</acronym> (the unique 64
bit identifier) of the &firewire; host controller, and
use &man.fwcontrol.8; or <command>dmesg</command> to
find the <acronym>EUI64</acronym> of the target machine.</para>
<para>Run &man.dconschat.8;, with:</para>
<screen>&prompt.root; <userinput>dconschat -e \# -br -G 12345 -t <replaceable>00-11-22-33-44-55-66-77</replaceable></userinput></screen>
<para>The following key combinations can be used once
&man.dconschat.8; is running:</para>
<informaltable pgwide="1">
<tgroup cols="2">
<tbody>
<row>
<entry>
<keycombo action="seq">
<keycap>~</keycap>
<keycap>.</keycap>
</keycombo>
</entry>
<entry>Disconnect</entry>
</row>
<row>
<entry>
<keycombo action="seq">
<keycap>~</keycap>
<keycombo action="simul">
<keycap>Ctrl</keycap>
<keycap>B</keycap>
</keycombo>
</keycombo>
</entry>
<entry>ALT BREAK</entry>
</row>
<row>
<entry>
<keycombo action="seq">
<keycap>~</keycap>
<keycombo action="simul">
<keycap>Ctrl</keycap>
<keycap>R</keycap>
</keycombo>
</keycombo>
</entry>
<entry>RESET target</entry>
</row>
<row>
<entry>
<keycombo action="seq">
<keycap>~</keycap>
<keycombo action="simul">
<keycap>Ctrl</keycap>
<keycap>Z</keycap>
</keycombo>
</keycombo>
</entry>
<entry>Suspend dconschat</entry>
</row>
</tbody>
</tgroup>
</informaltable>
<para>Attach remote <acronym>GDB</acronym> by starting
&man.kgdb.1; with a remote debugging session:</para>
<screen><userinput>kgdb -r :12345 kernel</userinput></screen>
</sect3>
<sect3>
<title>Some general tips</title>
<para>Here are some general tips:</para>
<para>To take full advantage of the speed of &firewire;,
disable other slow console drivers:</para>
<screen>&prompt.root; conscontrol delete ttyd0 # serial console
&prompt.root; conscontrol delete consolectl # video/keyboard</screen>
<para>There exists a <acronym>GDB</acronym> mode for
&man.emacs.1;; this is what you will need to add to your
<filename>.emacs</filename>:</para>
<screen><userinput>(setq gud-gdba-command-name "kgdb -a -a -a -r :12345")
(setq gdb-many-windows t)
(xterm-mouse-mode 1)
M-x gdba</userinput></screen>
<para>And for <acronym>DDD</acronym> (<filename>devel/ddd</filename>):</para>
<screen># remote serial protocol
LANG=C ddd --debugger kgdb -r :12345 kernel
# live core debug
LANG=C ddd --debugger kgdb kernel /dev/fwmem0.2</screen>
</sect3>
</sect2>
<sect2>
<title>Dcons with KVM</title>
<para>We can directly read the &man.dcons.4; buffer via
<filename>/dev/mem</filename> for live systems, and in the
core dump for crashed systems. These give you similar output
to <command>dmesg -a</command>, but the &man.dcons.4; buffer
includes more information.</para>
<sect3>
<title>Using Dcons with KVM</title>
<para>To use &man.dcons.4; with <acronym>KVM</acronym>:</para>
<para>Dump a &man.dcons.4; buffer of a live system:</para>
<screen>&prompt.root; <userinput>dconschat -1</userinput></screen>
<para>Dump a &man.dcons.4; buffer of a crash dump:</para>
<screen>&prompt.root; <userinput>dconschat -1 -M vmcore.XX</userinput></screen>
<para>Live core debugging can be done via:</para>
<screen>&prompt.root; <userinput>fwcontrol -m target_eui64</userinput>
&prompt.root; <userinput>kgdb kernel /dev/fwmem0.2</userinput></screen>
</sect3>
</sect2>
</sect1>
<sect1 id="kerneldebug-options">
<title>Glossary of Kernel Options for Debugging</title>