diff --git a/CHANGES.rst b/CHANGES.rst index d068962c8..c5071e0a7 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -48,6 +48,13 @@ New Features in 26.0 - Labgrid has gained support for network namespace forwarding from exporters to clients. This allows accessing a network as if it is locally connected. - HTTPVideoDrivers now optionally allow the specification of a port. +- The new `RKBootstrapDriver` uploads a combined barebox image into a Rockchip + SoC in MaskROM mode using barebox's ``rk-usb-loader`` tool, loading it into + RAM and executing it. In contrast, the existing `RKUSBDriver` uses + ``rkdeveloptool`` to write a bootloader to the target's storage. The + ``rkdeveloptool`` binary is now configured under the ``rkdeveloptool`` tools + key; the previously used ``rk-usb-loader`` key is deprecated but still honored + for backward compatibility. Breaking changes in 26.0 ~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/doc/configuration.rst b/doc/configuration.rst index cb7e4c520..cd753331b 100644 --- a/doc/configuration.rst +++ b/doc/configuration.rst @@ -818,6 +818,7 @@ Arguments: Used by: - `RKUSBDriver`_ + - `RKBootstrapDriver`_ NetworkMXSUSBLoader ~~~~~~~~~~~~~~~~~~~ @@ -2856,9 +2857,14 @@ Arguments: RKUSBDriver ~~~~~~~~~~~ -An :any:`RKUSBDriver` is used to upload an image into a device in the *Rockchip -USB loader state*. -This is useful to bootstrap a bootloader onto a device. +An :any:`RKUSBDriver` is used to write a bootloader onto a device in the +*Rockchip USB loader state* using the ``rkdeveloptool`` tool. +It runs ``rkdeveloptool db`` to load a first-stage bootloader into RAM, +followed by ``rkdeveloptool wl`` to write the bootloader image to the target's +storage (e.g. eMMC/SD). + +To load and execute a barebox image directly in RAM instead, use the +`RKBootstrapDriver`_. Binds to: loader: @@ -2883,9 +2889,46 @@ Implements: Arguments: - image (str): optional, key in :ref:`images ` containing the path - of an image to bootstrap onto the target + of an image to write to the target's storage - usb_loader (str): optional, key in :ref:`images ` containing the path - of a first-stage bootloader image to write + of a first-stage bootloader image to load into RAM + +.. note:: + The ``rkdeveloptool`` binary is configured under the ``rkdeveloptool`` tools + key. For backward compatibility, the previously used (and misnamed) + ``rk-usb-loader`` tools key is still honored if ``rkdeveloptool`` is not set, + but its use is deprecated. + +RKBootstrapDriver +~~~~~~~~~~~~~~~~~ +An :any:`RKBootstrapDriver` is used to upload a combined barebox image into a +device in the *Rockchip USB loader state* (MaskROM mode) using barebox's +``rk-usb-loader`` tool. +In contrast to the `RKUSBDriver`_, it loads the image into RAM and executes it, +i.e. it performs a true bootstrap and does not modify the target's storage. + +Binds to: + loader: + - `RKUSBLoader`_ + - `NetworkRKUSBLoader`_ + +Implements: + - :any:`BootstrapProtocol` + +.. code-block:: yaml + + targets: + main: + drivers: + RKBootstrapDriver: + image: 'mybootloaderkey' + + images: + mybootloaderkey: 'path/to/barebox.img' + +Arguments: + - image (str): optional, key in :ref:`images ` containing the path + of a combined barebox image to load into RAM and execute UUUDriver ~~~~~~~~~ diff --git a/doc/man/device-config.rst b/doc/man/device-config.rst index d0e5ff914..8338fb122 100644 --- a/doc/man/device-config.rst +++ b/doc/man/device-config.rst @@ -115,9 +115,16 @@ TOOLS KEYS See: https://www.intel.com/content/www/us/en/docs/programmable/683039/22-3/hps-flash-programmer.html ``rk-usb-loader`` - Path to the rk-usb-loader binary, used by the RKUSBDriver. + Path to the rk-usb-loader binary, used by the RKBootstrapDriver to load a + barebox image into RAM and execute it. See: https://git.pengutronix.de/cgit/barebox/tree/scripts/rk-usb-loader.c +``rkdeveloptool`` + Path to the rkdeveloptool binary, used by the RKUSBDriver. The driver + invokes it with rkdeveloptool's ``db`` and ``wl`` subcommands to write a + bootloader to the target's storage. + See: https://github.com/rockchip-linux/rkdeveloptool + ``rsync`` Path to the rsync binary, used by the SSHDriver. See: https://github.com/rsyncproject/rsync diff --git a/labgrid/driver/__init__.py b/labgrid/driver/__init__.py index d3cd6f55e..d453dedb2 100644 --- a/labgrid/driver/__init__.py +++ b/labgrid/driver/__init__.py @@ -16,7 +16,7 @@ DigitalOutputPowerDriver, YKUSHPowerDriver, \ USBPowerDriver, SiSPMPowerDriver, NetworkPowerDriver, \ PDUDaemonDriver -from .usbloader import MXSUSBDriver, IMXUSBDriver, BDIMXUSBDriver, RKUSBDriver, UUUDriver +from .usbloader import MXSUSBDriver, IMXUSBDriver, BDIMXUSBDriver, RKUSBDriver, RKBootstrapDriver, UUUDriver from .usbsdmuxdriver import USBSDMuxDriver from .usbsdwiredriver import USBSDWireDriver from .usbsdwire3driver import USBSDWire3Driver diff --git a/labgrid/driver/dfudriver.py b/labgrid/driver/dfudriver.py index 7aa1e9fc6..00d0aea48 100644 --- a/labgrid/driver/dfudriver.py +++ b/labgrid/driver/dfudriver.py @@ -16,11 +16,7 @@ class DFUDriver(Driver): def __attrs_post_init__(self): super().__attrs_post_init__() - # FIXME make sure we always have an environment or config - if self.target.env: - self.tool = self.target.env.config.get_tool("dfu-util") - else: - self.tool = "dfu-util" + self.tool = self.target.get_tool("dfu-util") def _get_dfu_prefix(self): return self.dfu.command_prefix + [ diff --git a/labgrid/driver/fastbootdriver.py b/labgrid/driver/fastbootdriver.py index c1949ca14..4e6be269a 100644 --- a/labgrid/driver/fastbootdriver.py +++ b/labgrid/driver/fastbootdriver.py @@ -34,11 +34,7 @@ class AndroidFastbootDriver(Driver): def __attrs_post_init__(self): super().__attrs_post_init__() - # FIXME make sure we always have an environment or config - if self.target.env: - self.tool = self.target.env.config.get_tool('fastboot') - else: - self.tool = 'fastboot' + self.tool = self.target.get_tool('fastboot') def _get_fastboot_prefix(self): if isinstance(self.fastboot, (AndroidUSBFastboot, RemoteAndroidUSBFastboot)): diff --git a/labgrid/driver/openocddriver.py b/labgrid/driver/openocddriver.py index 02440f4cf..1f9f3a61f 100644 --- a/labgrid/driver/openocddriver.py +++ b/labgrid/driver/openocddriver.py @@ -35,13 +35,11 @@ class OpenOCDDriver(Driver, BootstrapProtocol): def __attrs_post_init__(self): super().__attrs_post_init__() - # FIXME make sure we always have an environment or config + self.tool = self.target.get_tool("openocd") if self.target.env: - self.tool = self.target.env.config.get_tool("openocd") self.config = self.target.env.config.resolve_path_str_or_list(self.config) self.search = self.target.env.config.resolve_path_str_or_list(self.search) else: - self.tool = "openocd" if isinstance(self.config, str): self.config = [self.config] if isinstance(self.search, str): diff --git a/labgrid/driver/quartushpsdriver.py b/labgrid/driver/quartushpsdriver.py index 531adb25d..9f9a5b182 100644 --- a/labgrid/driver/quartushpsdriver.py +++ b/labgrid/driver/quartushpsdriver.py @@ -25,13 +25,8 @@ class QuartusHPSDriver(Driver): def __attrs_post_init__(self): super().__attrs_post_init__() - # FIXME make sure we always have an environment or config - if self.target.env: - self.tool = self.target.env.config.get_tool("quartus_hps") - self.jtag_tool = self.target.env.config.get_tool("jtagconfig") - else: - self.tool = "quartus_hps" - self.jtag_tool = "jtagconfig" + self.tool = self.target.get_tool("quartus_hps") + self.jtag_tool = self.target.get_tool("jtagconfig") def _get_cable_number(self): """ diff --git a/labgrid/driver/sigrokdriver.py b/labgrid/driver/sigrokdriver.py index 1e8e1ad9b..1fb72e88b 100644 --- a/labgrid/driver/sigrokdriver.py +++ b/labgrid/driver/sigrokdriver.py @@ -28,13 +28,7 @@ class SigrokCommon(Driver): def __attrs_post_init__(self): super().__attrs_post_init__() - # FIXME make sure we always have an environment or config - if self.target.env: - self.tool = self.target.env.config.get_tool( - 'sigrok-cli' - ) or 'sigrok-cli' - else: - self.tool = 'sigrok-cli' + self.tool = self.target.get_tool('sigrok-cli') or 'sigrok-cli' self._running = False def _create_tmpdir(self): diff --git a/labgrid/driver/usbloader.py b/labgrid/driver/usbloader.py index 5f4f90762..d3e6fa550 100644 --- a/labgrid/driver/usbloader.py +++ b/labgrid/driver/usbloader.py @@ -1,4 +1,5 @@ import subprocess +import warnings import attr from ..factory import target_factory @@ -21,11 +22,7 @@ class MXSUSBDriver(Driver, BootstrapProtocol): def __attrs_post_init__(self): super().__attrs_post_init__() - # FIXME make sure we always have an environment or config - if self.target.env: - self.tool = self.target.env.config.get_tool('mxs-usb-loader') - else: - self.tool = 'mxs-usb-loader' + self.tool = self.target.get_tool('mxs-usb-loader') def on_activate(self): pass @@ -59,11 +56,7 @@ class IMXUSBDriver(Driver, BootstrapProtocol): def __attrs_post_init__(self): super().__attrs_post_init__() - # FIXME make sure we always have an environment or config - if self.target.env: - self.tool = self.target.env.config.get_tool('imx-usb-loader') - else: - self.tool = 'imx-usb-loader' + self.tool = self.target.get_tool('imx-usb-loader') def on_activate(self): pass @@ -102,11 +95,21 @@ class RKUSBDriver(Driver, BootstrapProtocol): def __attrs_post_init__(self): super().__attrs_post_init__() - # FIXME make sure we always have an environment or config + tools = {} if self.target.env: - self.tool = self.target.env.config.get_tool('rk-usb-loader') + tools = self.target.env.config.data.get('tools') or {} + if 'rkdeveloptool' not in tools and 'rk-usb-loader' in tools: + # Backward compatibility: the rkdeveloptool binary used to be + # configured under the (misnamed) 'rk-usb-loader' tools key, which + # is now used by the RKBootstrapDriver instead. + warnings.warn( + "Configuring rkdeveloptool under the 'rk-usb-loader' tools key is " + "deprecated, use the 'rkdeveloptool' key instead", + DeprecationWarning, + ) + self.tool = self.target.get_tool('rk-usb-loader') else: - self.tool = 'rk-usb-loader' + self.tool = self.target.get_tool('rkdeveloptool') def on_activate(self): pass @@ -154,6 +157,54 @@ def load(self, filename=None): raise +@target_factory.reg_driver +@attr.s(eq=False) +class RKBootstrapDriver(Driver, BootstrapProtocol): + """The RKBootstrapDriver uploads a combined barebox image into a Rockchip + SoC in MaskROM mode using barebox's ``rk-usb-loader`` tool. + + In contrast to the :any:`RKUSBDriver` (which uses rkdeveloptool's ``db`` and + ``wl`` commands to flash a bootloader to storage), this driver loads the + image into RAM and executes it, i.e. it performs a true bootstrap. + """ + bindings = { + "loader": {"RKUSBLoader", "NetworkRKUSBLoader"}, + } + + image = attr.ib(default=None) + + def __attrs_post_init__(self): + super().__attrs_post_init__() + self.tool = self.target.get_tool('rk-usb-loader') + + def on_activate(self): + pass + + def on_deactivate(self): + pass + + @Driver.check_active + @step(args=['filename']) + def load(self, filename=None): + if filename is None and self.image is not None: + filename = self.target.env.config.get_image_path(self.image) + mf = ManagedFile(filename, self.loader) + mf.sync_to_resource() + + timeout = Timeout(3.0) + while True: + try: + processwrapper.check_output( + self.loader.command_prefix + + [self.tool, mf.get_remote_path()], + print_on_silent_log=True + ) + break + except subprocess.CalledProcessError: + if timeout.expired: + raise + + @target_factory.reg_driver @attr.s(eq=False) class UUUDriver(Driver, BootstrapProtocol): @@ -166,11 +217,7 @@ class UUUDriver(Driver, BootstrapProtocol): def __attrs_post_init__(self): super().__attrs_post_init__() - # FIXME make sure we always have an environment or config - if self.target.env: - self.tool = self.target.env.config.get_tool('uuu-loader') - else: - self.tool = 'uuu-loader' + self.tool = self.target.get_tool('uuu-loader') def on_activate(self): pass @@ -211,11 +258,7 @@ class BDIMXUSBDriver(Driver, BootstrapProtocol): def __attrs_post_init__(self): super().__attrs_post_init__() - # FIXME make sure we always have an environment or config - if self.target.env: - self.tool = self.target.env.config.get_tool('imx_usb') - else: - self.tool = 'imx_usb' + self.tool = self.target.get_tool('imx_usb') def on_activate(self): pass diff --git a/labgrid/target.py b/labgrid/target.py index a5fee74d6..16f6d0c9c 100644 --- a/labgrid/target.py +++ b/labgrid/target.py @@ -41,6 +41,16 @@ def interact(self, msg): else: input(msg) + def get_tool(self, tool): + """Return the path configured for ``tool`` in the environment. + + Falls back to the bare tool name if the target has no environment (and + thus no configuration), so it can still be resolved via ``$PATH``. + """ + if self.env: + return self.env.config.get_tool(tool) + return tool + def update_resources(self): """ Iterate over this target's resources, deactivate any active but diff --git a/man/labgrid-device-config.5 b/man/labgrid-device-config.5 index 0755927de..5ff263efe 100644 --- a/man/labgrid-device-config.5 +++ b/man/labgrid-device-config.5 @@ -130,9 +130,16 @@ Path to the quartus_hps binary, used by the QuartusHPSDriver. See: \X'tty: link https://www.intel.com/content/www/us/en/docs/programmable/683039/22-3/hps-flash-programmer.html'\fI\%https://www.intel.com/content/www/us/en/docs/programmable/683039/22\-3/hps\-flash\-programmer.html\fP\X'tty: link' .TP .B \fBrk\-usb\-loader\fP -Path to the rk\-usb\-loader binary, used by the RKUSBDriver. +Path to the rk\-usb\-loader binary, used by the RKBootstrapDriver to load a +barebox image into RAM and execute it. See: \X'tty: link https://git.pengutronix.de/cgit/barebox/tree/scripts/rk-usb-loader.c'\fI\%https://git.pengutronix.de/cgit/barebox/tree/scripts/rk\-usb\-loader.c\fP\X'tty: link' .TP +.B \fBrkdeveloptool\fP +Path to the rkdeveloptool binary, used by the RKUSBDriver. The driver +invokes it with rkdeveloptool\(aqs \fBdb\fP and \fBwl\fP subcommands to write a +bootloader to the target\(aqs storage. +See: \X'tty: link https://github.com/rockchip-linux/rkdeveloptool'\fI\%https://github.com/rockchip\-linux/rkdeveloptool\fP\X'tty: link' +.TP .B \fBrsync\fP Path to the rsync binary, used by the SSHDriver. See: \X'tty: link https://github.com/rsyncproject/rsync'\fI\%https://github.com/rsyncproject/rsync\fP\X'tty: link'