avatartwo / avatar2

Python core of avatar²
Apache License 2.0
518 stars 98 forks source link

Stuck when openocd_target try to wait #112

Open LittleNewton opened 1 year ago

LittleNewton commented 1 year ago

I am trying to use the mucleo L512RE example to test/learn avatar2. When I was runing the avatar2-example, I find it will get stuck in nucleo.wait() function which can be seen here.

The code is here.

from os.path import abspath
from time import sleep

import os

from avatar2 import *

# set env var
os.environ['AVATAR2_QEMU_EXECUTABLE']="qemu-system-arm"

# Change to control whether the state transfer should be explicit or implicit
USE_ORCHESTRATION = 0

def obvious_print(s):
    print("=========" + s + "=========")

def main():

    # Configure the location of various files
    firmware = abspath('./firmware.bin')

    openocd_config = abspath('./nucleo-l152re.cfg')

    # Initiate the avatar-object
    avatar = Avatar(arch=ARM_CORTEX_M3, output_directory='/tmp/avatar')

    # Create the target-objects
    nucleo = avatar.add_target(OpenOCDTarget, openocd_script=openocd_config)

    qemu = avatar.add_target(QemuTarget, gdb_port=1236)

    # Define the various memory ranges and store references to them
    rom  = avatar.add_memory_range(0x08000000, 0x1000000, file=firmware)
    ram  = avatar.add_memory_range(0x20000000, 0x14000)
    mmio = avatar.add_memory_range(0x40000000, 0x1000000,
                                   forwarded=True, forwarded_to=nucleo)

    # Initialize the targets
    avatar.init_targets()
    obvious_print("Avatar Inited")

    if not USE_ORCHESTRATION:
        # This branch shows explicit state transferring using avatar

        # 1) Set the breakpoint on the physical device and execute up to there
        nucleo.set_breakpoint(0x8005104)
        nucleo.cont()
        nucleo.wait()

        # 2) Transfer the state from the physical device to the emulator
        obvious_print("Now the state is transfering")

        avatar.transfer_state(nucleo, qemu, synced_ranges=[ram])

        print("State transfer finished, emulator $pc is: 0x%x" % qemu.regs.pc)
    else:
        # This shows implicit state transferring using the orchestration plugin

        # 1) Load the plugin
        avatar.load_plugin('orchestrator')

        # 2) Specify the first target of the analysis
        avatar.start_target = nucleo

        # 3) Configure transitions
        #    Here, only one transition is defined. Note that 'stop=True' forces
        #    the orchestration to stop once the transition has occurred.
        avatar.add_transition(0x8005104, nucleo, qemu, synced_ranges=[ram], stop=True)

        # 4) Start the orchestration!
        obvious_print("Now we are trying to start orchestration")
        avatar.start_orchestration()
        obvious_print("Now start orchestration")

        print("State transfer finished, emulator $pc is: 0x%x" % qemu.regs.pc)

    # Continue execution in the emulator.
    # Due due to the forwarded mmio, output on the serial port of the physical
    # device (/dev/ttyACMx) can be observed, although solely the emulator
    # is executing.
    qemu.cont()

    # Further analysis could go here:
    # import IPython; IPython.embed()
    qemu.stop()
    obvious_print("Qemu Stoped")

    # Let this example run for a bit before shutting down avatar cleanly
    sleep(5)
    avatar.shutdown()

if __name__ == '__main__':
    main()
mariusmue commented 1 year ago

Hi there!

Did you: 1) Made sure that openocd can find the nucleo board (e.g., by running openocd -f [config-file] from your command line? 2) Flashed the right firmware to the board?

This example should work, but I won't have a chance to verify it before Wednesday.

LittleNewton commented 1 year ago

@mariusmue Thank you for your reply.

I mistakenly think this program will flash the firmware automatically. After flash the firmware firmware.bin, I can see it run:

image

I make sure that this board can be found by openocd.

# lsusb
Bus 002 Device 018: ID 0483:374b STMicroelectronics ST-LINK/V2.1

After flashing, this program can run!

# python3 nucleo_state_transfer.py nucleo_state_transfer.py | tee run.log
2022-09-18 17:50:44,723 | avatar.INFO | Initialized Avatar. Output directory is /tmp/avatar
2022-09-18 17:50:45,979 | avatar.targets.OpenOCDTarget0.INFO | State changed to TargetStates.STOPPED
2022-09-18 17:50:45,979 | avatar.INFO | Received state update of target OpenOCDTarget0 to TargetStates.STOPPED
2022-09-18 17:50:45,990 | avatar.targets.OpenOCDTarget0.INFO | Successfully connected to OpenOCD target!
2022-09-18 17:50:46,112 | avatar.targets.QemuTarget0.INFO | QEMU process running
2022-09-18 17:50:46,178 | avatar.targets.QemuTarget0.INFO | State changed to TargetStates.STOPPED
2022-09-18 17:50:46,178 | avatar.INFO | Received state update of target QemuTarget0 to TargetStates.STOPPED
2022-09-18 17:50:46,188 | avatar.targets.QemuTarget0.QMPProtocol.INFO | b'{"return": {}, "id": 0}\r\n'
2022-09-18 17:50:46,189 | avatar.targets.QemuTarget0.INFO | Connected to remote target
2022-09-18 17:50:46,189 | avatar.targets.QemuTarget0.RemoteMemoryProtocol.INFO | Successfully connected rmp
=========Avatar Inited=========
2022-09-18 17:50:46,215 | avatar.targets.OpenOCDTarget0.INFO | State changed to TargetStates.RUNNING
2022-09-18 17:50:46,215 | avatar.INFO | Received state update of target OpenOCDTarget0 to TargetStates.RUNNING
2022-09-18 17:50:46,586 | avatar.targets.OpenOCDTarget0.INFO | State changed to TargetStates.BREAKPOINT
2022-09-18 17:50:46,586 | avatar.INFO | Breakpoint hit for Target: OpenOCDTarget0
2022-09-18 17:50:46,586 | avatar.INFO | Received state update of target OpenOCDTarget0 to TargetStates.BREAKPOINT
2022-09-18 17:50:46,587 | avatar.targets.OpenOCDTarget0.INFO | State changed to TargetStates.STOPPED
2022-09-18 17:50:46,587 | avatar.INFO | Received state update of target OpenOCDTarget0 to TargetStates.STOPPED
=========Now the state is transfering=========
2022-09-18 17:50:52,196 | avatar.targets.QemuTarget0.RemoteMemoryProtocol.WARNING | Tried to close/unlink non existent rx_queue
2022-09-18 17:50:52,196 | avatar.targets.QemuTarget0.RemoteMemoryProtocol.WARNING | Tried to close/unlink non existent tx_queue

However, I didn't get the ideal output, such as State transfer finished, emulator $pc is: 0x%x