Minoca OS features a rich kernel debugging and profiling experience that allows for deep insights into low level system operation. At a high level, the kernel debugger consists of a small amount of code baked into the kernel that can speak a simple binary protocol over a serial port. All Minoca OS images on the downloads page have debugging enabled by default, making debug setup quite simple: connect a serial cable from your device (the target) to your Windows development machine (the host), launch the Minoca Debugger on the Windows host, and then power on the target device you wish to debug. Connecting a serial cable is the tricky part; the ease of access to a serial port varies widely from platform to platform.
Connecting a Serial Cable
The more embedded and hacker friendly platforms expose direct access to serial ports (also known as UARTs). Minoca OS uses those ports whenever possible. For platforms that don't expose UARTs directly, Minoca OS is also capable of using an USB 2.0 controller to enumerate an FTDI USB-to-serial port.
Minoca OS currently only recognizes FTDI USB to serial ports (VID 0403, PID 6001) over EHCI USB host controllers. Because these FTDI devices are not high speed devices, you must have a USB hub plugged in between the machine and the FTDI port. The device must be plugged in when the system is booted. Other USB devices on that hub and other hubs are still usable.
The below image is an example of a USB-to-Serial debug setup on the Gizmo 2 platform. The blue USB-to-Serial cable is plugged into a USB hub attached to the Gizmo 2 and the null modem cable is attached to a Windows PC.
Low voltage UARTs
Some devices, like the Raspberry Pi and BeagleBone Black, expose the UART directly via pins. We've had some success ordering FTDI boards cheaply off of eBay (see http://www.ebay.com/sch/ftdi-serial-module). You may want to order a few, as quality may vary; we've had to touch up a couple of them with a soldering iron. They work well for communicating with other low voltage devices, but be aware these boards won't communicate with higher voltage RS-232 signaling (i.e. anything with an actual DB-9 connector). You'll also need some female-to-female jumpers to connect the boards together, also available on eBay or some place like Adafruit. Ignoring the green wires coming out of the left side of the board, the finished product should look something like this:
Launching the Minoca Debugger
You'll need to know which serial port to tell the debugger to connect to. On Windows, you can open up the Device Manager (Control Panel -> Device Manager) and expand the "Ports (COM & LPT)" to tell you the name of the serial port. Let's suppose your serial port is COM4.
Open up a Windows terminal (Start -> Accessories -> Command Prompt) and navigate to the directory where you've unpacked the Minoca Debugger archive. Prepare your command:
- The -s parameter points the debugger at the symbols for the image you'll be connecting to. Symbols allow the debugger to resolve an address like 0x8008125a into a function like MmAllocatePool. You need to specify the correct symbols for your platform's architecture (e.g. -s .\armv7 for the Raspberry Pi 2).
- The -e parameter loads the kernel debug extensions such as !thread and !object so you can explore certain kernel data structures easily.
- The -k parameter tells the debugger to connect to a kernel target, and where to find it. You may need to change COM4 to match your serial port.
- The -i parameter can be added to the end of the command line if you want an initial breakpoint when the target connects. This allows you to walk through early system initialization without having to try and break in as fast as you can.
Once you've got your command set and your target device ready to boot, execute the command. The Minoca Debugger will wait up to a minute for a target device to attempt a connection.
Booting the Target Device
Once the Minoca Debugger is launched on the host, you'll need to boot the target device. The steps to boot a device are platform specific. If you're not sure how to boot Minoca OS on your platform, the platform installation page will get you up and running.
Breaking into the Debugger
There are two ways to break into the debugger. The first is by using the -i parameter on the command line as mentioned above. The second, and more common, is to hit Control+B while running the debugger. The platform will freeze all cores, the debugger will load the current symbols, and the command area on the debugger will become enabled. Use the "help" command of the debugger to get a sense of the commands (or check out the Debugger Reference). Hit "g" (for "go") to allow the platform to continue execution.
If you close the debugger while it's connected, the target may not notice the host is gone. The next time it tries to communicate with the host, it may hang the machine for up to 10 seconds trying to connect. After that, it will assume the host has disconnected and continue. If you close the debugger while the target is broken in, it will stay broken in until you reconnect and hit "g" to let it go.
Platform Debug Notes
Below are some additional notes about setting up kernel debugging on each platform.
Raspberry Pi 1, 2 & 3
See the notes on low voltage UARTs above for grabbing a UART capable of communicating with these boards. You'll need to connect three pins: Ground, Transmit, and Receive. On all three Raspberry Pi platforms, pin 6 is ground, pin 8 is transmit, and pin 10 is receive. These three pins are sequential in the outer pin row, starting with the third pin from the corner of the board. And they are the same for both the 23 and 40 pin blocks available on the Raspberry Pi platforms. Remember that the Raspberry Pi's transmit line should go to the FTDI board's receive line, and vice versa. The perspective is always from the device being described. If done correctly, your setup should look like this:
Similar to the Raspberry Pi, the BeagleBone Black exposes low voltage UART pins directly. On the BeagleBone Black, the UART is exposed as a 6-pin male header near one of the main dual rows of female headers. pin 1 is ground, pin 4 is receive, and pin 5 is transmit. Pin 1 has a little white dot next to it. The correct setup should look like this:
If there is an exposed serial port on the machine, the kernel will use the first exposed COM port. Some motherboards expose 10-pin COM headers, which with a standard cable can expose a serial port on a PCI slot. These do count, and if there is one of these headers on your motherboard chances are Minoca OS will use it. Sometimes the serial port can be disabled in the BIOS if you do not want this behavior. Minoca uses the BIOS Data area at physical address 0x400 to determine whether such a serial port exists.
For machines without a serial port, including all modern laptops, USB serial debugging is the default choice. Minoca OS should find the USB to serial device plugged into any USB 2.0 port (black ports, not blue ports). Remember to place a hub between the PC and the USB to serial device.
Unfortunately the SoC UART pins are buried in an internal mezzanine connector. You'll need a special cable and Servo board from Google to access the serial port. The USB controllers on this SoC are also not EHCI. We currently do not have a great solution to suggest for kernel debugging on this Chromebook.
The headphone looking jack is the UART used for debugging and the symbols are located in the x86q directory of the Minoca Debugger package. If debugging is enabled, then the console gets bumped from that UART. You'll need to buy a Mini-PCIe serial port to enable both kernel debugging and the serial console simultaneously. We suggest using SSH to access the machine when kernel debugging is enabled.
Use a USB-to-serial device plugged into a black USB 2.0 port (via a hub).