Commit c75617b9 authored by alex@thinkpad's avatar alex@thinkpad
Browse files

QEMU readme: example of identifying the location of an assertion using gdb and...

QEMU readme: example of identifying the location of an assertion using gdb and -d callstack; minor updates

--HG--
branch : qemu
parent 8fa259bce06e
......@@ -27,28 +27,16 @@ MMIO handlers: eos_handle_whatever (with io_log for debug messages).
Useful: eos_get_current_task_name/id/stack, eos_mem_read/write.
To extract MPU messages from a `startup log <http://builds.magiclantern.fm/jenkins/view/Experiments/job/startup-log/>`_,
use `extract_init_spells.py <https://bitbucket.org/hudson/magic-lantern/src/qemu/contrib/qemu/eos/mpu_spells/extract_init_spells.py>`_ (see `MPU communication`_).
To customize keys or add support for new buttons or GUI events,
edit `mpu.c <https://bitbucket.org/hudson/magic-lantern/src/qemu/contrib/qemu/eos/mpu.c>`_,
`button_codes.h <https://bitbucket.org/hudson/magic-lantern/src/qemu/contrib/qemu/eos/mpu_spells/button_codes.h>`_
and `extract_button_codes.py <https://bitbucket.org/hudson/magic-lantern/src/qemu/contrib/qemu/eos/mpu_spells/extract_button_codes.py>`_.
To extract MPU messages from a `startup log <http://builds.magiclantern.fm/jenkins/view/Experiments/job/startup-log/>`_,
use `extract_init_spells.py <https://bitbucket.org/hudson/magic-lantern/src/qemu/contrib/qemu/eos/mpu_spells/extract_init_spells.py>`_.
Known MPU messages and properties are exported to `known_spells.h <https://bitbucket.org/hudson/magic-lantern/src/qemu/contrib/qemu/eos/mpu_spells/known_spells.h>`_.
Image capture emulation
```````````````````````
WIP, still pretty rough.
To capture a full-res image (aka FRSP) using a CR2 as reference data for the virtual sensor:
.. code:: shell
make -C ../magic-lantern/minimal/qemu-frsp MODEL=5D3 CONFIG_QEMU=y clean install_qemu
env QEMU_EOS_VRAM_PH_QR_RAW='/path/to/IMG_1234.CR2' ./run_canon_fw.sh 5D3,firmware="boot=1"
Adding support for a new camera model
`````````````````````````````````````
......@@ -508,10 +496,14 @@ There are usually over 1000 different conditions that can trigger an assertion (
The `ERR70 description from Canon <http://cpn.canon-europe.com/content/education/infobank/camera_settings/eos_error_codes_and_messages.do>`_
("A malfunction with the images has been detected.") is overly simplistic.
-------------
**Do not attempt to fix a camera with ERR70 yourself!** Please contact us instead,
providing any relevant details (crash logs, what you did before the error and so on).
This section is for fixing assertions **in the emulation** (on a virtual machine), not on real cameras!
-------------
What we can do about them?
- figure out why they happen and fix the emulation
......@@ -519,8 +511,7 @@ What we can do about them?
Tip: find the assert stub, add assert_log to your debugmsg.gdb
and run the firmware under GDB with ``-d callstack``.
You'll get a stack trace to see what code called that assertion
(so you'll know where to look in the disassembly).
You'll get a stack trace to see what code called that assertion - example below.
Patching code
'''''''''''''
......@@ -537,7 +528,19 @@ That's why we prefer to patch the firmware from GDB scripts. These can be edited
and there is some additional burden for running a patched firmware (longer commands to type),
as a reminder that a proper fix is still wanted.
For example, patching the USleep waiting routine on 80D could look like this (``80D/patches.gdb``, commit `7ea57e7 <https://bitbucket.org/hudson/magic-lantern/commits/7ea57e73c09>`_):
Patching things may very well break other stuff down the road — use with care.
-------------
**Be very careful patching the assertions when running on a physical camera.
If an assert was reached, that usually means something already went terribly wrong —
hiding the error message from the user is *not* the way to solve it!**
-------------
Examples:
**Patching the UTimer waiting routine on 80D** (``80D/patches.gdb``, commit `7ea57e7 <https://bitbucket.org/hudson/magic-lantern/commits/7ea57e73c09#chg-contrib/qemu/scripts/80D/patches.gdb>`_):
.. code::
......@@ -553,11 +556,33 @@ See arm-mcr.h for a few useful instructions encodings, use an assembler or read
(in particular, `ARM Architecture Reference Manual <http://www.scss.tcd.ie/~waldroj/3d1/arm_arm.pdf>`_
and `Thumb-2 Supplement Reference Manual <http://read.pudn.com/downloads159/doc/709030/Thumb-2SupplementReferenceManual.pdf>`_).
Patching things may very well break other stuff down the road — use with care.
**Patching the EstimatedSize assertion on 80D** (``80D/patches.gdb``, commit `b6c5710 <https://bitbucket.org/hudson/magic-lantern/commits/b6c5710afebbffbb194f9102fbfa9798b99fde1b?at=qemu#chg-contrib/qemu/scripts/80D/patches.gdb>`_)
**Be very careful patching the assertions when running on a physical camera.
If an assert was reached, that usually means something already went terribly wrong —
hiding the error message from the user is *not* the way to solve it!**
After enabling the above UTimer patch, with the generic MPU messages you may get this error::
ASSERT : Resource/./EstimatedSize.c, Task = RscMgr, Line 1484
To find where it was triggered from, make sure you have the assert stub enabled in ``80D/debugmsg.gdb``::
b *0xFE547CD4
assert_log
then run the firmware under GDB, with ``-d callstack``:
.. code:: shell
(./run_canon_fw.sh 80D,firmware="boot=0" -d debugmsg,callstack -s -S & arm-none-eabi-gdb -x 80D/debugmsg.gdb) |& grep --text -C 5 ASSERT
...
0xFE19B1A9(0, 1, 51, 8000003b) at [RscMgr:fe19b287:2f4330] (pc:sp)
0xFE19B03B(2f4320, 1, 51, 8000003b) at [RscMgr:fe19b1af:2f4310] (pc:sp)
0xFE547CD5(fe19b104 "FALSE", fe19b0d0 "Resource/./EstimatedSize.c", 5cc, 8000003b)
at [RscMgr:fe19b14b:2f42f0] (pc:sp)
[ RscMgr:fe19b14b ] [ASSERT] FALSE at Resource/./EstimatedSize.c:1484, fe19b14f
...
The function you are looking for is ``0xFE19B03B`` (could have been any of the callers) and the assertion was triggered at ``0xfe19b14b``.
`Our patch <https://bitbucket.org/hudson/magic-lantern/commits/b6c5710afebbffbb194f9102fbfa9798b99fde1b?at=qemu#chg-contrib/qemu/scripts/80D/patches.gdb>`_
is at ``0xFE19B06A``, in the function identified with this method.
Incorrect firmware version?
'''''''''''''''''''''''''''
......@@ -603,8 +628,9 @@ GUI events (button codes) have ``class = 06``.
To log the MPU communication:
- dm-spy-experiments branch, CONFIG_DEBUG_INTERCEPT_STARTUP=y (mpu_send and mpu_recv stubs are enabled by default)
- in QEMU, enable mpu_send and mpu_recv in debugmsg.gdb and run the firmware under GDB
- `dm-spy-experiments <http://www.magiclantern.fm/forum/index.php?topic=2388.0>`_ branch, ``CONFIG_DEBUG_INTERCEPT_STARTUP=y`` (``mpu_send`` and ``mpu_recv`` stubs are enabled by default)
- `startup log <http://builds.magiclantern.fm/jenkins/view/Experiments/job/startup-log/>`_ builds (compiled with the above configuration)
- in QEMU, enable ``mpu_send`` and ``mpu_recv`` in ``debugmsg.gdb`` and run the firmware under GDB
- low-level: ``-d io,mpu``.
The first message is sent from the main CPU; upon receiving it, the MPU replies back:
......@@ -684,7 +710,7 @@ define `.serial_flash_size` in model_list.c and a few other parameters:
- chip select signal (CS): some GPIO register toggled before and after serial flash access
- SIO channel (used for SPI transfers)
- SFIO channel (for DMA transfers — Canon reused the same kind of DMA used for SD card).
- SFIO and SFDMA channels (for DMA transfers — Canon reused the same kind of DMA used for SD card).
Dumper: `sf_dump module <https://bitbucket.org/hudson/magic-lantern/src/unified/modules/sf_dump>`_.
......
......@@ -89,9 +89,9 @@ Common issues and workarounds
- closing QEMU window does not perform a clean shutdown
- ``Machine -> Power Down`` — see `Shutdown and reboot`_ for more info
- quicker: press ``C`` to "open" the card door => also clean shutdown.
- quicker: press ``C`` to `"open" the card door`__ => also clean shutdown.
|
__ `Opening the card door`_
- dm-spy-experiments: saving the log and anything executed afterwards may not work
......@@ -163,7 +163,7 @@ without additional gymnastics (you will **not** have to merge ``qemu`` into your
If your camera requires a serial flash, compile the
`sf_dump module <https://bitbucket.org/hudson/magic-lantern/src/unified/modules/sf_dump>`_
and run it on your camera to get this file.
|
4. Test your installation.
......@@ -245,14 +245,14 @@ Running Magic Lantern
---------------------
As you already know, Magic Lantern runs from the SD or CF card. For emulation,
we provide two card images (sd.img and cf.img) which you can mount on your operating system
we provide two card images (``sd.img`` and ``cf.img``) which you can mount on your operating system
and copy files on them. If these images use a FAT filesystem (they do, by default), we prefer
`mtools <https://www.gnu.org/software/mtools/>`_ for automated tasks
(such as copying files to/from the card images without mounting them).
To install Magic Lantern to the virtual card, you may:
- mount the card image (sd.img or cf.img) as /whatever/EOS_DIGITAL,
- mount the card image (``sd.img`` or ``cf.img``) as ``/whatever/EOS_DIGITAL``,
then run ``make install`` from your platform directory:
.. code:: shell
......@@ -458,7 +458,7 @@ Compare this to a camera model where only one firmware version is supported::
/path/to/qemu/60D/ROM1.BIN
/path/to/qemu/5D3/patches.gdb
Note: you may also store ``debugmsg.gdb`` and ``patches.gdb`` under the firmware version subdirectory if you prefer, but other QEMU-related scripts won't pick them up.
You may also store ``debugmsg.gdb`` and ``patches.gdb`` under the firmware version subdirectory if you prefer, but other QEMU-related scripts won't pick them up.
Creating custom SD/CF card images
`````````````````````````````````
......@@ -502,6 +502,19 @@ Be very careful not to give it write access to your physical hard-disk!!!**
Note: the ROM files will not be loaded from the SD/CF card.
Image capture emulation
```````````````````````
WIP, still pretty rough.
To capture a full-res image (aka FRSP) using a CR2 as reference data for the virtual sensor:
.. code:: shell
make -C ../magic-lantern/minimal/qemu-frsp MODEL=5D3 CONFIG_QEMU=y clean install_qemu
env QEMU_EOS_VRAM_PH_QR_RAW='/path/to/IMG_1234.CR2' ./run_canon_fw.sh 5D3,firmware="boot=1"
Automation
----------
......@@ -539,7 +552,9 @@ That means, during emulation you can interact with it using netcat:
You can redirect the monitor console to stdio with... ``-monitor stdio``.
If you have trouble with these ``nc`` commands, don't forget to check this common `netcat-issue`_.
If you have trouble running the above ``nc`` commands, don't forget to check this `common netcat issue`__.
__ `netcat-issue`_
Taking screenshots
``````````````````
......@@ -551,7 +566,7 @@ The easiest way is to use the ``screendump`` command from QEMU monitor:
echo "screendump snap.ppm" | nc -N -U qemu.monitor
In the following example, we'll redirect the monitor to stdio
and take a screenshot after 10 seconds.
and take a screenshot after 10 seconds:
.. code:: shell
......@@ -655,7 +670,7 @@ Internally, this is how the emulator is invoked:
This script is very customizable (see the source code for available options).
More examples:
**More examples:**
- `EOSM2 hello world <http://builds.magiclantern.fm/jenkins/view/QEMU/job/QEMU-EOSM2/18/console>`_
- running ML from the dm-spy-experiments branch in the emulator (`QEMU-dm-spy <http://builds.magiclantern.fm/jenkins/view/QEMU/job/QEMU-dm-spy/65/consoleFull>`_)
......@@ -733,8 +748,8 @@ This is tricky and not automated. You need to be careful with the following glob
- any temporary files you may want to use
Use something like ``mktemp`` rather than hardcoding a filename.
Or, try to achieve the same thing without a temporary file (pipes, process substitution).
Try to achieve the same thing without a temporary file (pipes, process substitution, command-line options).
If that doesn't work, consider using ``mktemp`` rather than hardcoding a filename.
- any other global resources (you'll have to figure them out on your own).
......@@ -905,7 +920,7 @@ in execution traces and other logs, you need to use ``-d nochain -singlestep``
(for example: ``-d exec,nochain -singlestep``) —
`source <http://qemu-discuss.nongnu.narkive.com/f8A4tqdT/singlestepping-target-assembly-instructions>`_.
Please note: ``-d io`` implies ``-d nochain -singlestep`` by default. Should you want to disable this,
Please note: ``-d io`` implies ``-d nochain -singlestep`` by default, to avoid this issue. Should you want to disable this,
to get faster emulation at the expense of incorrect PC values, use ``-d io_quick``.
Additionally, ``-d nochain`` implies ``-singlestep``, unlike in vanilla QEMU.
......@@ -927,7 +942,7 @@ how to call them and so on. At any code address from the disassembly, we may set
and print some more info (such as function name, arguments, register values,
call location, DryOS task name and so on).
Predefined logging hook example (this goes into CAM/debugmsg.gdb)::
Predefined logging hook example (this goes into ``CAM/debugmsg.gdb``)::
b *0x8580
take_semaphore_log
......@@ -951,11 +966,13 @@ You may also use `dprintf <https://sourceware.org/gdb/onlinedocs/gdb/Dynamic-Pri
dprintf *0x8b10, "[ %s:%08X ] task_create(%s, prio=%x, stack=%x, entry=%x, arg=%x)\n", CURRENT_TASK_NAME, $lr-4, $r0, $r1, $r2, $r3, *(int*)$sp
but the output won't be as pretty.
Debugging symbols
'''''''''''''''''
There are no debugging symbols in Canon firmware, but you can import
some of them from Magic Lantern. Typically, you want to use one of these
some of them from Magic Lantern (see comments in ``debugmsg.gdb``). Typically, you want to use one of these
`elf <https://jvns.ca/blog/2014/09/06/how-to-read-an-executable/>`_ files
from the platform directory:
......@@ -972,13 +989,15 @@ to set breakpoints on function names, you need this trick::
Printing call stack from GDB
''''''''''''''''''''''''''''
The call stack feature can be very useful to find where a function was called from.
This works even when gdb's ``backtrace`` command cannot figure it out from the stack contents,
but you need to run the emulation with instrumentation enabled: ``-d callstack`` or ``-d callstack,tail``:
The ``callstack`` option from QEMU (``eos/dbi/logging.c``) can be very useful to find where a function was called from.
This works even when gdb's ``backtrace`` command cannot figure it out from the stack contents, does not require any debugging symbols,
but you need to run the emulation with instrumentation enabled: ``-d callstack`` or ``-d callstack,tail``.
Then, in GDB, use ``print_current_location_with_callstack`` to see the call stack for the current DryOS task.
**Example for 80D**:
Tip: the callstack feature is enabled by default in ``assert_log``.
**Example for 80D:**
The following goes into ``80D/debugmsg.gdb`` (modify the existing entry):
......@@ -1015,13 +1034,15 @@ The above shows the callers for the function being analyzed,
with 4 arguments (no attempts are made to guess the actual number of arguments)
and the locations for each call. You may examine these addresses in your disassembler.
GDB scripting docs:
GDB scripting docs
''''''''''''''''''
- `Sequences <https://sourceware.org/gdb/onlinedocs/gdb/Sequences.html>`_ (command files, define, if, while, printf)
- `Convenience variables <https://sourceware.org/gdb/current/onlinedocs/gdb/Convenience-Vars.html>`_
- `GDB user manual <https://sourceware.org/gdb/current/onlinedocs/gdb/index.html>`_.
**More examples**:
More examples
'''''''''''''
- `750D serial flash dumper <http://www.magiclantern.fm/forum/index.php?topic=17627.msg195357#msg195357>`_ (figuring out the parameters of an unknown function)
- `EOS M2 <http://www.magiclantern.fm/forum/index.php?topic=15895.msg186173#msg186173>`_ (examples with various GDB GUI front-ends):
......@@ -1038,6 +1059,7 @@ Instrumentation
`TODO (see QEMU forum thread) <http://www.magiclantern.fm/forum/index.php?topic=2864.msg184125#msg184125>`_
Hacking
-------
......@@ -1051,7 +1073,7 @@ History
-------
:2008: `SD1100 boot (CHDK) <http://chdk.wikia.com/wiki/GPL_Qemu>`_
:2009: `5D2/7D boot (Trammell) <http://magiclantern.wikia.com/wiki/Emulation>`_
:2009: `5D2/7D boot (Trammell Hudson) <http://magiclantern.wikia.com/wiki/Emulation>`_
:2012: `TriX_EOS (g3gg0) <http://www.magiclantern.fm/forum/index.php?topic=2882.0>`_
:2013: `Initial Hello World <http://www.magiclantern.fm/forum/index.php?topic=2864.msg26022#msg26022>`_
:2013: `g3gg0 ports TriX changes to QEMU <http://www.magiclantern.fm/forum/index.php?topic=2864.msg29748#msg29748>`_
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment