Add FWU documentation

Adds documentation to describe FWU support. Gives an overall
design description and explains the platform configuration
model.

Signed-off-by: Julian Hall <julian.hall@arm.com>
Change-Id: Ib7b362ec645c7afca198f4b5138a249c17bc5056
diff --git a/docs/services/fwu-service-description.rst b/docs/services/fwu-service-description.rst
new file mode 100644
index 0000000..4fa68eb
--- /dev/null
+++ b/docs/services/fwu-service-description.rst
@@ -0,0 +1,565 @@
+Firmware Update Service
+=======================
+Overview
+--------
+The ability to update device firmware and related resources is a key requirement for
+maintaining security over a device's lifetime. Keeping firmware up-to-date with security
+fixes and feature enhancements is important for defending against emerging threats.
+Because firmware forms the security foundation of a device, it is important to apply
+updates in a timely manner to minimize risks exposed by firmware vulnerabilities. Any
+remote firmware update mechanism carries a risk of failure. As firmware is critical to
+the operation of a device, failures during the update process that lead to corrupted
+firmware have the potential to be highly disruptive. Any update mechanism intended
+for use with a large population of devices must offer robustness guarantees sufficient
+to keep the risk of failure at an acceptable level.
+
+Firmware update support within the Trusted Services project consists of a set of reusable
+firmware components that can be deployed within different execution environments to enable
+platform integrators to create firmware update solutions, tailored for their platform.
+The components are intended to be integrated into platform firmware and will be used in
+conjunction with a third-party update client, such as mender, swupd or fwupd, to create
+an end-to-end solution. The features supported aim to meet requirements for robustness
+and security. These include:
+
+  - Banked A/B robust update support
+  - Transactional multi-component updates with ACID (Atomicity, Consistency, Isolation,
+    Durability) guarantees
+  - Partial updates where not all components are updated
+  - Trial of an update with bootloader or client initiated rollback
+  - Anti-rollback counter management
+  - Standardized signaling to bootloader via the FWU Metadata structure
+  - Flexible installer framework to support different image types
+  - Image directory for advertising updatable components
+  - Compatible with UEFI FMP capsule update model and ESRT
+
+To support test and development and to provide a useful reference, the Trusted Services
+project maintains a reference integration with the following characteristics:
+
+  - Dual flash system where firmware is loaded from a dedicated secure world flash device.
+  - Secure flash is formatted with UEFI MBR/GPT with separate partitions for FWU metadata
+    and firmware banks.
+  - TF-A is used as the bootloader with separate firmware components packaged in a FIP
+    image.
+  - The Update Agent runs within a secure partition and exposes an FF-A based ABI that
+    conforms to the Arm FWU-A specification.
+  - Test and development on FVP or QEMU platforms.
+
+Source Code Location
+--------------------
+Within the Trusted Services project, source code related to FWU can be found under the
+following subdirectories (relative to the project root).
+
+.. list-table::
+  :header-rows: 1
+
+  * - Directory
+    - Contains
+  * - components/service/fwu
+    - Service components for implementing the FWU service provider.
+  * - protocols/service/fwu
+    - Public service access protocol (ABI) definition.
+  * - media/volume
+    - Storage volume access.
+
+Testing is covered in more detail in a later section. However, if you want a simple way
+of building and testing FWU components, the component-test deployment may be built for a
+native PC environment. The built executable includes an extensive set of FWU related tests
+that exercise the core Update Agent in various configurations. To build and run these tests
+on a Linux PC, use the following (from TS root directory)::
+
+  cd deployments/component-test/linux-pc
+  cmake -B build
+  cd build
+  make
+  ./component-test -v -g Fwu
+
+  Output will look like this:
+  TEST(FwuCopyInstallerTests, installAndCopy) - 1 ms
+  TEST(FwuRawInstallerTests, normalInstallFlow) - 1 ms
+  TEST(FwuMetadataManagerTests, checkAndRepairInaccessibleStorage) - 0 ms
+  TEST(FwuMetadataManagerTests, checkAndRepairAccessibleStorage) - 1 ms
+  TEST(FwuRollbackTests, bootloaderFallback) - 0 ms
+  TEST(FwuRollbackTests, selectPreviousAfterActivation) - 0 ms
+  TEST(FwuRollbackTests, selectPreviousPriorToActivation) - 0 ms
+  TEST(FwuPowerFailureTests, powerFailureDuringTrial) - 0 ms
+  TEST(FwuPowerFailureTests, powerFailureDuringStaging) - 0 ms
+  TEST(FwuUpdateScenarioTests, partialFirmwareUpdateFlow) - 0 ms
+  TEST(FwuUpdateScenarioTests, wholeFirmwareUpdateFlow) - 0 ms
+  TEST(FwuInvalidBehaviourTests, invalidOperationsInTrial) - 0 ms
+  TEST(FwuInvalidBehaviourTests, invalidOperationsInStaging) - 0 ms
+  TEST(FwuInvalidBehaviourTests, invalidOperationsInRegular) - 0 ms
+  TEST(FwuImageDirectoryTests, zeroFwLocations) - 0 ms
+  TEST(FwuImageDirectoryTests, multipleFwLocations) - 0 ms
+  TEST(FwuImageDirectoryTests, singleFwLocation) - 1 ms
+  TEST(FwuImageDirectoryTests, streamRecycling) - 0 ms
+  TEST(FwuImageDirectoryTests, streamedReads) - 0 ms
+
+  OK (234 tests, 19 ran, 3452 checks, 0 ignored, 215 filtered out, 5 ms)
+
+Concepts and Assumptions
+------------------------
+Before describing details of the design, some important concepts and assumptions are
+introduced in this section.
+
+Update Packaging
+''''''''''''''''
+A set of firmware images that forms an update will be packaged in some way to enable
+it to be delivered to a device for installation. No particular packaging method is assumed
+by the FWU Update Agent. Any unpacking will be performed before individual images are
+presented to the FWU service for installation. The only assumption that the Update Agent
+relies on is that each image is identified by an image type UUID/GUID. The UEFI specification
+defines the FMP Capsule format that acts as a container for a set of arbitrary images. The
+reference integration maintained by the Trusted Services project uses UEFI FMP capsules
+but the FWU service can be used with any packaging method.
+
+Transactional Updates
+'''''''''''''''''''''
+A firmware update package may contain multiple images that all need to be installed as a
+set in order to successfully update a device's firmware. To avoid the hazard of booting
+a device using partially installed firmware, the FWU-A specification supports transactional
+updates where as set of separate image install operations are grouped together to form a
+single update transaction. The FWU-A specification defines a behavioral model where images
+are installed during the STAGING state.  Entry to the STAGING state is triggered by the
+client making the fwu_begin_staging ABI call. This is followed a set of one or more install
+operations where images are written to the Update Agent. After committing the final image
+in the set, the client marks the end of the transaction by calling fwu_end_staging.
+
+Banked Firmware Store
+'''''''''''''''''''''
+To offer the guarantee that device firmware is never left in an unbootable state, a valid
+version of firmware is always held in flash. Flash storage is organized into A and B banks
+where one bank holds a valid set of images while updates are installed in the other bank.
+The bootloader is capable of booting from either bank, as instructed by the FWU metadata
+written by the Update Agent. Where firmware storage is distributed across multiple locations,
+A and B volumes must exist for each location.
+
+Update Agent
+''''''''''''
+The Update Agent is a logical component defined in the FWU-A specification reference model.
+The Update Agent handles requests from a client to install a set of images in preparation
+for activating the updated firmware. In the TS project, the role of the Update Agent is
+reflected by a firmware component with the same name.
+
+Firmware Directory
+''''''''''''''''''
+The FWU-A specification defines a stream endpoint that can be read by a client to obtain a
+listing of updatable firmware components. In the TS implementation, this is backed by the
+Firmware Directory component that is populated with information about the booted firmware.
+
+Storage Volumes
+''''''''''''''''
+All NV storage accessed by the Update Agent is represented by a set of volume objects. A
+volume presents a unit of storage as a seekable file with support for conventional file IO
+operations. The volume provides a uniform interface for all storage operations performed by
+the Update Agent. The volume uses and extends the io_dev driver model from the TF-A project.
+Concrete volume objects can access different types of storage such as:
+
+  - A raw flash device
+  - A disk partition
+  - Storage managed by a sub-processor
+
+Installers
+''''''''''
+Trusted Services FWU support provides a framework for updating arbitrary firmware images.
+From the framework's perspective, an image is just a binary blob, identified by an image
+type UUID. To allow for image format specific installation, a common installer interface is
+defined to allow for alternative concrete installers. Installers can update the entire
+contents of a volume or modify parts of a volume.  Where a volume holds a container such
+as a FIP, a specialized installer with knowledge of the container format can provide finer
+grain updates of the container contents. An installer implements an enumerate method to
+return information about images that it can handle. The Firmware Directory is formed by
+aggregating the information returned by each installer's enumerate method.
+
+Firmware Locations
+''''''''''''''''''
+The Update Agent can manage firmware distributed across multiple locations e.g. different
+flash partitions, different flash devices or different subsystems. The concept of a firmware
+location is used in the TS implementation to provide a generalized model for handling
+distributed firmware. Each location is assigned an integer ID that is used to bind together:
+
+  - A pair of storage volumes (for A + B banks)
+  - A set of one or more installers. The set of installers configured for the location
+    determines which image types are updatable for the location.
+
+Installers are categorized as one of the following types:
+
+  - **Whole volume installer** - updates the entire contents of a volume. The whole volume
+    contents is presented as an entry in the firmware directory.
+  - **Sub-volume installer** - updates components contained within a volume. Each image
+    contained within the active volume is presented as an entry in the firmware directory.
+  - **Whole volume copy installer** - copies entire volume contents from one volume to
+    another. Contributes no entries to the firmware directory.
+
+A platform integrator is responsible for selecting which installers are configured for a
+location. Each location must be assigned at least one installer. Any combination of different
+types of installer could make sense in a platform configuration. Here are some example
+configurations:
+
+.. list-table::
+  :header-rows: 1
+
+  * - Location configuration
+    - Update capability for location
+  * - *WholeVolumeInstaller*
+    - A single entry appears in the firmware directory for the location that corresponds to
+      the entire volume contents. An incoming update package must include an image that
+      corresponds to the directory entry.
+  * - *WholeVolumeInstaller + SubVolumeInstaller*
+    - Firmware directory entries appear for the whole volume and for each updatable component
+      contained within the volume. An incoming update package must include either one or more
+      sub-volume images or a whole volume image for this location.
+  * - *WholeVolumeInstaller + SubVolumeInstaller + WholeVolumeCopyInstaller*
+    - Firmware directory entries appear for the whole volume and for each updatable component
+      contained within the volume. If no image for this location is included in an incoming
+      update package, the currently active volume contents is copied to the update volume.
+  * - *WholeVolumeCopyInstaller*
+    - This configuration can be used if it is necessary to prevent updates for a location.
+      For any update transaction, the currently active volume contents will always be copied
+      to the update volume for this location.
+
+Design Description
+------------------
+FWU components within the TS project are designed for reuse in alternative deployments. The
+project currently maintains two FWU deployments, both sharing many common components:
+
+  - **fwu/config/default-sp** - the Update Agent runs within a secure partition. The client
+    invokes ABI operations via FF-A based RPC. Updates are applied to a dedicated Swd flash device.
+  - **fwu/config/fwu-app-linux-pc** - the Update Agent runs within a command-line application.
+    Updates are applied to a disk image file residing in the host filesystem.
+
+There is clear separation between different classes of component making component-level reuse
+straight-forward. The following diagram illustrates the main FWU components. The direction of
+the arrows linking components shows the direction of a dependency between associated
+components (i.e. A→B means that A depends on B).
+
+.. image:: image/update-agent-components.svg
+
+Core Components
+''''''''''''''''
+Any FWU deployment that supports a banked firmware store is expected to use the core set of
+FWU components. Core components are partitioned between:
+
+  - **Generic Update Agent** - manages update transactions and streams used for transferring
+    image data. Also owns the FW Directory.
+  - **Banked FW Store** - manages banked access to storage and communication with the bootloader
+    via FWU metadata.
+
+Generic Update Agent Model
+""""""""""""""""""""""""""
+The following class diagram models the generic Update Agent:
+
+.. uml:: uml/UpdateAgentClassDiagram.puml
+
+Classes in the model perform the following roles:
+
+.. list-table::
+  :header-rows: 1
+
+  * - Class
+    - Description
+    - Source files
+  * - *update_agent*
+    - Coordinates update transactions from start to finish. Implements the FWU state machine that
+      enforces correct behaviour during an update. Provides functions that form the public interface
+      for an instance of the Update Agent.
+    - components/service/fwu/agent/update_agent.h, components/service/fwu/agent/update_agent.c
+  * - *stream_manager*
+    - Manages a pool of stream objects for client initiated stream read and write operations. Streams
+      are used for writing image data and reading FWU objects such as the image directory.
+    - components/service/fwu/agent/stream_manager.h, components/service/fwu/agent/stream_manager.c
+  * - *fw_directory*
+    - Holds information about the currently active firmware. The contents of the fw_directory is
+      updated by a fw_inspector at boot time. Forms the source of the information returned to a
+      client that reads the image directory object.
+    - components/service/fwu/agent/fw_directory.h, components/service/fwu/agent/fw_directory.c
+  * - *img_dir_serializer*
+    - Serializes information about currently active firmware in-line with the FWU-A specification.
+    - components/service/fwu/agent/img_dir_serializer.h, components/service/fwu/agent/img_dir_serializer.c
+  * - *fw_inspector*
+    - Called by the update_agent to inspect firmware and update the contents of the fw_directory to
+      provide a fresh view of active firmware. To allow for alternative inspection strategies, the
+      concrete fw_inspector to use is determined by deployment specific configuration code and passed
+      to the update_agent at initialization. The direct_fw_inspector is a concrete fw_inspector that
+      relies on direct access to the set of installers registered as part of the Update Agent configuration.
+    - components/service/fwu/inspector/fw_inspector.h, components/service/fwu/inspector/direct/direct_fw_inspector.h,
+      components/service/fwu/inspector/direct/direct_fw_inspector.c
+
+Banked FW Store Model
+""""""""""""""""""""""
+The update_agent interacts with the fw_store via a common interface. No details about the nature of the fw_store
+are exposed to the update_agent. The following class diagram models a particular realization of the fw_store
+interface that implements the A/B bank scheme:
+
+.. uml:: uml/FwStoreClassDiagram.puml
+
+Classes in the model perform the following roles:
+
+.. list-table::
+  :header-rows: 1
+
+  * - Class
+    - Description
+    - Source files
+  * - *fw_store*
+    - Manages updates to banked storage volumes.
+    - components/service/fwu/fw_store/fw_store.h,
+      components/service/fwu/fw_store/banked/banked_fw_store.h,
+      components/service/fwu/fw_store/banked/banked_fw_store.c
+  * - *bank_tracker*
+    - Tracks usage and accepted state of firmware banks.
+    - components/service/fwu/fw_store/banked/bank_tracker.h,
+      components/service/fwu/fw_store/banked/bank_tracker.c
+  * - *metadata_manager*
+    - Manages storage and updates to the FWU metadata used for signaling to the bootloader. Responsible for
+      detecting and repairing corrupted metadata.
+    - components/service/fwu/fw_store/banked/metadata_manager.h,
+      components/service/fwu/fw_store/banked/metadata_manager.c
+  * - *metadata_serializer*
+    - Serializes update bank state in a standard format for compatibility with the boot loader. To ensure
+      version compatibility through fw updates, alternative realizations of the metadata_serializer may be
+      selected at runtime. Currently support for V1 and V2 formats (as defined by the FWU-A specification).
+    - components/service/fwu/fw_store/banked/metadata_serializer/metadata_serializer.h
+  * - *installer*
+    - Base class for installers. Defines a common interface for installing images associated with a location.
+    - components/service/fwu/installer/installer.h,
+      components/service/fwu/installer/installer.c
+  * - *installer_index*
+    - Holds pointers to the set of concrete installers registered during platform configuration.
+    - components/service/fwu/installer/installer_index.h,
+      components/service/fwu/installer/installer_index.c
+  * - *volume*
+    - Presents a unit of storage is a seekable file.  Supports byte-orient read and writes operation
+      to storage. All NV storage is accessed by the Update Agent using volumes. The set of volume objects
+      needed for a deployment are created as part of platform specific initialisation.
+    - components/media/volume/volume.h,
+      components/media/volume/volume.c
+  * - *volume_index*
+    - Holds pointers to the set of concrete volumes registered during platform configuration.
+    - components/media/volume/index/volume_index.h,
+      components/media/volume/index/volume_index.c
+
+Service Interface
+''''''''''''''''''
+For deployments where the Update Agent needs to be remotely callable, the fwu_provider implements an
+RPC interface that accepts call requests, de-serializes call parameters and calls the corresponding
+interface functions provided by the update_agent. In the reference deployment, where the Update
+Agent runs within an SP, the fwu_provider receives call requests, made via FF-A, and returns responses
+to the remote client. The fwu_provider may be used with any RPC layer where remote calling is required.
+
+Platform Configuration
+----------------------
+A platform specific configuration tells the Update Agent about storage for firmware and defines the
+policy for the way the firmware can be update. Configuration steps result in the creation of:
+
+  - A set of concrete installer objects registered with the installer_index. This defines the
+    type of images that can be updated.
+  - A set of concrete volume objects registered with the volume_index. This defines where images
+    can be installed.
+
+Each installer is assigned a location ID to bind the installer to a particular firmware location.
+Location IDs are integer values defined by the configuration code. For example, where firmware
+consists of AP firmware, SCP firmware and RSS firmware, location IDs could be assigned as follows:
+
+.. list-table::
+  :header-rows: 1
+
+  * - Location
+    - ID
+  * - AP firmware
+    - 0
+  * - SCP firmware
+    - 1
+  * - RSS firmware
+    - 2
+
+When volume objects are added to the volume index, each one is assigned a volume ID which is
+formed by combining the corresponding location ID with the bank index to which the volume
+provides access to.
+
+The types of installer and volume needed will depend on factors such as:
+
+  - How NV storage is accessed by the Update Agent.
+  - The type of images that need to be installed.
+  - How flash storage is partitioned e.g. is GPT used or some other partition description method.
+
+Source files related to FWU configuration:
+
+.. list-table::
+  :header-rows: 1
+
+  * - Directory
+    - Contains
+  * - components/service/fwu/config
+    - Configuration strategies for provisioning installers and volumes
+  * - components/service/fwu/installer/factory
+    - Factories for constructing different types of installer
+  * - components/media/volume/factory
+    - Factories for constructing different types of volume
+
+Update Agent Configuration using GPT
+''''''''''''''''''''''''''''''''''''
+The TS FWU service implementation includes a GPT based configurator that automatically discovers
+the set of installers and volumes to construct, based on the contents of the GPT that describes
+the flash layout. The following diagram illustrates a typical flash partition layout. Note that
+not all partitions contain firmware.
+
+.. image:: image/gpt-based-flash-layout.svg
+
+A deployment of the Update Agent is built with an installer factory that has the capability to
+construct a set of installers that are suitable for a family of platforms where common image
+types and update policy applies. An installer factory is capable of constructing a concrete set
+of installers for installing images into a particular set of partitions, identified by partition
+type GUID. A platform may not incorporate the complete set of partition types. The default
+installer factory (under components/service/fwu/installer/factory/default) includes rules for
+constructing installers for:
+
+  - **AP Firmware** - where application firmware is contained within a FIP
+  - **SCP Firmware** - binary boot image for SCP
+  - **RSS Firmware** - binary boot image for RSS
+
+The GPT based configurator relies on access to the GPT partition table. During initialization
+of the Update Agent, the configurator iterates over each partition entry. If no installers are
+registered for the partition, the partition type GUID is offered to the installer factory. If
+at least one installer is constructed, a volume object is constructed to provide access to the
+partition. This partition will hold one of the banked copies of the image identified by the
+partition type GUID. If one or more installers have already been constructed for the partition
+type GUID, an additional volume object is constructed to provide access to the second
+banked partition.
+
+The designation of bank index to partition is determined from the PartitionName field in the
+partition entry.  The first UTF-16 character (0 or 1) is interpreted as the bank index assigned
+to the partition. Different conventions are possible if an alternative configurator is used.
+
+FWU Command Line Application
+----------------------------
+A build configuration of the fwu deployment integrates the Update Agent within a command-line
+application that can be run on a Linux PC. Instead of updating images stored in flash, the
+application operates on a GPT formatted disk image file residing in the host machine's filesystem.
+The core components of the application are identical to those used in embedded deployments.
+To build and run the fwu application, use the following commands from the root of the
+checked-out TS project::
+
+  cd deployments/fwu/config/fwu-app-linux-pc
+  cmake -B build
+  cd build
+  make
+  ./fwu -help
+  Usage: fwu disk-filename [-dir -meta] [-boot-index number -meta-ver number] [-img filename -img-type uuid]
+
+    disk-filename	Disk image file to update
+    -dir		Print image directory
+    -meta		Print FWU metadata
+    -boot-index	Override default boot index [0..n]
+    -meta-ver	Specify FWU metadata to use
+    -img		File containing image update
+    -img-type	Canonical UUID of image to update
+
+Some sample disk image files can be found under::
+
+  components/media/disk/disk_images
+
+The sample disk image file multi_location_fw.img includes a GPT with entries for the firmware
+and metadata partitions illustrated in the diagram above. Note that the sample disk image
+does not contain valid FWU metadata within the primary and backup metadata partitions. This
+condition is detected by the Update Agent which writes valid metadata that reflects the contents
+of the disk image file. Subsequent invocations of the app will use the valid metadata previously
+written to the disk image.
+
+The app can of course be used with flash image files created by a firmware build system.
+The command-line interface currently restricts updates to consist of just a single image,
+identified by an image type UUID. Extending the command-line interface to support multi-image
+update transactions is possible by for example adding the capability to process an FMP capsule
+file containing multiple images.
+
+Testing the Update Agent
+------------------------
+FWU components are tested in both native PC and embedded environments. PC based tests use the
+fwu_dut C++ class to simulate the role of the bootloader and to allow device reboot scenarios
+to be recreated. The simulated device-under-test maintains NV storage state through reboots
+to mimic real device behaviour. Test components that support PC based testing are summarized
+in the following table:
+
+.. list-table::
+  :header-rows: 1
+
+  * - Component
+    - Description
+    - Project Directory
+  * - *fwu_dut*
+    - Base class to represent a device-under-test (DUT). Presents an interface used by test
+      cases that allows for test-case reuse with different fwu_dut specializations.
+    - components/service/fwu/test/fwu_dut
+  * - *sim_fwu_dut*
+    - A specialization of the fwu_dut class that adds bootloader simulation and various
+      other test support capabilities.
+    - components/service/fwu/test/fwu_dut/sim
+  * - *proxy_fwu_dut*
+    - A specialization of the fwu_dut class that acts as a proxy for the fwu_dut that
+      actually hosts the Update Agent.
+    - components/service/fwu/test/fwu_dut/proxy
+  * - *fwu_client*
+    - Presents FWU methods (begin_staging, end_staging etc.) for use by test cases.
+    - components/service/fwu/test/fwu_client
+  * - *direct_fwu_client*
+    - An fwu_client that calls Update Agent interface functions directly.
+    - components/service/fwu/test/fwu_client/direct
+  * - *remote_fwu_client*
+    - An fwu_client that makes RPC call requests to invoke Update Agent operations. Call
+      parameters are serialized using the FWU access protocol.
+    - components/service/fwu/test/fwu_client/remote
+  * - *image_directory_checker*
+    - A test support class that fetches the serialized image directory and provides
+      methods for checking the fetched content.
+    - components/service/fwu/test/image_directory_checker
+  * - *metadata_checker*
+    - Provides methods to check that the fetched FWU metadata reflects the state expected
+      by test cases. Decouples test code from the underlying metadata format. Support
+      for V1 and V2 metadata is provided.
+    - components/service/fwu/test/metadata_checker
+  * - *metadata_fetcher*
+    - Provides an interface for fetching the metadata associated with the DUT. Depending
+      on the deployment, different strategies for fetching the metadata are needed.
+    - components/service/fwu/test/metadata_fetcher
+
+An extensive set of test suites uses the test framework components listed above to test
+various update scenarios. The following test suites live under::
+
+  components/service/fwu/test/ref_scenarios
+
+.. list-table::
+  :header-rows: 1
+
+  * - Test Suite
+    - Description
+  * - *image_directory_tests*
+    - Tests reading of the image directory via the Update Agent stream interface.
+  * - *invalid_behaviour_tests*
+    - Tests to check that invalid requests are rejected with the expected error codes.
+  * - *oversize_image_tests*
+    - Tests to check defenses against attempts to install images that are too big for
+      the available storage.
+  * - *power_failure_tests*
+    - Tests recreate power-failure scenarios at various points during an update transaction.
+      Tests check that a viable set of firmware is always available.
+  * - *rollback_tests*
+    - Tests recreate bootloader initiated and update client requested rollback scenarios.
+  * - *update_scenario_tests*
+    - Various normal update scenarios with a well-behaved client.
+
+The test suites list above are included in the following TS test deployments:
+
+  - **component-test** - runs tests in a native PC environment using a direct_fwu_client.
+  - **ts-service-test** - runs tests in a native PC environment using a remote_fwu_client.
+
+Reference Integration Test Environment
+--------------------------------------
+The following diagram provides an overview of the planned reference integration and test
+environment used for testing on FVP.
+
+.. image:: image/fwu-reference-integration.svg
+
+--------------
+
+*Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.*
+
+SPDX-License-Identifier: BSD-3-Clause
diff --git a/docs/services/image/fwu-reference-integration.svg b/docs/services/image/fwu-reference-integration.svg
new file mode 100644
index 0000000..e1decb0
--- /dev/null
+++ b/docs/services/image/fwu-reference-integration.svg
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Do not edit this file with editors other than diagrams.net -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg xmlns="http://www.w3.org/2000/svg" style="background-color: rgb(255, 255, 255);" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="931px" height="721px" viewBox="-0.5 -0.5 931 721" content="&lt;mxfile host=&quot;confluence.arm.com&quot; modified=&quot;2023-02-16T09:53:31.669Z&quot; agent=&quot;5.0 (X11)&quot; etag=&quot;zn_aC2t2yAJM8WazQzIG&quot; version=&quot;20.3.7&quot; type=&quot;atlas&quot;&gt;&lt;mxAtlasLibraries/&gt;&lt;diagram id=&quot;5UEW7cEHIPK3IHdKgyrX&quot; name=&quot;Page-1&quot;&gt;5Vtbd6I6FP41PrYLiNweq62dzpp22ml75pynrghRmAJxIGqdXz8JBIQkWnXE0Z4+WNm5EPb37Us2sQP68dt1CifBLfZR1DE0/60DLjuGobsA0H9MsuAS2zULyTgNfS5bCh7DX4gLNS6dhj7KGh0JxhEJJ02hh5MEeaQhg2mK581uIxw17zqBY35HbSl49GCEpG7fQ58EhdQxa70/oXAclHfWNd4Sw7IzF2QB9PG8JgJXHdBPMSbFt/itjyKmvVIvxbjBitZqYSlKyCYDHPLyI3Ptga2hK+MVOf1bVz8r1TyD0ZQ/8SecESq5hV4QJoivnSxKhcxQSkKqn4soHCdURPCkA3qQX0VoRBfTyybQC5PxE2u7dJaCL3nzpbGUfOO603NZACfsNt50iNhlwQa6RtDzw5TCG2J2kwxPmW57I5yQR76yLr0OSByx/qwpjKI+jnCaLxqM3JGNfDYlSfErqrUAC7iAtcjq5BpmD4zeaiKu3muEY0TSBe3CW8/MLlcnZ/uZBbhgvuSOW8qCGm/skiWQ83Vczb6ElH7hqG6BsCkBPPjn/mOgivK/1lE1LAFV0zYlVE1HgaqpmS2hqkuoXj4/nSiqe8FIEzFSWF7XUmAE7LYsrythJAGEEv+CBSl6leAENfWS4mniM691qeUchykROq/UHNV66pXm/uASoIO72cR5en2YPY8Xb59L/tA5x4iseQa+ZOSXUXIFDnVLUBpCIUtRBEk4a8ZWleL5He5xmJAlzLojoKx3BfCKB+fD6sFQmMkA4kyuMFOhGmmmnAnVg+9ODksixyiCWcCGxSwloalKGMnRt7S6GPtTJlthzKXtarUeHiUJov6xp/YK+7BCvfR3pVYN2QgNew0/9m6DjqTmDMVhQFMcqiVJu/Q5SdMGm5GFm109DHHRu0qOQ9/PAZsHIUGPFCZ2zznNmiVL3wMSupiI6JaMhNIbtgWEKwHxhDLiwezUOG4agmqBI2cD1S7gICTXt4s0HnU0WeitCzboLST/su/nJr/6r9Zy+Va/WJQXCX2WYpAO9FLAxunnmgZKwXJwftUYfY/SkKqEIbjeEurxbR3d3o1v5lHFN8olcQOxa4A7A2KEszaMcJQmcFHrNmEdsjWL7tpi7qW5AqeLOfcaQHV5Y5OnSHSyjFn7h/XtZ11T1Hf3Lzt33d67A6qcSd2RaGucCDBXeRG1M9PXOrP2PY91XJ7HEElliBWJnVNr41COh7uEdt2OnFFOJz4kKMfg55QmNRmDH7MMfs6+obycdnF/84FdEnAFzCsfVU+K9JZ80k1AerOB+5BNrp0sfbRfkvlCUSG5w2kM2bjvOI18CY3TKJYIJTDfRI7fVZXAHGMILGtfGzs5xCvKK6qkt9p47D3oGDLCdMcQjujMAw+n6XRCPrDFdcWipGKrrSpJtmZvhoTGI/KmKfpg9gaRM/JU9mZ5DhqO2rI3oChnAtc+NxUWt4995rqiYT30ZdQWDCtiUA3ZtzHJNWDBmIGZDDP2b5JiD2WZxICmVajsZgUQ3CZ9mAX5cNYewSGK7nEWcmwlQ/0idGjybaVdDzEhOP5DXKuwaClqBa7CTJ3WvKaE4Wj+wnKUFzgJJYSOuhQjZqzKnOOwhRi5qiupdLdCTLlbyXdB1T7mvULMn++dVsK0t30Q19CR7IOkNwzG3t4wtLYNAlKwsLS1S5NHdA+xdQKScTyXO6eLMUrkbO2kvI+heCl8WO/TYhHm3DY39SWHr7iADT3NcVVcjsDT7GDYytRfrsTuKeptw58aWbfi6u68MzbkHTgq3lVHvqRXg9vyTnzHWJ3ZOxDtZH/3BUNGIjouyQtwKJ5SXeWS8u06Tf0ZMWFKpm28I+CR6S8XBwzRtyheEBy4GifvHZ+vBjdUctt7ojNe3z8xkFiFjhSA+WH22lmehpiHJCj0QvINXFZ0p5+D78/0ky4T0mQCssUnOeBhGs9hXn8YwuQ1O/+oaEtHn1Rgq14HiVFiF7C1HzPXt+zPN+NfX3XrbrG4BSNFnSArS0EVfhIa/59iQNkqRW1FAqkq4bl7OFT407p6oFpM7q77/dep74zH8WdFgt7DmETMqaYSXkednJ9JB2AOmp4rtSsf0rhahqe7r9+YKyuC1GlpeuWZvPd43Jqm5bNGkk5PPB9dZ771fHQdEY8lH7Wls2piFrLxmRdLfA2pi3XU/aWkStUqfk4hUY9GwlkVqLbjYSPGVaSslwZXUlIvmSudjti6Wqi3UC20TpO7juj8dqauI27iN2Tu1tVCQ7QRp1Es3Lb0Ry+XP2Equi9/CQaufgM=&lt;/diagram&gt;&lt;/mxfile&gt;"><defs/><g><path d="M 105 -105 L 815 -105 L 825 -95 L 825 825 L 115 825 L 105 815 L 105 -105 Z" fill="#f9f7ed" stroke="#36393d" stroke-miterlimit="10" transform="rotate(90,465,360)" pointer-events="all"/><path d="M 115 825 L 115 -95 L 105 -105 M 115 -95 L 825 -95" fill="none" stroke="#36393d" stroke-miterlimit="10" transform="rotate(90,465,360)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe flex-start; width: 1px; height: 1px; padding-top: 15px; margin-left: 4px;"><div style="box-sizing: border-box; font-size: 0px; text-align: left;" data-drawio-colors="color: rgb(0, 0, 0); "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; text-decoration: underline; white-space: nowrap;">Host Machine</div></div></div></foreignObject><text x="4" y="27" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-decoration="underline">Host Machine</text></switch></g><path d="M 317.5 17.5 L 812.5 17.5 L 822.5 27.5 L 822.5 597.5 L 327.5 597.5 L 317.5 587.5 L 317.5 17.5 Z" fill="#eeeeee" stroke="#36393d" stroke-miterlimit="10" transform="rotate(90,570,307.5)" pointer-events="all"/><path d="M 327.5 597.5 L 327.5 27.5 L 317.5 17.5 M 327.5 27.5 L 822.5 27.5" fill="none" stroke="#36393d" stroke-miterlimit="10" transform="rotate(90,570,307.5)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe flex-start; width: 1px; height: 1px; padding-top: 70px; margin-left: 284px;"><div style="box-sizing: border-box; font-size: 0px; text-align: left;" data-drawio-colors="color: rgb(0, 0, 0); "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; text-decoration: underline; white-space: nowrap;">FVP</div></div></div></foreignObject><text x="284" y="82" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-decoration="underline">FVP</text></switch></g><path d="M 385 55 L 745 55 L 755 65 L 755 515 L 395 515 L 385 505 L 385 55 Z" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" transform="rotate(90,570,285)" pointer-events="all"/><path d="M 395 515 L 395 65 L 385 55 M 395 65 L 755 65" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" transform="rotate(90,570,285)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe flex-start; width: 1px; height: 1px; padding-top: 115px; margin-left: 344px;"><div style="box-sizing: border-box; font-size: 0px; text-align: left;" data-drawio-colors="color: rgb(0, 0, 0); "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; text-decoration: underline; white-space: nowrap;">DUT</div></div></div></foreignObject><text x="344" y="127" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-decoration="underline">DUT</text></switch></g><path d="M 540 205 L 590 205" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 445 610 L 705 610 L 705 660 L 445 660 L 445 650 L 435 650 L 435 640 L 445 640 L 445 630 L 435 630 L 435 620 L 445 620 Z" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 445 620 L 455 620 L 455 630 L 445 630 M 445 640 L 455 640 L 455 650 L 445 650" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g fill="rgb(0, 0, 0)" font-family="Helvetica" text-anchor="middle" font-size="12px"><text x="579.5" y="627.5">flash image file</text></g><rect x="680" y="470" width="60" height="30" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 485px; margin-left: 681px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">semihosting</div></div></div></foreignObject><text x="710" y="489" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">semihosting</text></switch></g><path d="M 30 245 L 120 245 L 120 295 L 30 295 L 30 285 L 20 285 L 20 275 L 30 275 L 30 265 L 20 265 L 20 255 L 30 255 Z" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 30 255 L 40 255 L 40 265 L 30 265 M 30 275 L 40 275 L 40 285 L 30 285" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g fill="rgb(0, 0, 0)" font-family="Helvetica" text-anchor="middle" font-size="12px"><text x="79.5" y="262.5">Testcase</text></g><path d="M 70 245 L 70 121 L 271.89 121.15" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 277.14 121.15 L 270.14 124.65 L 271.89 121.15 L 270.14 117.65 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="90" y="90" width="60" height="30" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 105px; margin-left: 91px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">start/stop</div></div></div></foreignObject><text x="120" y="109" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">start/stop</text></switch></g><path d="M 70 295 L 70 645 L 428.63 645" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 433.88 645 L 426.88 648.5 L 428.63 645 L 426.88 641.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="150" y="180" width="110" height="30" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 108px; height: 1px; padding-top: 195px; margin-left: 151px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">update requests to fw test API</div></div></div></foreignObject><text x="205" y="199" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">update requests to...</text></switch></g><path d="M 490 10 L 640 10 L 650 20 L 650 410 L 500 410 L 490 400 L 490 10 Z" fill="#d5e8d4" stroke="#82b366" stroke-miterlimit="10" transform="rotate(90,570,210)" pointer-events="all"/><path d="M 500 410 L 500 20 L 490 10 M 500 20 L 650 20" fill="none" stroke="#82b366" stroke-miterlimit="10" transform="rotate(90,570,210)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe flex-start; width: 1px; height: 1px; padding-top: 145px; margin-left: 374px;"><div style="box-sizing: border-box; font-size: 0px; text-align: left;" data-drawio-colors="color: rgb(0, 0, 0); "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; text-decoration: underline; white-space: nowrap;">Normal World</div></div></div></foreignObject><text x="374" y="157" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-decoration="underline">Normal World</text></switch></g><rect x="80" y="610" width="80" height="30" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 625px; margin-left: 81px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">modify/corrupt</div></div></div></foreignObject><text x="120" y="629" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">modify/corrupt</text></switch></g><path d="M 493.75 176.25 L 633.75 176.25 L 643.75 186.25 L 643.75 573.75 L 503.75 573.75 L 493.75 563.75 L 493.75 176.25 Z" fill="#dae8fc" stroke="#6c8ebf" stroke-miterlimit="10" transform="rotate(90,568.75,375)" pointer-events="all"/><path d="M 503.75 573.75 L 503.75 186.25 L 493.75 176.25 M 503.75 186.25 L 643.75 186.25" fill="none" stroke="#6c8ebf" stroke-miterlimit="10" transform="rotate(90,568.75,375)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe flex-start; width: 1px; height: 1px; padding-top: 315px; margin-left: 374px;"><div style="box-sizing: border-box; font-size: 0px; text-align: left;" data-drawio-colors="color: rgb(0, 0, 0); "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; text-decoration: underline; white-space: nowrap;">Secure World</div></div></div></foreignObject><text x="374" y="327" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-decoration="underline">Secure World</text></switch></g><rect x="540" y="165" width="190" height="80" fill="none" stroke="rgb(0, 0, 0)" stroke-dasharray="3 3" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe center; width: 188px; height: 1px; padding-top: 162px; margin-left: 541px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">user<br /> process</div></div></div></foreignObject><text x="635" y="162" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">user...</text></switch></g><path d="M 600 180 L 690 180 L 690 230 L 600 230 L 600 220 L 590 220 L 590 210 L 600 210 L 600 200 L 590 200 L 590 190 L 600 190 Z" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 600 190 L 610 190 L 610 200 L 600 200 M 600 210 L 610 210 L 610 220 L 600 220" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g fill="rgb(0, 0, 0)" font-family="Helvetica" text-anchor="middle" font-size="12px"><text x="649.5" y="197.5">fw_test_api</text></g><path d="M 120 270 L 170 270 L 170 215 L 583.63 215" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 588.88 215 L 581.88 218.5 L 583.63 215 L 581.88 211.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 600 355 L 690 355 L 690 405 L 600 405 L 600 395 L 590 395 L 590 385 L 600 385 L 600 375 L 590 375 L 590 365 L 600 365 Z" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 600 365 L 610 365 L 610 375 L 600 375 M 600 385 L 610 385 L 610 395 L 600 395" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g fill="rgb(0, 0, 0)" font-family="Helvetica" text-anchor="middle" font-size="12px"><text x="649.5" y="372.5">Update Agent</text></g><path d="M 640 405 L 637.58 603.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 637.51 608.88 L 634.1 601.84 L 637.58 603.63 L 641.1 601.93 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 640 230 L 640 348.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 640 353.88 L 636.5 346.88 L 640 348.63 L 643.5 346.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="260" y="590" width="110" height="30" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 108px; height: 1px; padding-top: 605px; margin-left: 262px;"><div style="box-sizing: border-box; font-size: 0px; text-align: left;" data-drawio-colors="color: rgb(0, 0, 0); "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Loaded into emulated flash on startup</div></div></div></foreignObject><text x="262" y="609" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px">Loaded into emulat...</text></switch></g><rect x="740" y="590" width="160" height="90" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 158px; height: 1px; padding-top: 635px; margin-left: 742px;"><div style="box-sizing: border-box; font-size: 0px; text-align: left;" data-drawio-colors="color: rgb(0, 0, 0); "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">UEFI MBT/GPT formatted disk image with partitions for FWU metadata and firmware banks.</div></div></div></foreignObject><text x="742" y="639" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px">UEFI MBT/GPT formatted dis...</text></switch></g><rect x="550" y="335" width="180" height="95" fill="none" stroke="rgb(0, 0, 0)" stroke-dasharray="3 3" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe center; width: 178px; height: 1px; padding-top: 332px; margin-left: 551px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">secure partition</div></div></div></foreignObject><text x="640" y="332" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">secure partition</text></switch></g><path d="M 410 355 L 500 355 L 500 405 L 410 405 L 410 395 L 400 395 L 400 385 L 410 385 L 410 375 L 400 375 L 400 365 L 410 365 Z" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 410 365 L 420 365 L 420 375 L 410 375 M 410 385 L 420 385 L 420 395 L 410 395" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g fill="rgb(0, 0, 0)" font-family="Helvetica" text-anchor="middle" font-size="12px"><text x="459.5" y="372.5">Bootloader</text></g><path d="M 370 490 L 540 490 L 540 540 L 370 540 L 370 530 L 360 530 L 360 520 L 370 520 L 370 510 L 360 510 L 360 500 L 370 500 Z" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 370 500 L 380 500 L 380 510 L 370 510 M 370 520 L 380 520 L 380 530 L 370 530" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g fill="rgb(0, 0, 0)" font-family="Helvetica" text-anchor="middle" font-size="12px"><text x="459.5" y="507.5">Emulated NOR Flash</text></g><path d="M 450 405 L 450 483.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 450 488.88 L 446.5 481.88 L 450 483.63 L 453.5 481.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 435 625 Q 250 550 354.11 507.41" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="stroke"/><path d="M 358.97 505.42 L 353.81 511.31 L 354.11 507.41 L 351.16 504.83 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/></g><switch><g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/><a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank"><text text-anchor="middle" font-size="10px" x="50%" y="100%">Text is not SVG - cannot display</text></a></switch></svg>
\ No newline at end of file
diff --git a/docs/services/image/gpt-based-flash-layout.svg b/docs/services/image/gpt-based-flash-layout.svg
new file mode 100644
index 0000000..8f1061c
--- /dev/null
+++ b/docs/services/image/gpt-based-flash-layout.svg
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Do not edit this file with editors other than diagrams.net -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg xmlns="http://www.w3.org/2000/svg" style="background-color: rgb(255, 255, 255);" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="401px" height="781px" viewBox="-0.5 -0.5 401 781" content="&lt;mxfile host=&quot;confluence.arm.com&quot; modified=&quot;2023-02-16T09:50:57.516Z&quot; agent=&quot;5.0 (X11)&quot; etag=&quot;9oA7HNylA2Pn-M09WDsz&quot; version=&quot;20.3.7&quot; type=&quot;atlas&quot;&gt;&lt;mxAtlasLibraries/&gt;&lt;diagram id=&quot;MJao7NBNlqcqI8fyxszN&quot; name=&quot;Page-1&quot;&gt;7Zlbb9owGIZ/TS4tJfEB57LQwqqpHSLtql06sQNZkxgZM2C/fg6YEpZsgo0oakW4wH59iP0+/pBtHDjI1yPF5rMHyUXm+C5fO/DW8X0PQ2i+SmVjFRjgnTJVKbfaQQjTn8KKrlWXKReLo4paykyn82MxlkUhYn2kMaXk6rhaIrPjt87Z1L7RPQhhzDJRq/aScj3bqRRXan8S6XS2f7Pn2pKc7StbYTFjXK4qErxz4EBJqXepfD0QWene3pddu+EfSt8GpkShT2kA5UA9jb49DvjjZC7zBz9ffAe2lx8sW9oJj5XUxsj0hzD6Q39iB683e0eUXBZclJ26DuyvZqkW4ZzFZenKLAKjzXSemZxnkkmaZQOZSbVtCxMaizg2+kIr+SoqJRHFCJcd1qe1H6NQWqwrkp3mSMhcaLUxVWwpoNbyzW/51YEg2nOaVehBqzG7aKZvXR98NQlr7Rk2+w02pznbDno0frqsx7j8NHlMtk/ZQha6ou+elrzHJ3pP2vIe/sX74ctzucqFZpxp5vgkM6PpR8qkpmVqzJROdSoLU+tpMy9DYvR8f+vAG1OD5SWIIlqUX5T1GEXMBRTSHkBuQgCLkAcYjQKGGXG5Dy+LOUn85lDiJCKYtIPT65omqtE01t3cjMEwVfnKTPV/IPoIezEnAgRuIgCKPAyixHMBI0EUC58jRMlFIXIsKEdNEKkfQdISxF7XEHENoneFeG4kwq4pksZQDAeXwUgCzxjLIPB7JUbPRSBinIMehkHsuixw9zvJ940x6BpjrzEYrxjPwuh3vs2hjdE4CcOLYIwDRJmHCcA0jgCKIQURcgkQxI3MRsQvff8AGGHn+5ugMRqvGM/D2PkOZ7+OKhyf74b34CtTKYsysbisy0zQpPEsQGIqoqQdl9GpOxDcmsv164svocl/FqooL6Lev8Wn3ly0Z3H9+Dwpr6zM2Tn8AAbj7tdw/UTbZ/Hrcn69nvgHnKfGS3s//PWz7RvOj33TR1B73pvs4aJ8W1b5vwHe/QI=&lt;/diagram&gt;&lt;/mxfile&gt;"><defs/><g><rect x="0" y="0" width="400" height="30" fill="#f8cecc" stroke="#b85450" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 398px; height: 1px; padding-top: 15px; margin-left: 1px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Protective MBR</div></div></div></foreignObject><text x="200" y="19" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Protective MBR</text></switch></g><rect x="0" y="30" width="400" height="60" fill="#f5f5f5" stroke="#666666" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 398px; height: 1px; padding-top: 60px; margin-left: 1px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: #333333; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(51, 51, 51); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Primary GPT</div></div></div></foreignObject><text x="200" y="64" fill="#333333" font-family="Helvetica" font-size="12px" text-anchor="middle">Primary GPT</text></switch></g><rect x="0" y="90" width="400" height="60" fill="#fff2cc" stroke="#d6b656" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 398px; height: 1px; padding-top: 120px; margin-left: 1px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Primary FWU Metadata<br />Partition Type GUID: 8a7a84a0-8387-40f6-ab41-a8b9a5a60d23</div></div></div></foreignObject><text x="200" y="124" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Primary FWU Metadata...</text></switch></g><rect x="0" y="150" width="400" height="60" fill="#d5e8d4" stroke="#82b366" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 398px; height: 1px; padding-top: 180px; margin-left: 1px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">0:AP-Firmware<br />Partition Type GUID: 2451cd6e-90fe-4b15-bf10-a69bce2d4486</div></div></div></foreignObject><text x="200" y="184" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">0:AP-Firmware...</text></switch></g><rect x="0" y="210" width="400" height="60" fill="#d5e8d4" stroke="#82b366" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 398px; height: 1px; padding-top: 240px; margin-left: 1px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">1:AP-Firmware<br />Partition Type GUID: 2451cd6e-90fe-4b15-bf10-a69bce2d4486</div></div></div></foreignObject><text x="200" y="244" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">1:AP-Firmware...</text></switch></g><rect x="0" y="270" width="400" height="60" fill="#d5e8d4" stroke="#82b366" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 398px; height: 1px; padding-top: 300px; margin-left: 1px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">0:SCP-Firmware<br />Partition Type GUID: 691d5ea3-27fe-4104-badd-7539c00a9095</div></div></div></foreignObject><text x="200" y="304" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">0:SCP-Firmware...</text></switch></g><rect x="0" y="330" width="400" height="60" fill="#d5e8d4" stroke="#82b366" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 398px; height: 1px; padding-top: 360px; margin-left: 1px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">1:SCP-Firmware<br />Partition Type GUID: 691d5ea3-27fe-4104-badd-7539c00a9095</div></div></div></foreignObject><text x="200" y="364" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">1:SCP-Firmware...</text></switch></g><rect x="0" y="390" width="400" height="60" fill="#d5e8d4" stroke="#82b366" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 398px; height: 1px; padding-top: 420px; margin-left: 1px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">0:RSS-Firmware<br />Partition Type GUID: c948a156-58cb-4c38-b406-e60bff2223d5</div></div></div></foreignObject><text x="200" y="424" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">0:RSS-Firmware...</text></switch></g><rect x="0" y="450" width="400" height="60" fill="#d5e8d4" stroke="#82b366" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 398px; height: 1px; padding-top: 480px; margin-left: 1px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">1:RSS-Firmware<br />Partition Type GUID: c948a156-58cb-4c38-b406-e60bff2223d5</div></div></div></foreignObject><text x="200" y="484" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">1:RSS-Firmware...</text></switch></g><rect x="0" y="510" width="400" height="50" fill="#dae8fc" stroke="#6c8ebf" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 398px; height: 1px; padding-top: 535px; margin-left: 1px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">UEFI-Variables</div></div></div></foreignObject><text x="200" y="539" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">UEFI-Variables</text></switch></g><rect x="0" y="560" width="400" height="50" fill="#dae8fc" stroke="#6c8ebf" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 398px; height: 1px; padding-top: 585px; margin-left: 1px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">OS Kernel</div></div></div></foreignObject><text x="200" y="589" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">OS Kernel</text></switch></g><rect x="0" y="610" width="400" height="50" fill="#dae8fc" stroke="#6c8ebf" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 398px; height: 1px; padding-top: 635px; margin-left: 1px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Root FS</div></div></div></foreignObject><text x="200" y="639" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Root FS</text></switch></g><rect x="0" y="660" width="400" height="60" fill="#fff2cc" stroke="#d6b656" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 398px; height: 1px; padding-top: 690px; margin-left: 1px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Backup FWU Metadata<br />Partition Type GUID: 8a7a84a0-8387-40f6-ab41-a8b9a5a60d23</div></div></div></foreignObject><text x="200" y="694" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Backup FWU Metadata...</text></switch></g><rect x="0" y="720" width="400" height="60" fill="#f5f5f5" stroke="#666666" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 398px; height: 1px; padding-top: 750px; margin-left: 1px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: #333333; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(51, 51, 51); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Backup GPT</div></div></div></foreignObject><text x="200" y="754" fill="#333333" font-family="Helvetica" font-size="12px" text-anchor="middle">Backup GPT</text></switch></g></g><switch><g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/><a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank"><text text-anchor="middle" font-size="10px" x="50%" y="100%">Text is not SVG - cannot display</text></a></switch></svg>
\ No newline at end of file
diff --git a/docs/services/image/update-agent-components.svg b/docs/services/image/update-agent-components.svg
new file mode 100644
index 0000000..526c3ad
--- /dev/null
+++ b/docs/services/image/update-agent-components.svg
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Do not edit this file with editors other than diagrams.net -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg xmlns="http://www.w3.org/2000/svg" style="background-color: rgb(255, 255, 255);" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="834px" height="501px" viewBox="-0.5 -0.5 834 501" content="&lt;mxfile host=&quot;confluence.arm.com&quot; modified=&quot;2023-02-16T09:32:33.504Z&quot; agent=&quot;5.0 (X11)&quot; etag=&quot;OKKkJQnMIhDDIoBytUQw&quot; version=&quot;20.3.7&quot; type=&quot;atlas&quot;&gt;&lt;mxAtlasLibraries/&gt;&lt;diagram id=&quot;afqreZy9bPJOplJgL8vq&quot; name=&quot;Page-1&quot;&gt;5Ztdk6I4FIZ/jZduARG1L1udnZ2qnq2usqZm56orDUFTE4kb4kfvr98ACWiCvegAZmlvhJPkQN48OSQHHYD55viZwe36Kw0RGXhOeByAxcDzXB8A8ZVa3qQFPPi5ZcVwKG2lYYn/QdLoSOsOhyg5q8gpJRxvz40BjWMU8DMbZIwezqtFlJxfdQtX8opOaVgGkCCj2ncc8nVunfontf9AeLVWV3YdWbKBqrI0JGsY0sOJCXwagDmjlOdHm+MckVQ9pUve7vcLpcWNMRTzOg3Qt+/L5Rc++ca28OnP5WL3FQZDNT57SHayxwNvTITDWYj36V3zNynF+O9deqszjo58CAlexQPwKGoQFKXmsoI4WqXfS8T2OEDK3ytTBV9ijlgEq4qURXQju76yeme34jG6i0OUdswRxYc15mi5TR2CxUGAKGxrviHizBWHESZkTgllWVuA3NBHE2FPOKM/kSqJaSyazwh8ReSZJphjKjq4kL3bI8axoOJJK97gMExvaiYFWbCchaLBo7QXFRNxnzhePWV+s9s3B1KObeoDHU9McmA/I7pBnL2JKrJ06Cns5DwbjuX5oYR2omzrE2AfpA3KebIqfJcoiQNJ0zVkOe2RNaesgp053WzFIMY86YCiEKJpFPScIr8mRN64LYq8h/YoUo6ElnGlp1cY/FxlkAyDfHxTfzgWwwZJpctnAnlE2eYEwNz7+9HN3g7NaRzh1Y7BjNTretXgbIuiyAvuN9vamFsA1JxcrtvW5HKNuRUddi9bRvdizcUaHUDH8R0UpXYa8/OBFR9jYLMW7mI2b0b8qfZwHJnSu16F9O2FNUP53TaEHL2I5aToZW+Vr1iVdCu8udyNDi8Jz9YTfRXdvTvuI0N1HCccEoLYCxYiH3skfrHylup7d1ffN9TfU7LboN5JX2y1rZF+XBVuQsxQIELOW4+kH9oW6CeXQ06jskcOBA40ZXeyT5Xss8UkL2lCdtfXVpUVyE+71H36MXTXZa/YKXcqu7lN7qPstsGudmbGo7VRzcfhdDIeXRPZwaM/Am4zmlsXYVxz29o70Q3SK56n3Ypu7lh7JzqwTnRzt9o70UfWhRdzs2rIjeLwMX23KM4CApMEB+cKnw8HOmL+V3r8my/Pfsh66fHieFJt8aZOYtGXk0bp6Y/TsrJZdqbaXRyRhO5YgN7rd16PQ7ZC/J16Ug0UqvemF8b3ZPz8ivFTNoYI5Hh//ra1alDlFZ4pThNkxdNpemHOKhd5v2WrEg3DkQc0R3rWNRfGcJQxVnT7F7Azd+lNYXcCXYlgNXa34+PVxGdsFT56yNffhtalR/fjgo7pMRMNHyJo1aUOWEXdSMtTFZmRa7EzHOnRr23szCzLr2J3I0Ilrl59Xm/nDtTkbmQVd8WLAJUfdf6v3JlZpsbC3cTmeFeXO98q7sCDhsvo1ses7mjaMXdVv0ZpiLsr4lb33I1qcjexirvRpRehV8c73VHH3Klwe//n7EWE/hONqR1oqO3drY++8eTOKJjZT9tQaCyaPNiBjBz5iRYECr/XImQ40nedbSPkfdCnmF+TO5X6sQU8/Rclt24XDUcdL9u9qj8bfIAsRW3uXLu4036x6t6aHdMdeR1nx7wWU/pWbxdrg+dZDd7NeQrDkb4BaBu81pL6bh+osysr6+vZsVvXd4ajxtZ34rT8v2BevfzbJfj0Lw==&lt;/diagram&gt;&lt;/mxfile&gt;"><defs/><g><rect x="73" y="0" width="760" height="90" fill="#e1d5e7" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-end; width: 762px; height: 1px; padding-top: 45px; margin-left: -691px;"><div style="box-sizing: border-box; font-size: 0px; text-align: right;" data-drawio-colors="color: rgb(0, 0, 0); "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><div style="text-align: left;">Service<br />Interface<br /></div></div></div></div></foreignObject><text x="71" y="49" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="end">Service...</text></switch></g><rect x="73" y="110" width="760" height="260" fill="#dae8fc" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-end; width: 762px; height: 1px; padding-top: 240px; margin-left: -691px;"><div style="box-sizing: border-box; font-size: 0px; text-align: right;" data-drawio-colors="color: rgb(0, 0, 0); "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><div style="text-align: left;">Core<br />Components</div></div></div></div></foreignObject><text x="71" y="244" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="end">Core...</text></switch></g><rect x="73" y="390" width="760" height="110" fill="#fff2cc" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-end; width: 762px; height: 1px; padding-top: 445px; margin-left: -691px;"><div style="box-sizing: border-box; font-size: 0px; text-align: right;" data-drawio-colors="color: rgb(0, 0, 0); "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><div style="text-align: left;"><span style="background-color: initial;">Platform</span></div><div style="text-align: left;"><span style="background-color: initial;">Configuration</span></div></div></div></div></foreignObject><text x="71" y="449" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="end">Platform...</text></switch></g><rect x="353" y="20" width="120" height="60" fill="#0050ef" stroke="#001dbc" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 50px; margin-left: 354px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: #ffffff; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(255, 255, 255); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">fwu_provider</div></div></div></foreignObject><text x="413" y="54" fill="#ffffff" font-family="Helvetica" font-size="12px" text-anchor="middle">fwu_provider</text></switch></g><rect x="353" y="120" width="120" height="60" fill="#0050ef" stroke="#001dbc" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 150px; margin-left: 354px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: #ffffff; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(255, 255, 255); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">update_agent</div></div></div></foreignObject><text x="413" y="154" fill="#ffffff" font-family="Helvetica" font-size="12px" text-anchor="middle">update_agent</text></switch></g><rect x="353" y="200" width="120" height="60" fill="#0050ef" stroke="#001dbc" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 230px; margin-left: 354px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: #ffffff; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(255, 255, 255); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">fw_store</div></div></div></foreignObject><text x="413" y="234" fill="#ffffff" font-family="Helvetica" font-size="12px" text-anchor="middle">fw_store</text></switch></g><rect x="213" y="300" width="120" height="60" fill="#0050ef" stroke="#001dbc" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 330px; margin-left: 214px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: #ffffff; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(255, 255, 255); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">installer_index</div></div></div></foreignObject><text x="273" y="334" fill="#ffffff" font-family="Helvetica" font-size="12px" text-anchor="middle">installer_index</text></switch></g><rect x="493" y="300" width="120" height="60" fill="#0050ef" stroke="#001dbc" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 330px; margin-left: 494px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: #ffffff; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(255, 255, 255); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">volume_index</div></div></div></foreignObject><text x="553" y="334" fill="#ffffff" font-family="Helvetica" font-size="12px" text-anchor="middle">volume_index</text></switch></g><rect x="193" y="120" width="120" height="60" fill="#0050ef" stroke="#001dbc" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 150px; margin-left: 194px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: #ffffff; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(255, 255, 255); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">fw_directory</div></div></div></foreignObject><text x="253" y="154" fill="#ffffff" font-family="Helvetica" font-size="12px" text-anchor="middle">fw_directory</text></switch></g><rect x="123" y="400" width="80" height="60" fill="#f0a30a" stroke="#bd7000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 430px; margin-left: 124px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">installer</div></div></div></foreignObject><text x="163" y="434" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">installer</text></switch></g><rect x="223" y="410" width="80" height="60" fill="#f0a30a" stroke="#bd7000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 440px; margin-left: 224px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">installer</div></div></div></foreignObject><text x="263" y="444" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">installer</text></switch></g><rect x="323" y="400" width="80" height="60" fill="#f0a30a" stroke="#bd7000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 430px; margin-left: 324px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">installer</div></div></div></foreignObject><text x="363" y="434" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">installer</text></switch></g><rect x="423" y="400" width="80" height="60" fill="#6d8764" stroke="#3a5431" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 430px; margin-left: 424px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: #ffffff; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(255, 255, 255); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">volume</div></div></div></foreignObject><text x="463" y="434" fill="#ffffff" font-family="Helvetica" font-size="12px" text-anchor="middle">volume</text></switch></g><rect x="523" y="420" width="80" height="60" fill="#6d8764" stroke="#3a5431" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 450px; margin-left: 524px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: #ffffff; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(255, 255, 255); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">volume</div></div></div></foreignObject><text x="563" y="454" fill="#ffffff" font-family="Helvetica" font-size="12px" text-anchor="middle">volume</text></switch></g><rect x="623" y="420" width="80" height="60" fill="#6d8764" stroke="#3a5431" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 450px; margin-left: 624px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: #ffffff; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(255, 255, 255); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">volume</div></div></div></foreignObject><text x="663" y="454" fill="#ffffff" font-family="Helvetica" font-size="12px" text-anchor="middle">volume</text></switch></g><rect x="723" y="400" width="80" height="60" fill="#6d8764" stroke="#3a5431" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 430px; margin-left: 724px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: #ffffff; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(255, 255, 255); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">volume</div></div></div></foreignObject><text x="763" y="434" fill="#ffffff" font-family="Helvetica" font-size="12px" text-anchor="middle">volume</text></switch></g><path d="M 413 80 L 413 113.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 413 118.88 L 409.5 111.88 L 413 113.63 L 416.5 111.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 353 150 L 319.37 150" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 314.12 150 L 321.12 146.5 L 319.37 150 L 321.12 153.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 413 180 L 413 193.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 413 198.88 L 409.5 191.88 L 413 193.63 L 416.5 191.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 383 260 L 278.98 297.82" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 274.05 299.62 L 279.43 293.94 L 278.98 297.82 L 281.83 300.52 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 443 260 L 547.02 297.82" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 551.95 299.62 L 544.17 300.52 L 547.02 297.82 L 546.57 293.94 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 243 360 L 168.7 397.15" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 164 399.5 L 168.7 393.24 L 168.7 397.15 L 171.83 399.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 273 360 L 264.25 403.76" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 263.22 408.9 L 261.16 401.35 L 264.25 403.76 L 268.02 402.73 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 311.57 360 L 357.97 396.09" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 362.12 399.31 L 354.44 397.78 L 357.97 396.09 L 358.74 392.25 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 523 360 L 468.3 396.47" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 463.93 399.38 L 467.81 392.58 L 468.3 396.47 L 471.7 398.41 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 553 360 L 561.95 413.72" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 562.82 418.9 L 558.21 412.57 L 561.95 413.72 L 565.12 411.42 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 583 360 L 657.91 416.18" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 662.11 419.33 L 654.41 417.93 L 657.91 416.18 L 658.61 412.33 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 613 360 L 756.85 398.36" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 761.92 399.71 L 754.25 401.29 L 756.85 398.36 L 756.06 394.53 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/></g><switch><g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/><a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank"><text text-anchor="middle" font-size="10px" x="50%" y="100%">Text is not SVG - cannot display</text></a></switch></svg>
\ No newline at end of file
diff --git a/docs/services/index.rst b/docs/services/index.rst
index b479f8b..dee2252 100644
--- a/docs/services/index.rst
+++ b/docs/services/index.rst
@@ -7,12 +7,13 @@
 
     attest-service-description
     crypto-service-description
+    fwu-service-description
     secure-storage-service-description
     block-storage-service-description
     uefi-smm-services
 
 --------------
 
-*Copyright (c) 2020-2022, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2020-2023, Arm Limited and Contributors. All rights reserved.*
 
 SPDX-License-Identifier: BSD-3-Clause
diff --git a/docs/services/uml/FwStoreClassDiagram.puml b/docs/services/uml/FwStoreClassDiagram.puml
new file mode 100644
index 0000000..228c3db
--- /dev/null
+++ b/docs/services/uml/FwStoreClassDiagram.puml
@@ -0,0 +1,104 @@
+'-------------------------------------------------------------------------------
+' Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+'
+' SPDX-License-Identifier: BSD-3-Clause
+'
+'-------------------------------------------------------------------------------
+
+@startuml
+
+ class fw_store
+class bank_tracker
+class metadata_manager
+class metadata_serializer
+class installer_index
+class volume_index
+class installer
+class volume
+
+class bank_tracker {
+	+accept()
+	+copy_accept()
+	+set_no_content()
+	+set_holds_content()
+	+set_holds_acceped_content()
+	+is_content()
+	+is_accepted()
+	+is_all_accepted()
+}
+
+class fw_store {
+	+synchronize()
+	+begin_install()
+	+cancel_install()
+	+finalize_install()
+	+select_installer()
+	+write_image()
+	+commit_image()
+	+notify_accepted()
+	+is_accepted()
+	+is_trial()
+	+commit_to_update()
+	+revert_to_previous()
+	+export()
+}
+
+class metadata_manager {
+	+check_and_repair()
+	+update()
+	+get_active_indices()
+	+preload_bank_tracker()
+}
+
+class metadata_serializer {
+	+serialize()
+	+size()
+	+max_size()
+	+deserialize_bank_info()
+	+deserialize_active_indices()
+}
+
+class installer_index {
+	+register()
+	+find()
+	+get()
+	+get_location_ids()
+}
+
+class installer {
+	+begin()
+	+finalize()
+	+abort()
+	+open()
+	+commit()
+	+write()
+	+enumerate()
+}
+
+class volume_index {
+	+add()
+	+find()
+}
+
+class volume {
+	+open()
+	+close()
+	+seek()
+	+size()
+	+read()
+	+write()
+	+erase()
+	+get_storage_ids()
+}
+
+fw_store -> metadata_manager
+fw_store -> bank_tracker
+fw_store -> installer_index
+fw_store -> volume_index
+metadata_manager -> metadata_serializer
+installer_index -> "*" installer
+volume_index -> "*" volume
+metadata_manager -> "2" volume
+installer ..> volume
+
+@enduml
diff --git a/docs/services/uml/UpdateAgentClassDiagram.puml b/docs/services/uml/UpdateAgentClassDiagram.puml
new file mode 100644
index 0000000..0dad627
--- /dev/null
+++ b/docs/services/uml/UpdateAgentClassDiagram.puml
@@ -0,0 +1,100 @@
+'-------------------------------------------------------------------------------
+' Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+'
+' SPDX-License-Identifier: BSD-3-Clause
+'
+'-------------------------------------------------------------------------------
+
+@startuml
+
+class fw_directory
+class fw_inspector
+class img_dir_serializer
+class stream_manager
+class update_agent
+class fw_store
+class installer
+
+class update_agent {
+	+begin_staging()
+	+end_staging()
+	+cancel_staging()
+	+accept()
+	+select_previous()
+  	+open()
+	+commit()
+	+read_stream()
+	+write_stream()
+}
+
+class fw_directory {
+	+set_boot_info()
+	+add_image_info()
+	+find_image_info()
+	+get_image_info()
+	+num_images()
+}
+
+class fw_inspector {
+	+inspect
+}
+
+class img_dir_serializer {
+	+serialize()
+	+get_len()
+}
+
+class stream_manager {
+	+open_buffer_stream()
+	+open_install_stream()
+	+close_stream()
+	+cancel_streams()
+	+is_open_streams()
+	+read()
+	+write()
+}
+
+class fw_store {
+	+synchronize()
+	+begin_install()
+	+cancel_install()
+	+finalize_install()
+	+select_installer()
+	+write_image()
+	+commit_image()
+	+notify_accepted()
+	+is_accepted()
+	+is_trial()
+	+commit_to_update()
+	+revert_to_previous()
+	+export()
+}
+
+class installer {
+	+begin()
+	+finalize()
+	+abort()
+	+open()
+	+commit()
+	+write()
+	+enumerate()
+}
+
+class installer_index {
+	+register()
+	+find()
+	+get()
+	+get_location_ids()
+}
+
+update_agent -> fw_store
+update_agent -> fw_directory
+update_agent -> fw_inspector
+update_agent -> stream_manager
+update_agent -> img_dir_serializer
+img_dir_serializer ..> fw_directory
+fw_inspector -> installer_index
+fw_inspector ..> installer
+stream_manager ..> installer
+
+@enduml