This was tested using the console provided by IPMI over LAN.
(The setup may be simpler when the console is attached to a physical serial port).
The test goal is to be able to perform basic remote debugging, using 2 machines with the same FreeBSD version.
For the debuggee, a physical POWER8 machine was used.
For the debugger, a POWER8 VM emulated by QEMU was used.
Note: for now, this was tested only with ELFv1 systems and with /usr/libexec/kgdb, as recent gdb/kgdb versions fail to attach to a remote FreeBSD target.
Below are the steps needed to establish a debug connection between the 2 machines:
1. QEMU is invoked to start the debugger VM. An extra serial port is added to it and connected to a pseudo-terminal (`-serial pty`). QEMU prints the path to the allocated pseudo-terminal (pty).
2. On another host terminal, use the screen command to attach to the pty. Ex: `screen /dev/pts/3`.
Next, execute the ipmitool command needed to activate a console to the debuggee machine, redirecting its I/O to the pty.
Inside screen, this can be achieved by the following command: `C-a :` then `exec !::/path/to/ipmi.sh`, where ipmi.sh is a script that runs ipmitool with all needed args and flags.
`!` connects ipmitool's stdin to the pty and `:` connects its output to both the pty and screen output (see screen(1) for more details).
3. On the VM, start minicom or a similar program, to start controlling the remote machine through the serial port.
When Petitboot is reached, start FreeBSD in debug mode and specify the debug port path.
Ex: `kexec -l kernel -c 'hw.uart_opal.dbgport=/ibm,opal/consoles/serial@0 -d' -e`.
4. FreeBSD kernel should detect the OPAL DGBPORT and stop at DDB prompt. Type `gdb` to switch to the gdb backend.
5. Then, either close minicom or open another terminal on the VM to start kgdb and attach to the remote machine.
Ex: `kgdb kernel` then `target remote /dev/cuau0`.
After the final step, the debug connection should (finally) be established, allowing debug commands to be executed.
At the moment, kgdb on PowerPC is unable to properly adjust the symbol locations to match those of the loaded kernel, resulting in wrong symbol resolution.
While this is not fixed, a temporary workaround is to manually reload the symbols, specifying the actual load addresses of the sections.
Ex: `add-symbol-file kernel.debug <text_addr> -s .data <data_addr> ...`.