docs/develop: Import oco's article on profiling applications
- Create a new "debugging" section and move two other articles there as well
This commit is contained in:
@@ -1,137 +0,0 @@
|
||||
Bootloader debugging with GEF
|
||||
=============================
|
||||
|
||||
When Haiku’s early boot process is experiencing unknown crashes or
|
||||
faults, it can be extremely difficult to troubleshoot (especially when
|
||||
serial, video, or other i/o devices are non-functional)
|
||||
|
||||
It **is** possible to step through the boot of any architecture of Haiku
|
||||
in a debugger if the system boots and the issue can be reproduced in
|
||||
qemu.
|
||||
|
||||
This works for any architecture and is *extremely* helpful to trouble
|
||||
early platforms. Linux or Mac OS are requirements. You need a full
|
||||
POSIX environment.
|
||||
|
||||
Building Haiku
|
||||
--------------
|
||||
|
||||
On most non-x86 platforms, you will need a “kernel” (haiku_loader) and
|
||||
an “initrd” (haiku_floppyboot).
|
||||
|
||||
For arm/arm64: ``jam -q @minimum-mmc``
|
||||
|
||||
Launching Haiku in QEMU
|
||||
-----------------------
|
||||
|
||||
In the example below, we will prepare Haiku arm in QEMU for debugging.
|
||||
|
||||
::
|
||||
|
||||
qemu-system-arm -M raspi2 -kernel haiku_loader.u-boot -initrd haiku-floppyboot.tgz.u-boot -serial stdio -m 2G -dtb rpi2.dtb -s -S
|
||||
|
||||
**Key Flags:**
|
||||
|
||||
- **-s**
|
||||
|
||||
- Shorthand for -gdb tcp::1234, i.e. open a gdbserver on TCP port
|
||||
1234.
|
||||
|
||||
- **-S**
|
||||
|
||||
- Do not start CPU at startup (you must type ‘c’ in the monitor).
|
||||
|
||||
These simple flags will make qemu listen for a debugger connection on
|
||||
localhost:1234 and have the VM not start until you tell it to.
|
||||
|
||||
In the example above, we are Emulating a Raspberry Pi 2, and using
|
||||
our Raspberry Pi 2 dtb. If you don’t have a dtb for the machine
|
||||
you’re emulating, you can dump qemu’s internal dtb by adding
|
||||
``-M dumpdtb=myboard.dtb`` to the end of your qemu command.
|
||||
|
||||
Attaching GEF
|
||||
-------------
|
||||
|
||||
`GEF <https://github.com/hugsy/gef>`__ is an enhanced debugger which
|
||||
works extremely well for debugging code running in virtual machines. It
|
||||
piggy-backs on gdb and offers a lot of valueable insight at a glance
|
||||
without requiring to know every gdb command.
|
||||
|
||||
Once GEF is installed, we can step through the process to attach gdb to
|
||||
qemu.
|
||||
|
||||
Open gdb with our symbols.
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
First we run gdb pointed at our boot loader. We use the native ELF
|
||||
binary as that seems to give gdb/gef the most accurate knowledge of our
|
||||
symbols. (the haiku_loader.u-boot is wrapped by u-boot’s mkimage, your
|
||||
milage may vary based on platform)
|
||||
|
||||
``gdb objects/haiku/arm/release/system/boot/u-boot/boot_loader_u-boot``
|
||||
|
||||
Set the architecture
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
This may not be required, but re-enforces to gef/gdb that we’re working
|
||||
on arm.
|
||||
|
||||
``set architecture arm``
|
||||
|
||||
Connect to QEMU
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
Now we tell gdb/gef about out running (but paused) QEMU instance.
|
||||
|
||||
``gef-remote -q localhost:1234``
|
||||
|
||||
A successful connection should occur.
|
||||
|
||||
Step into debugging
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Before you begin execution, it’s handy to set a *breakpoint*. A
|
||||
*breakpoint* tells gdb/gef where it should pause execution to begin the
|
||||
debugging process. All of our bootloaders start in a ``start_gen``
|
||||
function, so this is a good place to start.
|
||||
|
||||
``breakpoint start_gen``
|
||||
|
||||
Now that a breakpoint is defined, lets run the virtual machine.
|
||||
|
||||
In gef, type ``continue``.
|
||||
|
||||
If everything is working as expected, you should now be “paused” at the
|
||||
``start_gen`` function (hopefully showing the C/C++ code).
|
||||
|
||||
Now, you have a few commands to leverage:
|
||||
|
||||
- **step**
|
||||
|
||||
- Take a single step forward and execute the code listed.
|
||||
- Does **not** step “into” functions, just over them getting the
|
||||
return from the code.
|
||||
- Alias: s
|
||||
|
||||
- **stepi**
|
||||
|
||||
- step forward “into” the next code.
|
||||
- If you’re on a function it will enter the function and show the
|
||||
code executed.
|
||||
|
||||
- **break**
|
||||
|
||||
- add additional “breakpoints” where you can step through the code
|
||||
execution.
|
||||
|
||||
- **continue**
|
||||
|
||||
- Resume execution.
|
||||
- If you have no additional breakpoints the code will “go do what
|
||||
it’s supposed to”
|
||||
- Alias: c
|
||||
|
||||
- **next**
|
||||
|
||||
- Resume execution until it reaches the next line of code.
|
||||
- Useful for example to run until a loop is completed, and stop at the first line after that loop.
|
||||
@@ -10,5 +10,3 @@ Kernel
|
||||
/kernel/vm/swap_file_support
|
||||
/kernel/arch/index
|
||||
/kernel/boot/boot_process_specs.rst
|
||||
/kernel/boot/Debugging_Bootloaders_GEF
|
||||
/kernel/pci_serial_debug
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
Using PCI serial ports for debugging
|
||||
====================================
|
||||
|
||||
Modern systems usually don't come with a built-in serial port anymore. This
|
||||
is unconvenient for low level debugging, since the serial port allows access
|
||||
to early boot log as well as kernel debugger, even when the display or keyboard
|
||||
are not working.
|
||||
|
||||
It is fortunately possible to add a serial port over the PCI bus on machines
|
||||
which have appropriate expansion ports. This can be done using expresscard,
|
||||
mini-PCI, or PCI express ports.
|
||||
|
||||
Devices known to work
|
||||
---------------------
|
||||
|
||||
Dexlan XMT01A (https://www.accessoires-informatiques.com/Prix/EXPRESSCARD-PCIE-POUR-PORTABLE-23842.html)
|
||||
Uses MOSCHIP 9922 controller
|
||||
|
||||
Devices to be tested
|
||||
--------------------
|
||||
|
||||
https://smile.amazon.com/Industrial-Desktop-Bracket-Moschip-MCS9922/dp/B003D3MFHM/
|
||||
|
||||
Configuring
|
||||
-----------
|
||||
|
||||
- Install the card in your computer
|
||||
- Boot Haiku and look in the syslog for the PCI bus scan for the device:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
KERN: PCI: [dom 0, bus 5] bus 5, device 0, function 0: vendor 9710, device 9922, revision 00
|
||||
KERN: PCI: class_base 07, class_function 00, class_api 02
|
||||
KERN: PCI: vendor 9710: MosChip Semiconductor Technology Ltd.
|
||||
KERN: PCI: device 9922: MCS9922 PCIe Multi-I/O Controller
|
||||
KERN: PCI: info: Communication controller (Serial controller, 16550)
|
||||
KERN: PCI: line_size 10, latency 00, header_type 80, BIST 00
|
||||
KERN: PCI: ROM base host 00000000, pci 00000000, size 00000000
|
||||
KERN: PCI: cardbus_CIS 00000000, subsystem_id 1000, subsystem_vendor_id a000
|
||||
KERN: PCI: interrupt_line 0b, interrupt_pin 01, min_grant 00, max_latency 00
|
||||
KERN: PCI: base reg 0: host 00004000, pci 0000KERN: 4000, size 00000008, flags 01
|
||||
KERN: PCI: base reg 1: host f1c01000, pci f1c01000, size 00001000, flags 00
|
||||
KERN: PCI: base reg 2: host 00000000, pci 00000000, size 00000000, flags 00
|
||||
KERN: PCI: base reg 3: host 00000000, pci 00000000, size 00000000, flags 00
|
||||
KERN: PCI: base reg 4: host 00000000, pci 00000000, size 00000000, flags 00
|
||||
KERN: PCI: base reg 5: host f1c00000, pci f1c00000, size 00001000, flags 00
|
||||
KERN: PCI: Capabilities: MSI, PM, PCIe
|
||||
KERN: PCI: Extended capabilities: Virtual Channel, Advanced Error Reporting
|
||||
|
||||
|
||||
Write down the address of "base reg 0", this is where the serial port registers
|
||||
are mapped (it is probably possible to get this information from lspci on Linux
|
||||
as well?)
|
||||
|
||||
Configure serial debug in config/settings/kernel/drivers/kernel:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
serial_debug_output true
|
||||
serial_debug_speed 115200
|
||||
serial_debug_port 0x4000
|
||||
|
||||
Now your kernel is configured to send its output to the serial port. You can
|
||||
connect another machine to it (using an USB to serial adapter and a NULL modem
|
||||
cable, for example) and use SerialConnect or a similar tool to see the output
|
||||
and access the KDL prompt.
|
||||
|
||||
Happy debugging!
|
||||
Reference in New Issue
Block a user