DRIVE Update V3#

DRIVE Update V3 provides the mechanism and user interface to perform the updates of DRIVE Thor and DRIVE AGX Orin storage from the Drive Update Service. This enables building Software Update Applications based on the DRIVE Update V3 interface to flash all QSPI, eMMC and UFS partitions of Drive Thor and Orin SoC on NVIDIA DRIVE™ AGX Orin Platform.

Terminology#

Name

Description

DU

DRIVE Update

DU plug-in

A component to perform tasks in support of update operations. DU plug-ins are managed by DU Master.

DU Master

A DU plug-in which manages all the other DU plug-ins. A single DU Master can manage multiple Thors/Orins and runs in Guest OS on Orin A. The user can start an update by issuing the command to start deploying a package for update via DU Master interface.

DU TII

DRIVE Update Tegra Image Installer. A DU plug-in running in Guest OS to perform storage update of the Thor/Orin Soc that it is running on. It always updates partitions that belong to the Inactive Chain.

Content Server

A DU plug-in to export update payload and file-based content to be read by other plug-ins. Content Server runs in Guest OS on Orin A. The user can expose the package files to DU Master and DU TII via Content Server interface.

DU Link

The communication protocol among all DU plug-ins, which enables the distributed interconnection among DU plug-ins with file-system-like topology.

DU Link Router

The router to connect DU Link network for interconnection among customer OTA application and DU plug-ins.

DUCC

DRIVE Update Command and Control interface for the user to get DU status, to control and interact with customer OTA application in the user’s OTA solution.

BHC

Boot Health Check. BHC DU plug-in is a validator type plug-in to provide the user with the interface to perform boot health check on the newly updated packages after update.

DU Boot Manager

A DU plug-in that handles bootchain selection and board-level reset on GPIO based bootchain selection board.

Persistent Context Store

A DU plug-in that stores binary content persistent across reboots, including reboots to new bootchains.

DU Authenticator

A DU plug-in of file transform type that authenticates update payload content files.

Metadata

The data file that includes the payload information, a series of commands executed by DU plug-ins.

Active bootchain

The active bootchain is the bootchain from which Thor/Orin successfully boots the currently running system.

Inactive bootchain

The opposite to the active bootchain. This is the chain that is not in use by anything running at the time.

Default bootchain

The default bootchain is the bootchain from which Thor/Orin attempts first to boot up on cold boot.

DU Decompressor

A DU plug-in of file transform type that decompresses update payload content files.

DUS

DRIVE Update server. A native process that runs in HVRTOS to support DRIVE Update activities.

Update Mechanism#

Below diagram shows the DRIVE Update architecture of Thor/Orin platform:

DRIVE Update Architecture

DRIVE Update Architecture#

DU Server Client API is only linked to TII and DRIVE Update Server in the schema. But DU Server Client API is possible to be called by user applications and we have CLI sample tool.

The user can use DUCC interface to control the update behavior, to allow or forbid specific update activities, such as checking the availability of update package, installing update package files. The update package files can be exported to DU Link network via Content Server. When update is allowed and user initiates the update via DU Master command interface, the DU installer plug-ins like DU TII starts to read package files from Content Server and write the update payload to the storage partitions.

Note

  • Content Server is provided as a sample application and is not packaged into the filesystem of Guest OS. User can use it for development purpose, or as a reference to implement his own content provider plug-in

Below diagram shows the DRIVE Update architecture of Thor/Orin platform when Drive Update Server Client API is directly used:

Drive Update Server

Drive Update Server#

Alternatively, Customer could develop their OTA App directly using Drive Update Server Client API. Such approach could be chosen in case additional features provided by Drive Update are not required.

Note

DU CLI tool is provided as a sample application to call Drive Update Server Client API directly. It’s not packaged into the filesystem of Guest OS. User can use it for development purpose, or as a reference to implement his own OTA app.

Storage Partitions#

The storage is divided into two bootchains (e.g. A and B) and persistent partitions outside the bootchains.

  • The size and configuration of these blocks is referred to as “first level” partitions (L1PT).

  • Each bootchain is further subdivided into smaller partitions referred to as “second level” partitions (L2PT).

    • The second level partition contains the Guest OS, file system and DRIVE Update partition.

  • The currently booted bootchain is referred to as the Active bootchain.

  • Persistent partitions are accessible by either bootchain while they are active and allows for persistent data (e.g. user info, vehicle configuration) to be accessible from either bootchain.

DRIVE Update provides the mechanism and user interface to update each bootchain. The typical update sequence is to update the inactive partition from the active partition followed by a reboot to the updated partition. This sequence allows for updating each bootchain without affecting the persistent partitions.

Note

  • In the event that the boothchains or persistent partitions needs to be resized, then a repartition is required.

  • Resizing of the first level partition is a destructive process and data in the storage is erased.

  • Resizing of the first level partition is not supported in safety builds.

  • DRIVE Update does not support updating the active boot-chain content or data partitions used by actively running software.

  • DRIVE Update can only update the storage used by Tegra SoC software on which it is running.

  • DRIVE Update does not support updating of non-Tegra software (e.g. MCU, VBIOS).

DRIVE Update Package#

DRIVE Update package consists of the following:

  • DU Master metadata

  • Content metadata

  • Authenticator metadata

  • Decompressor metadata

  • Boot Manager metadata

  • Payload of other DU plug-ins, including:

    • DU TII payload consists of TII metadata and image files of SoC storage partitions.

For the content and syntax of metadata, see DRIVE Update Metadata for more information.

DU TII image files can be generated with the create_bsp tool. For more information, see Generating Flashing Binaries Offline in this guide document.

The following figure shows the organization of DRIVE Update package files when using the sample Content Server:

DRIVE Update Package Organization

DRIVE Update Package Organization#

Note

The above diagram does not show the payload of Authenticator and Decompressor.

DRIVE Update Package Tool (DUPKG)#

DRIVE Update Packaging Tool (DUPKG) is a command line tool which can be used to generate DRIVE Update package.

Overview#

Below picture shows the design in action, for generating a DRIVE Update Package containing partition images.

DUPKG Generation Action

DUPKG Generation Action#

Installing the DUPKG Tool#

Note

  • Dockers released by DRIVE Platform team have DUPKG Utility pre-installed in the docker’s root filesystem.

  • This step is needed only if you want to run DUPKG from outside the released/tested docker environment.

The tool is provided as a Python3 source code package that can run on the host machine

The Python3 source code package can then be installed with the following command:

cd /drive/drive-foundation/tools/driveupdate/dupkg
python3 setup.py build
sudo python3 setup.py install

Steps to Generate Package#

Note

  • If generating DU packages of PDK, then the images need to be generated prior to calling the DUPKG tool.

  • When generate the DU Package and found the error “ModuleNotFoundError: No module named ‘tabulate’”, try to install the ‘tabulate’ module with the command: sudo apt install python3-tabulate.

  • When generate the Authenticator DU Package and found the error “ImportError: cannot import name ‘pss’ “, try to install the pycryptodome with the command: pip3 install pycryptodome.

  1. List all the installed templates (python3 dupkg.py lstemplate).

  2. List all the required input variables to be provided for generating packages (python3 dupkg.py lsin).

  3. Generate package (python3 dupkg.py gen).

List all the installed templates#

All the installed templates can be listed with the help of lstemplate command.

python3 dupkg.py lstemplate

lstemplate example

$ python3 dupkg.py lstemplate
DRIVE Update Packaging Tool
Version 1.5.0

List of installed templates are:

Some templates are hidden, use --all to show all templates.

 Template                        | Description
---------------------------------+--------------------------------------------------------------------------------------------------------------------------------
 dupkg_cli_update_template       | CLI Update in 7.0 release
 dupkg_clone_template            | Single Tegra update both chains with clone on GPIO based bootchain selection
 dupkg_dual_tegra_template       | Dual Tegra update with GPIO based bootchain selection
 dupkg_ducompressor_template     | Single Tegra GPIO update with compression
 dupkg_install_bch_template      | Delta update for Boot Component Header
 dupkg_l1pt_repartition_template | L1PT update with repartition and reboot
 dupkg_only_install_template     | Single Tegra install only for inactive chain and recovery chain, without others action such as reboot, set_default_chain, etc.
 dupkg_push_template             | Single Tegra update with PUSH mode on GPIO based bootchain selection
 dupkg_recovery_template         | Single Tegra GPIO update for chain C only, discard emmc is by default
 dupkg_revoke_key_template       | Single Tegra update for revoke key
 dupkg_sample_template           | Template for sample_installer plugin package generation
 dupkg_sign_template             | Sign the DUPKG with private key or tegrasign
 dupkg_single_tegra_template     | Single Tegra update with GPIO based bootchain selection
List the required input variables#

The required input variables are dependent on the template used. To list all the required input variables, pass the template by calling the following command.

python3 dupkg.py lsin --template TEMPLATE_NAME / path_to_TEMPLATE_NAME
lsin arguments
  • –template TEMPLATE : Template name or path

Note

If only the template name is mentioned without any path, then the installed template is taken as input. If ‘./’ is mentioned prior to the template then the template in the path provided is considered.

User shall perform all applicable safety and security assessments for the DU Packages generated using external templates. DRIVE Update has no visibility on external templates. Therefore, user will be at a better position to assess the impact of using external templates in the term of safety and security.

lsin example

$ python3 dupkg.py lsin --template dupkg_single_tegra_template
DRIVE Update Packaging Tool
Version 1.5.0

List of all the variables that need to be provided as input while generating packages:

 Input Variable       | Req / Opt   | Description
----------------------+-------------+-----------------------------------------------------------------------------------------------
 TEGRA_A_SRC          | Required    | Path to folder containing Tegra images, filesToFlash.txt
 VALIDATE_OPTION      | Optional    | If enable validate command [True | False]
 ERASE_PADDING_FLAG   | Optional    | If enable erase padding [0 | 1]
 AUTHENTICATOR_OPTION | Optional    | Set "AuthPkg" if enable Authenticator, Default is NormalPkg
 PRIVATE_KEY_PATH     | Optional    | The path to private key file. Required if enable Authenticator
 TEGRASIGN_PATH       | Optional    | The path to the tegrasign_v3.py tool in the PDK. Required if enable Authenticator and use HSM
 SHA_ALG              | Optional    | The SHA algorithm using for validation. Default is SHA256
 CHAIN                | Optional    | The chain option for update, optional: recovery/A/B. Default is empty
 DISCARD_EMMC_FLAG    | Optional    | If erase the emmc chain [True | False]
 INSTALL_BRBCT        | Optional    | If install brbct [True | False]
 OS_VERSION           | Optional    | The OS version of images to generate DU package. Default is 6.0.8.0
Generate package#

Once all the required input variables are listed, generate the package by passing the path to all the input variable and template as follows:

python3 dupkg.py gen --template NAME/PATH_OF_TEMPLATE --in REQ_VAR1=/path/to/value1 REQ_VAR2=/path/to/value2 --out /path/to/output/
gen arguments
  • –in VAR=VAL [VAR=VAL …​] : Required input varaiables and its value (use python3 dupkg.py lsin to list the required input variables)

  • –out OUT : Output folder for package

  • –template TEMPLATE : Template name or path

gen example

$python3 dupkg.py gen --in TEGRA_A_SRC=./bsp_images/642-63960-0010-000_TS1/flash-images/ --template $TEMPLATE --out ./out_new

DRIVE Update Packaging Tool
Version 1.5.0

Generating packages... | (output size: 394874K)
Support HSM (Hardware Security Module)#

DUPKG Tool supports generating the Authenticator DU Package with HSM.

Check the input variables from dupkg templates, there are three variables to enable HSM:

  • AUTHENTICATOR_OPTION : Authenticator option, should be AuthPkg

  • Input the full path to the private key file to “PKC_KEY” in /drive/drive-foundation/tools/flashtools/flash/tegrasign_v3_debug.yaml, for example:

{"HSM":
    {
        ....
        "PKC_KEY"     : "<PRIVATE_KEY_PATH>",
        ....
  • TEGRASIGN_PATH : Input the full path to the tegrasign_v3.py. Please find this file in the release PDK. for example: /drive/drive-foundation/tools/flashtools/flash/tegrasign_v3.py.

Either PRIVATE_KEY_PATH or TEGRASIGN_PATH is required to sign the key. And AUTHENTICATOR_OPTION needs to be set as AuthPkg in general for authentication.

DUPKG templates that support HSM:

  • dupkg_clone_template

  • dupkg_compat_template

  • dupkg_dual_tegra_template

  • dupkg_ducompressor_template

  • dupkg_install_bch_template

  • dupkg_only_install_template

  • dupkg_push_template

  • dupkg_single_tegra_template

gen example

TEGRA_A_SRC=${BSP}/642-63960-0010-000_TS1/flash-images
AUTHENTICATOR_OPTION=AuthPkg
TEGRASIGN_PATH=/drive/drive-foundation/tools/flashtools/flash/tegrasign_v3.py
OUTPUT_FOLDER=${DU_PACKAGE}/hsm_gpio_pull_$(date '+%m%d')
TEMPLATE=dupkg_single_tegra_template

python3 dupkg.py gen --in VALIDATE_OPTION=True TEGRA_A_SRC=$TEGRA_A_SRC AUTHENTICATOR_OPTION=$AUTHENTICATOR_OPTION TEGRASIGN_PATH=$TEGRASIGN_PATH --template $TEMPLATE --out $OUTPUT_FOLDER

gen result

DRIVE Update Packaging Tool
Version 1.5.0

Generating packages...  Done

DRIVE Update Metadata#

Note

This section does not describe the Metadata of Authenticator. Please refer to Authenticator HOWTO for more information.

Content metadata#

The content metadata file is consumed by content provider plug-in, which is Content Server in this example. The file name must be list_of_files.json. It lists all the package files to be deployed. Each file or directory can be defined by a pair of keys in the following table:

Key

Description

name

The relative path to the location of list_of_files.json file.

type

Use “file” for a normal file, and “dir” for a directory.

The following is a sample list_of_files.json to list all the package files for the example package format in section DRIVE Update Package.

list_of_files.json

[
    {
        "name": "./",
        "type": "dir"
    },
    {
        "name":"./du_master.json",
        "type":"file"
    },
    {
        "name":"./list_of_files.json",
        "type":"file"
    },
    {
        "name":"./tii-a",
        "type":"dir"
    },
    {
        "name":"./tii-a/metadata.json",
        "type":"file"
    },
    {
        "name":"./tii-a/A_1_3_kernel_zerosign.img",
        "type":"file"
    },
    {
        "name":"./tii-a/A_bct_MEM_zerosign.bct",
        "type":"file"
    },
    {
        // other Thor/Orin-A package files
    },
    {
        "name":"./tii-b",
        "type":"dir"
    },
    {
        "name":"./tii-b/tii-image-metadata.json",
        "type":"file"
    },
    {
        "name":"./tii-b/B_bct_MEM_zerosign.bct",
        "type":"file"
    },
    {
        "name":"./tii-b/B_4_spe_zerosign.bin",
        "type":"file"
    },
    {
        // other Orin-B package files
    },
    {
        "name":"./reboot.json",
        "type":"file"
    },
    {
        "name":"./set_default_chain.json",
        "type":"file"
    },
]

Note

For a single Thor/Orin platform, please remove the ./tii-b directory and ./tii-b/* files from list_of_files.json

DU Master metadata#

DU Master metadata contains all required actions for an update. It is the input parameter of DU master “deploy” command. Each DU plug-in being managed by DU Master may in turn deploy its own metadata file using whatever format each plug-in itself requires via the “deploy” command.

Note

  • The metadata file must be manually composed with the specified syntax as defined in below sections.

  • Validate and ensure the correctness of the file.

Syntax#

DU Master metadata contains the following sections in the top level.

Key

Description

metaVersion

Integer version number for the metadata file. It is used by DU Master to perform compatibility check.

restoreSequence

Define the context restoring sequence of DU plug-ins when a package deployment is resumed on system boot. This section is optional, and DU Master will use the pre-defined restore sequence if the section is not present.

actions

Array containing all default actions to be executed by DU Master. Each action must provide details for an action object as provided in the table below.

Note

The value of metaVersion should be 3 for this release. The value of the version number may increase if additional features are added in future versions of the metadata.

Below is the syntax of an action object in the “actions” array.

Key

Mandatory

Description

actionId

Yes

Unique integer index for an action starting from zero.

description

No

Description of the action command being run, used for debugging purposes only.

gatedBy

No

List of actions which gate this action from being executed. The action does not run until all actions in this list are complete.  If array is empty or the field is omitted entirely then there are no actions gating the action.

pluginType

Yes

Type of DU plug-in. It is “installer” for DU TII, and “validator” for BHC plug-in.

pluginPath

Yes

DU Link path of DU plug-in root.

cmd

Yes

Command string to send to worker DU plug-in. For example, “deploy metadata=</path/to/metadata_file>”.

startOnState

Yes

List of possible states a plug-in may be in before deploying the action.

exitOnStateTransitionTo

Yes

List of possible states a plug-in may transition to which will signal action is complete.

failOnStateTransitionTo

Yes

List of possible states a plug-in may transition to which will signal action has failed and plug-in is in error state.

onFail

No

Define the name of the set of actions to be executed on the failure of this action item. See Switch Back On Failure of Post Installation Check for more details.

logOnStart

No

Optional logging field to provide more information on update, the string provided here would be logged once this action has been started. The log can be read from “/master/persistent_log.list”

logOnExit

No

Optional logging field to provide more information on update, the string provided here would be logged once this action has been finished. The log can be read from “/master/persistent_log.list”

logOnFail

No

Optional logging field to provide more information on update, the string provided here would be logged once this action has been failed. The log can be read from “/master/persistent_log.list”

Note

There is no confidentiality in the Master supported logOn command logs.

In order to mitigate this, the user must not pass any information that is deemed to be sensitive/confidential, such as Critical Security Parameters, or Personally Identifiable Information.

Example#

The following is a simple example to demonstrate how to fill the value of keys in DU Master metadata:

du_master_metadata.json

{
    "metaVersion": 3,
    "restoreSequence": [
        "*/ddu",
        "*/du-client",
        "*/content",
        "/tii",
        "/bhc",
        "/bootmgr"
    ],
    "actions": [
        {
            "actionId": 0,
            "description": "Deploy images to TA",
            "gatedBy": [],
            "pluginType": "installer",
            "pluginPath": "/tii",
            "startOnState": [
                "IDLE"
            ],
            "exitOnStateTransitionTo": [
                "IDLE"
            ],
            "failOnStateTransitionTo": [
                "ERROR"
            ],
            "logOnStart": "Start Deploy images to TA",
            "logOnExit": "TA images updated",
            "logOnFail": "Failed to deploy images to TA",
            "cmd": "deploy metadata=$CONTENT_ROOT$/tii-a/metadata.json"
        }
    ]
}

Note

  • The above metadata file contains only one action object to install Thor/Orin-A images, and the update package files are exported via content_server.

  • The “pluginType” must be set correctly. It is “installer” for TII to install Thor images.

  • The “pluginPath” must be “/gos-b/tii” if the action object installs Thor/Orin-B images.

  • Always follow the above example to configure the key values of “startOnState”, “exitOnStateTransitionTo” and “failOnStateTransitionTo” for TII.

  • “logOnStart”, “logOnExit” and “logOnFail” show the log of each step respectively in /master/persistent_log.list.

  • The metadata path $CONTENT_ROOT$ is a variable that represents the value of “content_root” parameter of “deploy” command written to DU Master interface /master/cmd. Alternatively, you can use the path value directly according to your configuration. For instance, /content/files/ if content_server is used to export the package files. Note that it is the path in DU Link network, but not the actual location where the package files are in the physical file system.

  • The section “restoreSequence” defines a list of DU plug-ins which DU Master needs to wait until their context is restored in order before resuming the deployment. The “*” before the plug-in path means that the plug-in will be checked by DU master only if it is registered previously during the deployment.

  • The pre-defined restoreSequence is “/bhc”, “/tii”.

The following is the example du_master.json which contains multiple action objects to deploy Thor/Orin on the platform with Marker based bootchain selection mode.

du_master.json

{
    "metaVersion": 3,
    "restoreSequence": [
        "*/ddu",
        "*/du-client",
        "*/content",
        "/tii"
    ],
    "actions": [
        {
            "actionId": 0,
            "description": "Deploy images to TA",
            "gatedBy": [],
            "pluginType": "installer",
            "pluginPath": "/tii",
            "startOnState": ["IDLE"],
            "exitOnStateTransitionTo": ["IDLE"],
            "failOnStateTransitionTo": ["ERROR"],
            "logOnStart": "Start Deploy images to TA",
            "logOnExit": "TA images updated",
            "logOnFail": "Failed to deploy images to TA",
            "cmd" : "deploy metadata=$CONTENT_ROOT$/tii-a/metadata.json"
        },
        {
            "actionId": 1,
            "description": "Set default chain on TA",
            "gatedBy": [0],
            "pluginType": "installer",
            "pluginPath": "/tii",
            "startOnState": ["IDLE"],
            "exitOnStateTransitionTo": ["IDLE"],
            "failOnStateTransitionTo": ["ERROR"],
            "logOnStart": "Setting default chain to new image",
            "logOnExit": "Default chain is set, Please reboot manually",
            "cmd" : "deploy metadata=$CONTENT_ROOT$/tii-a/set_default_chain.json"
        }
    ]
}

Note

  • The action object to set_default_chain.json is gated by action objects to update Thor/Orin partitions. It is defined by “gatedBy” key value.

  • The Du master does not store the .json file deployed to it. Thus, if a reboot occurs, which is commonly done during an install, the details of the install will not be available on reboot. To rememdy this, the content server which provided the json must be available upon reboot in order for du master to continue or abort. Failure to provide the json will ultimately lead to driveupdate to time out after several minutes, requiring a deploy to be restarted. Until this timeout occurs, an abort cannot be issued without providing the json file

  • Du master supports maximum 65 actions written in .json

Boot Manager metadata#

There are two metadata files, which are composed of a series of commands executed by DU Boot Manager to perform bootchain selection or board reset.

Syntax#

DU Boot Manager metadata contains the following sections in the top level.

Key

Description

magic

A string to identify the owner of the metadata. Must be “NVDU-BOOTMGR”.

metaVersion

Integer version number for the metadata file. The current supported version is 1.

procedure

The series of commands to be executed by DU Boot Manager.

Below is the list of supported commands in the “procedure” section.

Command

Description

reboot

This command reboots one Thor/Orin to the specified bootchain. The run level should be RL_FULL_APPLY and higher for this command. It’s not recommended to use this command on dual-Tegra hardware as this would potentially lead to bootchain insistency. Please use board_reset command on such system.

set_default_chain

This command sets the default bootchain of one certain Thor/Orin.

board_reset

This command triggers board level reset. It can specify a certain bootchain which Thor/Orin will boot into. The run level should be RL_FULL_APPLY for this command.

The arguments for reboot are as follows:

Arguments

Description

cmd

Command to reboot is “reboot”.

chip_id

Specify which Thor/Orin chip to reboot. 0 for Thor/Orin-A and 1 for Thor/Orin-B. It’s not recommended to use this command to reboot Thor/Orin-B only.

target_bootchain

Set the bootchain from which Tegra boots on reboot command:

  • “default”: reboots from the default bootchain.

  • “active”: remains the current active bootchain.

  • “inactive”: reboots from the inactive bootchain.

This command does not change the default bootchain

delay

Optional parameter. Wait time before actual system reboot. The default delay is 2 seconds. This parameter, if set, should be at least 1 for DRIVE Update to save its context correctly. The maximum value for this parameter is 5 seconds.

The arguments for set_default_chain are as follows:

Arguments

Description

cmd

Command to set default chain is “set_default_chain”.

chip_id

By default in Thor/Orin there is one Tegra-a and the ID is 0. If on dual-Tegra hardware the ID could be 0 and 1.

target_bootchain

Set the current “active” or “inactive” bootchain as the default bootchain, from which Thor/Orin will boot on next cold boot. This command does not trigger board reset or Thor/Orin reboot.

The arguments for board_reset are as follows:

Arguments

Description

cmd

Command to board_reset is “board_reset”.

target_bootchain

The same semantics as that of reboot command.

delay

The same semantics as that of reboot command.

Note

Boot Manager interface works only with GPIO bootchain selection mode. For the platforms with Marker based bootchain selection mode, please use the DU TII Metadata command set_default_chain.

It is assumed that the user of DRIVE Update will update which switch bootchain selection method (Marker based to GPIO based) to be deployed, independently of software updates and, at minimum, a version with working Boot Manager and a compatible MCU firmware must be flashed on both bootchains a priori.

Boot Manager is a plug-in of installer type. User can trigger the execution of Boot Manager Metadata by adding it as an action object into DU Master Metadata, as the following example:

The following is a sample metadata file to triggering board reset and Thor/Orin booting into the inactive bootchain:

reboot.json

{
    "magic": "NVDU-BOOTMGR",
    "metaVersion": 1,
    "procedure": [
        {
            "cmd": "board_reset",
            "target_bootchain": "inactive"
        }
    ]
}

Configuring Default Bootchain Example#

The following is a sample metadata file to configure the default bootchain:

set_default_bootchain.json

{
    "magic": "NVDU-BOOTMGR",
    "metaVersion": 1,
    "procedure": [
        {
            "cmd": "set_default_chain",
            "chip_id": 0,
            "target_bootchain": "active"
        }
    ]
}

DU TII metadata#

The metadata file is composed of a series of commands executed by DU TII to flash binaries into their respective partitions. The partition and binary information referred to can be found in FileToFlash.txt and (grouped_partitions.txt) generated by the create_bsp_images.sh script.

There are two types of partitions: grouped and ungrouped. All the partitions in the same group must be updated together. The grouped_partitions.txt file lists all the grouped and ungrouped partitions.

Syntax#

DU TII metadata contains the following sections in the top level.

Key

Description

metaVersion

Integer version number for the metadata file. It is used by DU TII to perform compatibility check. The current version is 2.

procedure

A series of commands executed by DU TII.

The supported commands in cmd field of procedure section are described in the following sections.

Bootchain Management Commands#

The following commands are for bootchain management.

Command

Description

install_lock

This command locks the inactive bootchain. Mark a chain to invalid.

install_unlock

This command unlocks the inactive bootchain after update is completed. It must be used before switching to the inactive bootchain. When writing data to a chain’s partition, the chain will be disabled, install_unlock will check and enable a chain. Note that locking and unlocking is expected to be done for the entire update.

discard

This command enable to discard the partition. It should be used before the image deployment.

set_default_chain

Set the default bootchain in BRBCT which Tegra boots from on cold boot. It can be used to switch bootchain by specifying “inactive” as the value of “target_bootchain”.

The arguments for install_lock are as follows:

Arguments

Description

chain

Optional parameter. Identifies the chain of the partition, can be “A”, “B”, “recovery”.

The arguments for install_unlock are as follows:

Arguments

Description

chain

Optional parameter. Identifies the chain of the partition, can be “A”, “B”, “recovery”. if this argument is not specified, then will take it as inactive chain, if active chain is chain A, inactive chain is B, else inactive chain is A.

The argument for discard is as follows:

Arguments

Description

partition_name

The partition name to be discarded.

Note

  • Discard only for EMMC/UFS partition in inactive chain.

  • Discard doesn’t erase all the content of the partition to 0.

  • Please update l2pt and l3pt before any install_*_images if you have discard full inactive chain or L3 container.

The arguments for set_default_chain are as follows:

Arguments

Description

target_bootchain

Set the current “active” or “inactive” bootchain as the default bootchain in BR BCT, from which Tegra will boot on next cold boot.

a_brbct_path

Identifies the filename of the chain A BR BCT binary found in FileToFlash.txt.

b_brbct_path

Identifies the filename of the chain B BR BCT binary found in FileToFlash.txt.

customer_data

Optional parameter. Whether to update unsigned customer data. if this argument is not specified, take it as 0.

  • “0”: do not update unsigned customer data

  • “1”: update unsigned customer data

Note

  • The DU TII metadata commands set_default_chain should be used only on the platform with Marker based Bootchain selection mode.

  • customer_data parameter is only effective in standard build.

  • signed section of customer_data would always be updated.

Installation Commands#

The following commands are for installation of partitions.

Command

Description

install_l1_images

Install the binaries for the partitions in the first level partition table except the following partitions:

  • BR BCT

  • PT partition

  • L2 container partitions

install_l2_images

Install the binaries for the partitions in the second level partition table except the PT partitions and L3 container partitions.

install_l3_nvpt_images

Install the binaries for the partitions in the third level partition table except the PT partitions.

install_l3_gpt_images

Install the binaries for the partitions in the third level partition table except the PT partitions.

install_l1_pt

Installs the first level PT binary.

install_l2_pt

Installs the second level PT binary.

install_l3_nvpt

Installs the third level PT binary of default DriveOS configuration.

install_l3_gpt

Install the third level GPT binary.

install_brbct

Update BRBCT partition. This command should be used only on the platform using GPIO bootchain selection mode.

install_bch

Update the bch of a partition. This command should be not used for the partitions in L1PT.

The arguments for install_l1_images are as follows:

Arguments

Description

partition_type

  • “single”: update an ungrouped partition.

  • “group”: update the grouped partitions in the same group.

img_group

Required only if partition_type is “group”. Identifies the grouped partitions to flash. All the groups are listed in grouped_partitions.txt.

Each partition in this group is defined by the arguments partition_name and img_fname arguments, with erase_pad_flag and img_type arguments for advanced configurations. An example is provided in the Example Metadata File.

erase_pad_flag

A partition may not be fully filled with its image content when the image size is less than the partition size. This argument provides an option to pad the partition space which is not filled with its image.

  • “0”: do not pad

  • “1”: pad with the erased value of the partition

img_type

  • “full”: The original image file enerated by the create_bsp_images.sh script.

  • “delta”: The image file is a delta image.

partition_name

Identifies the name of the QSPI/eMMC/UFS partition to flash, For example, kernel.

  • Do NOT add chain label A_ or B_ or C_ as the prefix of the partition name.

  • DRIVE Update always updates the partitions in the inactive chain.

img_fname

Identifies the filename of the binary to flash found in FileToFlash.txt.

Note

Only can use install_l1_images to update the L1 partition with write permission given to du server.

The arguments for install_l2_images are as follows:

Arguments

Description

partition_type

The same semantics as that of install_l1_images command.

img_group

The same semantics as that of install_l1_images command.

erase_pad_flag

The same semantics as that of install_l1_images command.

img_type

The same semantics as that of install_l1_images command.

partition_name

The same semantics as that of install_l1_images command.

img_fname

The same semantics as that of install_l1_images command.

chain

Optional parameter. Identifies the chain of the partition. if this argument is not specified, then will take it as inactive chain, if active chain is chain A, inactive chain is B, else inactive chain is A.

  • “A”: chain A

  • “B”: chain B

  • “recovery”: recovery chain

Note

Please do not use install_l1_images command to update l2 container partitions, or use install_l2_images command to update l3 container partitions.

This may lead to unable to unlock inactive bootchain

Note

Only can use install_l1_images to update the L1 partition with write permission given to du server.

The arguments for install_l3_nvpt_images are as follows:

Arguments

Description

container_pname

The container partition name of this level 3 partiion. Container name can be obtained in level 2 PCT config file boot_chain_storage_qspi.cfg.

partition_type

The same semantics as that of install_l1_images command.

erase_pad_flag

The same semantics as that of install_l1_images command.

img_group

The same semantics as that of install_l1_images command.

img_type

The same semantics as that of install_l1_images command.

partition_name

The same semantics as that of install_l1_images command.

img_fname

The same semantics as that of install_l1_images command.

chain

Optional parameter. Identifies the chain of the partition. if this argument is not specified, then will take it as inactive chain, if active chain is chain A, inactive chain is B, else inactive chain is A.

  • “A”: chain A

  • “B”: chain B

  • “recovery”: recovery chain

The arguments for install_l3_gpt_images are as follows:

Arguments

Description

container_pname

The container partition name of this level 3 partiion. Container name can be obtained in level 2 PCT config file boot_chain_storage_qspi.cfg.

partition_type

The same semantics as that of install_l1_images command.

erase_pad_flag

The same semantics as that of install_l1_images command.

img_group

The same semantics as that of install_l1_images command.

img_type

The same semantics as that of install_l1_images command.

partition_name

The same semantics as that of install_l1_images command.

img_fname

The same semantics as that of install_l1_images command.

Note

When add a new partition, please do not use a partition name end with “_pt”.

The arguments for install_l1_pt are as follows:

Arguments

Description

pt_path

Identifies the filename of the first level PT binary found in FileToFlash.txt.

copy_index_bch

Optional parameter. The index of the source L1PT copy to be update its bch, should be 0 ~ 1, this will be used in revoke key in Thor and L1PT can be changed in this case.

repartitioning

  • “0”: Request DRIVE Update to update the first level PT binary directly without repartitioning procedure. It can be used only if L1PT layout is not changed.

  • “1”: Indicate DRIVE Update that the first level PT binary is different from the content in the partition, and should be updated by the repartitioning procedure. Please note that, L1PT repartitioning is supported only when system is booted in Chain C.

Note

  • Repartitioning is required when resizing the overall bootchain size for A and B partitions.

    • When repartitioning is required, it must be started from bootchain C.

    • Please make sure Chain C can access Chain A and B after L1PT update that means.

    • Some essential information includes but not limited to ivc number for Chain A and B can not be changed.

  • Please do not use the install_l1_pt command to update the first level PT unless the L1PT image is different from the current content in L1PT partition.

  • Safety build does not support L1PT update.

  • L1PT is defined as per global_storage_qspi.cfg. L1PT needs to be updated if changes occur in global_storage_qspi.cfg. It would cause L1PT layout change if partition size changes, or any L2 partitions with “A_” or “B_” prefix in the name is removed or added in global_storage_qspi.cfg. L1PT layout won’t change if only some of the attributes are changed.

  • It is the user’s responsibility to set the correct value of “repartitioning” argument, otherwise it may lead to failure of update, or brick the device.

  • Repartitioning is not power fail safe and not safety compliant.

The arguments for install_l2_pt are as follows:

Arguments

Description

partition_name

Identifies the name of the level 2 pt in FileToFlash.txt. Do NOT add chain label A_ or B_ as the prefix of the partition name.

img_fname

Identifies the filename of the second level PT binary found in FileToFlash.txt.

chain

Optional parameter. Identifies the chain of the partition. if this argument is not specified, then will take it as inactive chain, if active chain is chain A, inactive chain is B, else inactive chain is A.

  • “A”: chain A

  • “B”: chain B

  • “recovery”: recovery chain

The arguments for install_l3_nvpt are as follows:

Arguments

Description

container_pname

Container partition name of default level 3 PT, defined in the level 2 PCT config file boot_chain_storage_qspi.cfg.

img_fname

Identifies the filename of the second level PT binary found in FileToFlash.txt.

chain

Optional parameter. Identifies the chain of the partition. if this argument is not specified, then will take it as inactive chain, if active chain is chain A, inactive chain is B, else inactive chain is A.

  • “A”: chain A

  • “B”: chain B

  • “recovery”: recovery chain

The arguments for install_l3_gpt are as follows:

Arguments

Description

container_pname

Container partition name of GPT.

prim_gpt_fname

Identifies the filename of the image of primary partition table.

sec_gpt_fname

Identifies the filename of the image of secondary partition table.

The arguments for install_brbct are as follows:

Arguments

Description

img_fname

The filename of the image of BRBCT partition.

customer_data

Optional parameter. Whether to update unsigned customer data. if this argument is not specified, take it as 0.

  • “0”: do not update unsigned customer data

  • “1”: update unsigned customer data

Note

  • customer_data parameter is only effective in standard build.

  • signed section of customer_data would always be updated.

The arguments for install_bch are as follows:

Arguments

Description

img_fname

The filename of the image of BRBCT partition.

partition_name

Identifies the name of the QSPI/eMMC/UFS partition to flash, For example, kernel.

pre_hash

The hex string of SHA-256 or SHA-512 (base on hash_algorithm) hash value before the bch updated.

pos_hash

The hex string of SHA-256 or SHA-512 (base on hash_algorithm) hash value after the bch updated.

hash_algorithm

The algorithm used to calculate hash. “sha256” and “sha512” are supported.

Validation Commands#

The following commands are for partition validation after installation.

Command

Description

validate_l1_images

Validate the partition in the first level PT. BR BCT cannot be validated with this command.

validate_l2_images

Validate the partition in the second level PT.

validate_l3_nvpt_images

Validate the partition in the third level PT of default DriveOS configuration.

validate_l3_gpt_images

Validate the partition in the third level GPT.

validate_l2_pt

Validate the second level PT.

validate_l3_nvpt

Validate the third level PT of default DriveOS configuration.

validate_l3_gpt

Validate the third level GPT.

The arguments for validate_l1_images, validate_l2_images, validate_l3_nvpt_images, validate_l3_gpt_images, validate_l1_pt, validate_l2_pt and validate_l3_nvpt are as follows:

Arguments

Description

container_pname

Container partition name of GPT. This argument is required by validate_l3_nvpt and validate_l3_gpt_images command only.

partition_name

The name of the partition to be validated.

data_size

DRIVE Update validates the partition as two parts:

  • For data from partition start address to the offset of (data_size - 1), hash of the partition content would be calculated with the algorithm specified by “hash_algorithm” argument, and compared against the hash value specified by “hash” argument.

Usually, the image size of the partition is used here to validate the update of the whole image.

hash_algorithm

The algorithm used to calculate hash. “sha256” and “sha512” are supported.

hash

The hex string of SHA-256 or SHA-512 (base on hash_algorithm) hash value.

chain

Not required by validate_l1_images, validate_l3_gpt_images and validate_l1_pt, optional parameter in validate_l2_images, validate_l3_nvpt_images, validate_l2_pt and validate_l3_nvpt. Identifies the chain of the partition. if this argument is not specified, then will take it as inactive chain, if active chain is chain A, inactive chain is B, else inactive chain is A.

  • “A”: chain A

  • “B”: chain B

  • “recovery”: recovery chain

The arguments for validate_l3_gpt are as follows:

Arguments

Description

container_pname

Container partition name of GPT.

hash_prim_gpt

The hex string of SHA-256 or SHA-512 (base on hash_algorithm) hash value of the primary partition table.

hash_sec_gpt

The hex string of SHA-256 or SHA-512 (base on hash_algorithm) hash value of the secondary partition table.

hash_algorithm

The algorithm used to calculate hash. “sha256” and “sha512” are supported.

Bootchain Clone Commands#

DRIVE Update supports cloning active partitions to inactive bootchain directly. Below table defines all the DU TII metadata commands for bootchain clone.

Command

Description

clone_bootchain

Clone the entire active bootchain to the inactive bootchain. This command does not have any argument.

clone_l2_pt

Clone the second level PT from active chain to inactive chain.

clone_l3_nvpt

Clone the third level PT of default DriveOS configuration from active chain to inactive chain.

clone_l3_gpt

Clone the third level GPT from active chain to inactive chain.

clone_l2_images

Clone the partitions in the second level partition table except the PT partitions.

clone_l3_nvpt_images

Clone the partitions in the third level partition table.

clone_l3_gpt_images

Clone the partitions in the third level GPT.

replicate_brbct

In Orin, replicate a certain BRBCT copy to all the other copies (if the argument dst_bct_index is not exist) or to a special copy (if the argument dst_bct_index is exist). In Thor, this is to clone active brbct to inactive brbct. This command is used only when BRBCT copies are different in the case of asymmetric bootchain.

Note

  • The clone commands are only guaranteed to work with read-only partitions.

  • Partitions in the first-level PT cannot be cloned.

  • The clone commands work only when the active chain is A or B:

    1. When the active chain is A, it clones from A chain to B chain

    2. When the active chain is B, it clones from B chain to A chain

  • The clone commands do not need validation commands to validate if the data is written correctly, as DRIVE Update will automatically perform read-back-verify during the clone operation.

  • Users should ensure no write operations occur on the read-write partitions during the clone procedure; otherwise, it could result in failures during partition validation.

  • The command clone_bootchain will clone the entire image from the active chain to the inactive chain. See the section Clone Bootchain for more details.

The arguments for clone_l2_pt are as follows:

Arguments

Description

partition_name

Identifies the name of the level 2 pt in FileToFlash.txt. Do NOT add chain label A_ or B_ as the prefix of the partition name.

The arguments for clone_l3_nvpt are as follows:

Arguments

Description

container_pname

Container partition name of default level 3 PT, defined in the level 2 PCT config file boot_chain_storage_qspi.cfg.

The arguments for clone_l3_gpt are as follows:

Arguments

Description

container_pname

Container partition name of GPT.

The arguments for clone_l2_images are as follows:

Arguments

Description

partition_type

  • “single”: update an ungrouped partition.

  • “group”: update the grouped partitions in the same group.

img_group

Required only if partition_type is “group”. Identifies the grouped partitions to clone. All the groups are listed in grouped_partitions.txt. Each partition in this group is defined by the partition_name argument. Refer Sample metadata for example.

partition_name

Identifies the name of the QSPI/eMMC/UFS partition to flash. Do NOT add chain label A_ or B_ as the prefix of the partition name.

The arguments for clone_l3_nvpt_images and clone_l3_gpt_images are as follows:

Arguments

Description

container_pname

The container partition name of this level 3 partition. Container name can be obtained in level 2 PCT config file boot_chain_storage_qspi.cfg.

partition_type

The same semantics as that of clone_l2_images command.

img_group

The same semantics as that of clone_l2_images command.

partition_name

The same semantics as that of clone_l2_images command.

The arguments for replicate_brbct are as follows (Only available for Orin):

Arguments

Description

src_bct_index

The index of the source BRBCT copy to be replicated to other copies or to a special copy, should be 0 ~ 3.

dst_bct_index

Optional parameter. The index of the destination BRBCT copy, should be 0 ~ 3. This argument is only effective in standard build.

Note

  • BRBCT include a key which is used by bootloader to authenticate the boot chain. so we should be careful when use install_brbct or replicate_brbct to update BRBCT:

    1. The update should not change the key.

    2. If users do need the update to change the key, then:

      • revoke_key command should be used (even if you don’t intend to revoke the old key).

      • L1PT and all the partitions in the inactive boot chain should be updated.

      • If error or reset happen during updating L1PT, then the system could be crashed need USB flashed to recover.

Push mode Commands#

The following command is for push mode.

Command

Description

start_push_update

This command triggers DU TII to enter push mode. Once DU TII enters push mode, it will not execute the subsequent metadata commands until it exits from push mode as requested by the user.

The arguments for start_push_update are as follows:

Arguments

Description

meta_only

  • “0”: Export all the partitions. Refer Push Mode HOWTO for more information.

  • “1”: Export the partitions configure in device tree (in /dev/nvdt/chosen/driveupdate/export_nodes_list/) with read-only permission. Refer Push Mode Dtb HOWTO for more information.

Rate Limiting Commands#

DRIVE Update provides the mechanism to limit the average data rate of requests to storage server accessing eMMC, UFS and QSPI partitions. The average data rate is configured by setting a certain storage bandwidth limit within a certain time window. It can be done by the following command:

Command

Description

set_storage_bw_limit

This command enables the storage bandwidth limit.

The arguments for set_storage_bw_limit are as follows:

Arguments

Description

storage_bw_limit_bytes

Set the size limit in bytes of allowed storage operation in the time window specified by storage_bw_window_ms.

storage_bw_window_ms

Set the time window in milliseconds. The argument is optional, if it is not specified, DRIVE Update will use 100ms as the default time window.

apply_to_rl

Optional parameter. Specify the storage bw limit will be applied to which runlevel. If this is not specified, the storage bw limit will be applied to all runlevels.

Storage bandwidth limit is disabled by default, and will be enabled by DU-TII on set_storage_bw_limit command. Once it is enabled, it will be effective through the end of the metadata JSON file in which set_storage_bw_limit command resides. DU-TII will limit the total size of storage operation within the bytes specified by storage_bw_limit_bytes in storage_bw_window_ms milliseconds. The storage operations include both reading and writing inactive partitions via Installation commands, Validation commands and Clone commands.

Storage bandwidth limit can be disabled by set storage_bw_window_ms = 0.

Note

Rate limiting commands are not applied to Push mode.

Note

if storage_bw_limit_bytes is not aligned to 256KB, then it will be aligned down to 256KB.

Revoke Key Commands#

DRIVE Update provides the mechanism to change the OEM public key in BRBCT or revoke an OEM public key. It can be done by the following command:

Command

Description

revoke_key

Change the OEM public key in BRBCT or revoke an OEM public key, and Update the BCH of L1PT.

The arguments for revoke_key are as follows:

Arguments

Description

brbct_path

BRBCT image with a different OEM public key or revoke an OEM publick key.

pt_path

L1PT image signed with the new OEM public key.

bch_partitions_list

A partition list that contains all partitions that would be checked as part of secure boot.

Note

  • User should provide completed list for bch_partitions_list.

Note

  • Revoke Key will check if L1PT BCH and the inactive chain (when active chain is A, then inactive chain is B, otherwise inactive chain is A.) partitions’ BCH are matched the BRBCT’s OEM key.

  • If new BRBCT image does not change OEM public key and does not cause new OEM public key to be revoked, then the command revoke_key will be rejected.

  • If the L1PT image other than signature, then the revoke key will be rejected.

  • Revoke Key can only be used in authenticated du package.

  • User should ensure inactive chain, the new L1PT BCH and the new BRBCT are bootable, otherwise it may lead to brick the device.

Note

discard, set_default_chain are not supported.

Command Sequence#

Construct the metadata file so that each command builds on the next instruction in sequence from top to bottom. The inactive bootchain must be locked with install_lock command before updating any inactive partitions. Use the order of partitions in FileToFlash.txt as a reference to the partition update sequence. If partition needs to be discarded, discard command should be right after install_lock and before updating. When all the required partitions are updated, the inactive bootchain must be unlocked with install_unlock command before switching the active and default bootchain. The only exception is that the install_l1_pt command must be put just ahead of the set_default_chain command to update the partition pt of the first level partition table.

For Guest OS partition update:

  • The install_l2_pt command must be present to update the second level PT before any install_l2_images command to update the other partitions of this Guest OS.

  • The install_l3_nvpt or install_l3_gpt command must be present to update the third level PT before any install_l3_nvpt_images or install_l3_gpt_images command to update the other partitions of this Guest OS.

Warning

  • The first level partition table (l1_pt) must be updated after all the other partitions. Any attempt to update partitions after install_l1_pt command is rejected by DU TII.

  • A full system reboot is needed to reload partition table after install_l1_pt.

  • Once install_lock is successfully performed, user can issue multiple times of deployment before install_unlock.

  • If discard is required, it should be performed before image deployment.

  • Before a successful install_unlock command, do not switch to the inactive bootchain with reboot command or set inactive chain as default bootchain with set_default_chain command.

  • The command install_l1_pt should not be wrapped by install_lock and install_unlock because L1PT does not belong to any bootchain.

Installing Thor/Orin Images Example#

The following is a sample metadata file tii-image-metadata.json to install Thor/Orin images:

tii-image-metadata.json

{
    "metaVersion": 2,
    "procedure": [
        {
            "cmd": "install_lock"
        },
        {
            "cmd":"discard",
            "partition_name":"emmc_chain"
        },
        {
            "cmd":"install_l2_pt",
            "partition_name":"pt",
            "img_fname":"$CONTENT_ROOT$A_1_PT.bin"
        },
        {
            "cmd":"validate_l2_pt",
            "partition_name":"pt",
            "hash_algorithm":"sha256",
            "data_size":262144,
            "hash":"77866732cf1bb7a7e98a45380aae1ee37f182f5d507537a2cd6ee7a4be9ac073"
        },
        {
            "cmd":"install_l2_images",
            "partition_type":"single",
            "erase_pad_flag":"0",
            "partition_name":"mb1-bootloader",
            "img_type":"full",
            "img_fname":"$CONTENT_ROOT$A_2_mb1_t234_dev_zerosign.bin"
        },
        {
            "cmd":"validate_l2_images",
            "partition_name":"mb1-bootloader",
            "hash_algorithm":"sha256",
            "data_size":237200,
            "hash":"caf6aac5b24a93a720f2b8444d8137504a1b81bc79d7aeffaa1b9a834341b410"
        },
        {
            "cmd":"install_l3_nvpt",
            "container_pname":"qnx-gos0",
            "img_fname":"$CONTENT_ROOT$A_1_1_PT.bin"
        },
        {
            "cmd":"validate_l3_nvpt",
            "container_pname":"qnx-gos0",
            "hash_algorithm":"sha256",
            "data_size":261120,
            "hash":"b486ba962717aef76791e2ac0673dc4041117b8c229f0cc0b7f353d7237b3a42"
        },
        {
            "cmd":"install_l3_nvpt_images",
            "container_pname":"qnx-update",
            "partition_type":"single",
            "erase_pad_flag":"0",
            "img_type":"full",
            "partition_name":"2_kernel-dtb",
            "img_fname":"$CONTENT_ROOT$A_2_2_tegra_dtb_zerosign.dtb"
        },
        {
            "cmd":"validate_l3_nvpt_images",
            "partition_name":"2_kernel-dtb",
            "hash_algorithm":"sha256",
            "data_size":172032,
            "hash":"f6fabcf7d090dbc0d2ff4dfff74e8fe9cd590da7176690a521b7bc83becdb6d8"
        },
        {
            "cmd": "install_l2_images",
            "partition_type": "group",
            "img_group": [
                {
                    "partition_name": "mb1-bct",
                    "erase_pad_flag": "0",
                    "img_type": "full",
                    "img_fname": "A_2_bct_MB1_zerosign.bct"
                },
                {
                    "partition_name": "spe-fw",
                    "erase_pad_flag": "0",
                    "img_type": "full",
                    "img_fname": "A_4_spe_zerosign.bin"
                },
                {
                    "partition_name": "mb2-bootloader",
                    "erase_pad_flag": "0",
                    "img_type": "full",
                    "img_fname": "A_5_nvtboot_zerosign.bin"
                }
            ]
        },
        {
            "cmd": "validate_l2_images",
            "partition_type": "group",
            "img_group": [
                {
                    "partition_name":"mb1-bct",
                    "hash_algorithm":"sha256",
                    "data_size":20160,
                    "hash":"460c65bfb08f49242735accfdb712c5439339aafee6bcbf2d428371210ac43bd"
                },
                {
                    "partition_name":"spe-fw",
                    "hash_algorithm":"sha256",
                    "data_size":270336,
                    "hash":"7f99090f7e05008bedf453d3c4a95b651e65bf550cd440544ce5bf9513274d7d"
                },
                {
                    "partition_name":"mb2-bootloader",
                    "hash_algorithm":"sha256",
                    "data_size":437568,
                    "hash":"341e2e4815da3f245f5111fed0c0e5029976d6d719968ce58bb79e7bdbbdf03a"
                }
            ]
        },
        // Install other partitions
        {
            "cmd": "install_unlock"
        }
    ]
}

Note

  • The metadata file must be manually composed.

  • Validate and ensure the correctness of the file.

  • The value of metaVersion must be 2 for this release. The value of the version number may increase if additional features are added in future versions of the metadata.

  • Spaces and tabs may be used to improve usability but are not required.

Configuring Default Bootchain Example#

The following is a sample metadata file to configure the default bootchain:

set_default_bootchain.json

{
    "metaVersion":2,
    "procedure":[
        {
            "cmd":"set_default_chain",
            "target_bootchain":"inactive",
            "a_brbct_path":"A_bct_BR_zerosign.bct",
            "b_brbct_path":"B_bct_BR_zerosign.bct"
        }
    ]
}

Note

The recommended normal update workflow is:

  • Update all image data to the partitions, with TII metadata similar as the example of installing Thor/Orin images.

  • Switch to the inactive chain temporarily and perform boot health check.

  • Configure the default bootchain based on the boot health check result.

See Switch Back On Failure of Post Installation Check for more details.

Note

  • The max partitions number in TII metadata is about 150.

  • The max size of TII metadata is 1MB.

Perform Updates#

This section introduces how to use DRIVE Update to perform updates.

Before You Begin#

The first thing is to prepare the DRIVE Update package files. See DRIVE Update Package and DRIVE Update Metadata for more information.

DRIVE Update assumes that the user provides the update content in a decrypted format to perform the update because DRIVE Update does not have decryption functionality.

All the package files shall be downloaded into the same directory of the local file system of Guest OS on Thor/Orin A if the user uses Content Server to export the package files. All the files must be read-accessible by customer OTA application and DU Content Server.

Note

The user must mark the exported files by Client OTA Application/Content Server as globally read only [* R!W] to ensure there is no undefined behavior if a malicious actor tries to write to the exported files.

Note

SC7 is not supported when DRIVE Update is in a deployment.

Note

REINIT is not supported when DRIVE Update is in a deployment.

Note

DUS needs at least 2% local CPU resource to accomplish deployment without starving of CPU to failure. For more information how to yield CPU to DUS, see the “Timed VCPU Yield” section.

Security Hardening for IPC Parameters#

To access the IPC channel on Linux, the OTA application must config the UID for IPC endpoint nvdu_gos_ipc_xx_1, nvdu_gos_ipc_xx_0.

/drive-linux/lib-target/nvsciipc_t26x.cfg

Example of configuration file entries:

# INTER_PROCESS  <Endpoint-name1> <Endpoint-name2> <backend-specific-info> <UID of Endpoint-name1 owner process: UID1> <UID of Endpoint-name2 owner process: UID2>
# INTER_VM       <Endpoint-name> <backend-specific-info> <UID of Endpoint-name owner process>
INTER_PROCESS   nvmcc_du_ipc_0         nvmcc_du_ipc_1   16     4096   2423 2430
INTER_PROCESS   nvdu_gos_ipc_d_0       nvdu_gos_ipc_d_1 5      262656 2426 2909
INTER_PROCESS   nvdu_gos_ipc_e_0       nvdu_gos_ipc_e_1 5      262656 2426 2910
INTER_PROCESS   nvdu_gos_ipc_g_0       nvdu_gos_ipc_g_1 5      262656 2426 2912
INTER_PROCESS   nvdu_gos_ipc_i_0       nvdu_gos_ipc_i_1 5      262656 2427 2909
INTER_VM        nvdriveupdate_ivc_1    407 2433

For the INTER_PROCESS backend, two UIDs must be defined, one for each communicating process. The second process must include the GID of the first UID in its supplementary group list.

Group membership can be updated following NV UID and GID Reservation Tool.

For example, DU Master appliaction with predefined UID 2427 owns nvdu_gos_ipc_i_0 IPC endpoint and DU sample_driveupdate sample application with predefined UID 2909 owns nvdu_gos_ipc_i_1 IPC endpoint, then the process sample_driveupdate with UID 2909 must be added to the group DU Master associated with UID 2427. This additional group assignment is required only for channels using the INTER_PROCESS backend.

  • nvmcc_du_ipc_0/1 is used by mcc_daemon with UID 2423 and DU bootmgr application with predefined UID 2430.

  • nvdu_gos_ipc_d_0/1 is used by dulink_router with UID 2426 and sample_driveupdate sample application with UID predefined 2909.

  • nvdu_gos_ipc_e_0/1 is used by dulink_router with UID 2426 and content_server sample application with UID predefined 2910.

  • nvdu_gos_ipc_g_0/1 is used by dulink_router with UID 2426 and sample_duinstaller sample application with predefined UID 2912.

  • nvdu_gos_ipc_i_0/1 is used by dumaster with UID 24267 and sample_driveupdate sample application with predefined UID 2909.

  • nvdriveupdate_ivc_1 is used by dutii with predefined UID 2433 currently and need to change to customer UID if customer develop their own apllication that use dus_client library.

Update Workflow#

Note

In this section, it describes the update workflow of normal updates with DU TII install_* commands. The update workflow of push mode and bootchain clone is similar, please refer to Application Note for more details.

The following is a typical workflow of the customer OTA application to perform the update with DRIVE Update APIs.

Initialize DUCC and start monitoring update state via DUCC interface.

DUCC can be initialized by the following sample code:

static PDUCC     gpDucc = NULL;
static DUTR_SEC_NONE_PARAM     dutrCCSecParams;;
static DUTR_NVSCI_PARAM        dutrCCParams = \
    { .ep[0] = "nvdu_gos_ipc_i_1", .ep[1] = "nvdu_gos_ipc_i_0"};

duRet = DUCC_Init(DUTR_TR_TYPE_NVSCI, DUTR_SEC_TYPE_NONE,
                    &dutrCCParams, &dutrCCSecParams, &gpDucc);

Parameters of DUCC_Init are shown below:

  • trType(DUTR_TR_TYPE): Type of back-end transport protocol used. For example, “DUTR_TR_TYPE_NVSCI” in type DUTR_TR_TYPE.

  • seType(DUTR_SEC_TYPE): Type of security protocol. For example, “DUTR_SEC_TYPE_NONE” in type DUTR_SEC_TYPE.

  • pTrParam(const_PDUTR_TR_PARAM): Pointer to the argument of selected transport protocol. For example, struct DUTR_NVSCI_PARAM with value { .ep[0] = “nvdu_gos_ipc_i_1”, .ep[1] = “nvdu_gos_ipc_i_0”};.

  • pSeParam(const_PDUTR_SEC_PARAM): Pointer to the argument of selected security protocol. For example, struct DUTR_SEC_NONE_PARAM.

  • ppDucc(PDUCC*): Pointer to initialized DUCC handle. For example, DUCC pointer.

Note

  • As dumaster is now in Guest OS, DUTR_NVSCI_PARAM shall use IPC not IVC channel to access DUCC interface.

  • DUCC interface relies on IPC channel to connect DU Master. Must use the IPC channel name nvdu_gos_ipc_i_1, nvdu_gos_ipc_i_0 for DUCC_Init(). For Linux, see Security Hardening IPC Parameters.

  • In this release, only DUTR_SEC_TYPE_NONE is supported which must be used together with DUTR_SEC_NONE_PARAM.

  • For QNX, In order to access to this IPC channel, the OTA application must be started with iolauncher, with security tag “nvdriveupdate_cc_service”.

  • To open both DUCC and du-client IPC channels, use security tag “nvdriveupdate_guest_vm_client”

  • DUCC interfaces should be called after DUCC_Init is successfully returned

See DUCC API for more information.

The update state can be polled periodically with the following DUCC API:

DUCC_Status status;
DUCC_Get_Current_Status(pDucc, &status);

The caller can get the current update state from status.state, and the pending action from status.pendingAction, see DUCC API for more information. The initiate run level is RL_DORMANT and initiate state is STATE_DORMANT. Update activity requires a higher run level, and the caller can get the required run level of DU Master from status.pendingActionArgs. The caller can forward the request of higher run level to the UI of customer OTA application, and set the run level as following to perform further update activity if the user accept the request:

DUCC_Request_RunLevel(pDucc, status.pendingActionArgs);

Normally the customer OTA application shall check whether any update package is available from OTA cloud server only if the run level is set higher than RL_DORMANT by the user.

Once the update procedure starts, the returned status.state is STATE_UPDATE_IN_PROGRESS, and it changes to STATE_UP_TO_DATE once the update completes successfully. Otherwise, STATE_UPDATE_FAILED or STATE_FATAL_ERROR is returned.

The customer OTA application shall register itself to DU Link network and initialize the connection to DU Link Router in Guest OS on Orin A.

This can be done as follows:

DULINK_CONNECT_INFO duConnInfo = {0};
uint32_t gRefId = DULINK_CLOSE_ALL;

getPluginConnInfo("du-client", &duConnInfo);
dulinkInit("du-client", duConnInfo.remotePath);
dulinkOpen(duConnInfo.remotePath, duConnInfo.trType, duConnInfo.seType,
          (PDUTR_TR_PARAM) &duConnInfo.trParamBuf,
          (PDUTR_SEC_PARAM) &duConnInfo.secParamBuf,
          duConnInfo.connType, &gRefId);

Parameters of dulinkInit are shown below:

  • pName(const_char*): name of the element ot open dulink. For example, “du-client”.

  • pParentPath(const_char*): Parent path of this element.

Parameters of dulinkOpen are shown below:

  • pRemotePath(const_char*): Absolute path of node being connected.

  • trType(DUTR_TR_TYPE): Type of back-end transport protocol used.

  • seType(DUTR_SEC_TYPE): Type of security protocol.

  • pTrParam(const_void*): Pointer to the argument of selected transport protocol. For example, “nvdu_gos_ipc_d_0”, “nvdu_gos_ipc_d_1”.

  • pSeParam(const_void*): Pointer to the argument of selected security protocol.

  • connType(DULINK_CONNECTION_TYPE): Type of connection. For example, “DOWNLINK”.

  • pConnRefId(uint32_t*): Reference ID can be used to close connection.

Note

  • The DU Link element name must be “du-client” and its parent path must be “/”, so that OTA application can connect to DU Link Router and access DU Master and Content Server interfaces.

  • OTA application connects to DU Link Router via IPC channel, hence NVSCI shall be used for DUTR_TR_TYPE, and “nvdu_gos_ipc_d_0”, “nvdu_gos_ipc_d_1” can be used as parameters. It is recommended for OTA application to use a configuration file to define the parameters for flexibility. For Linux, see Security Hardening IPC Parameters.

  • dulink interfaces should be called only dulinkInit is successfully returned

The user shall make sure that the connection to DU Link Router is setup before performing any further update activity, by doing similar checking as follows:

DULINK_ATTR attr;
uint32_t    retries = USER_DEFINED_RETRY_COUNT;
while (dulinkGetAttribute("/", &attr) != DU_OK)
{
    if (retries == 0)
    {
        printf("Failed connect to router\n");
        return ERROR_CODE;
    }
    retries--;
    sleep(USER_DEFINED_RETRY_INTERVAL);
}

Export package files to DU Link network

char cmd[] = "serve local_path=/absolute/directory/path/of/package/files";
dulinkWrite("/content/cmd", 0, strlen(cmd), cmd, &len);

Note

On success, the package files are accessible by DU plug-ins via DU Link APIs.

See Content Server Interface for more information.

Trigger the actual update procedure via DU Master command interface

char cmd[] = "deploy metadata=/content/files/du_master.json content_root=/content/files";
dulinkWrite("/master/cmd", 0, strlen(cmd), cmd, &len);

Note

  • The name du_master.json is an example, which can be replaced by the user. However, the path must be /content/files if Content Server is used to export package files.

  • The deploy command is written to DU Master interface /master/cmd. See DU Master Interface for more information.

Keep monitoring the update status via DUCC interface until the end of update. When update procedure ends up, user shall stop serving package files by writing “stop_serving” command to Content Server interface.

Context Management#

System may reboot for multiple time during the full update procedure, which can be initiated by DRIVE Update itself or by accidental power failure. The customer OTA application should manage its own context across reboot, to distinguish and handle various conditions properly.

User can use Persistent Context Store Interface to manage the context.

On register to DU Master, the Plugin would be written to the path to persistent context storage in persistent_ctx_path node. Customer OTA application should read its context first once the run level is not DORMANT, to check if it is a new update or whether it needs to resume the updates in progress. Refer the following code example in sample_driveupdate.c to read context:

dulinkRead(persistent_ctx_path, 0, sizeof(context), context, &retLen);

Once OTA application triggered the update procedure via DU Master interface, it should record the current deployment into persistent context, so that it can read the stored context on next startup. The context can be updated as the following example code:

static DU_RCODE updateContext(char *pLocalPath)
{
    char     context[DU_PATH_MAX] = {0};
    uint64_t retLen;
    if (pLocalPath != NULL)
    {
        (void)strncpy(context, pLocalPath, DU_PATH_MAX);
    }

    if (dulinkWrite(persistent_ctx_path, 0,
                    strlen(context), context, &retLen) != DU_OK)
    {
        LOG("Error Updating context\n");
        return DUCOMMON_ERR_GENERIC;
    }
    return DU_OK;
}

Note

The above example just demonstrates how to store a simple string to the context. User can define his own context format, of binary type or JSON strings.

The context should be updated when there is a status change of the updates, for example, error on updates, abort from updates, or success on updates.

Switch Back On Failure of Post Installation Check#

DRIVE Update provides the mechanism for user to do post installation check and switch back to the previous bootchain on failure of post installation check.

Firstly user should implement his own boot health check functionality with the BHC skeleton plug-in. See BHC Interface for details.

Secondly user can define and enable the workflow with boot health check in DU Master metadata as the following example:

du_bhc_metadata.json

{
    "metaVersion": 3,
    "restoreSequence": [
        "*/du-client",
        "*/content",
        "/tii",
        "/bhc",
        "/bootmgr"
    ],
    "actions": [
        {
            "actionId": 0,
            "description": "Deploy images to TA",
            "gatedBy": [],
            "pluginType": "installer",
            "pluginPath": "/tii",
            "startOnState": [
                "IDLE"
            ],
            "exitOnStateTransitionTo": [
                "IDLE"
            ],
            "failOnStateTransitionTo": [
                "ERROR"
            ],
            "cmd": "deploy metadata=$CONTENT_ROOT$/tii-a/metadata.json"
        },
        {
            "actionId": 1,
            "description": "Reboot TA to new chain",
            "gatedBy": [
                0
            ],
            "pluginType": "installer",
            "pluginPath": "/bootmgr",
            "startOnState": [
                "IDLE"
            ],
            "exitOnStateTransitionTo": [
                "IDLE"
            ],
            "failOnStateTransitionTo": [
                "ERROR"
            ],
            "cmd": "deploy metadata=$CONTENT_ROOT$/reboot.json"
        },
        {
            "actionId": 2,
            "description": "Invoke boot health check on TA",
            "gatedBy": [
                1
            ],
            "pluginType": "validator",
            "pluginPath": "/bhc",
            "startOnState": [
                "IDLE"
            ],
            "exitOnStateTransitionTo": [
                "IDLE"
            ],
            "failOnStateTransitionTo": [
                "ERROR"
            ],
            "cmd": "validate",
            "onFail": "bhc_fail"
        },
        {
            "actionId": 3,
            "description": "Set default chain on TA",
            "gatedBy": [
                2
            ],
            "pluginType": "installer",
            "pluginPath": "/bootmgr",
            "startOnState": [
                "IDLE"
            ],
            "exitOnStateTransitionTo": [
                "IDLE"
            ],
            "failOnStateTransitionTo": [
                "ERROR"
            ],
            "cmd": "deploy metadata=$CONTENT_ROOT$/set_default_chain.json"
        }
    ],
    "bhc_fail": [
        {
            "actionId": 0,
            "description": "Switch back to old chain on TA",
            "gatedBy": [],
            "pluginType": "installer",
            "pluginPath": "/bootmgr",
            "startOnState": [
                "IDLE"
            ],
            "exitOnStateTransitionTo": [
                "IDLE"
            ],
            "failOnStateTransitionTo": [
                "ERROR"
            ],
            "cmd": "deploy metadata=$CONTENT_ROOT$/reboot.json"
        }
    ]
}

Note

  • In the default actions section of the above example, action 0 performs the partition updates, and actionId 1 reboots Tegra into the other bootchain. Once DU Master boots up to the new chain, it performs actionId 2 to do boot health check, and performs actionId 3 to set the new chain as the default bootchain on success of boot health check. See BHC Interface for instructions how to enable the user defined boot health check.

  • The above metadata file defines a set of actions named “bhc_fail” to be executed on failure of “actionId” 2 in the default action set “actions”, specified with “onFail” key word. In the “bhc_fail” action set, actionId 0 switches back to the previous bootchain.

  • It’s needed to update MCU firmware prior to above process. If any reboot happens when system booting in the updated chain but before execution of set default bootchain, DRIVE Update would think this new chain as unstable and return update failure. DriveOS may automatic update MCU firmware and reboot before set default chain if MCU firmware is not updated prior to Tegra.

  • The above example is for the target platform with GPIO bootchain selection mode, therefore Boot Manager is used to reboot and configure the default bootchain. Refer DU Master Metadata Example For BRBCT Mode for the target platform with Marker based bootchain selection mode.

Note

Deployment resumption: If reboot occurs when it is deploying via DRIVE Update, then deployment resumes after system bootup. - The section “restoreSequence” in du_master.json defines a list of DU plug-ins which DU Master needs to wait until their context is restored in order before resuming the deployment. The “*” before the plug-in path means that the plug-in will be checked by DU master only if it is registered previously during the deployment. - When restoring, DU Master will wait for the plug-ins connected one by one, and each one will wait for 4 minutes. - User uses content_server + du-client or DDU to serve files and trigger deployment, so to resume a previous deployment, they should start up content_server + du-client or DDU.

Note

STATE_UPDATE_FAILED: When deployment is failed or aborted, DU Master will go to IDLE state, if runlevel is not RL_DORMANT, then user will get STATE_UPDATE_FAILED. STATE_FATAL_ERROR: The system is now in an undetermined state, possibly bootable but should be assumed unsafe to use. The system has to be manually re-flashed or restored in order to exit this state.

Note

“failOnStateTransitionTo” in each action in du_master.json list a state, if related plug-in switches to the state, then if will cause the deployment to fail.

Deployment resume#

When DU Master bootup, it will try to load stored context data via DU Persistent Context Store, then it will goto “RESTORE_CTX” state (DU is In STATE_UPDATE_IN_PROGRESS status (with 0% progress)) to try to resume deployment if .

if there is deployment in the previous bootup, then DU Master tries to resume the previous deployment. The following are the steps of the deployment resume:

  • Resume the previous plugins based on the “restoreSequence” in du_master.json. See DU Master metadata for more information about restoreSequence. DU Master will wait for approximately 4 minutes for each plugin to connect to the dulink space and another 4 minutes for each plugin to transition out of the RESTORE_CTX state (i.e. until fail to get the state of the plugin or the state is not RESTORE_CTX).

  • After all the plugins resumed, the previous deployment is continued.

Mostly, the user own the plugins “/du-client,” “/content,” or “/ddu,” which are included in the DU Master’s restored plugins list upon deployment resumption. Therefore, the user needs to resume “/du-client,” “/content,” or “/ddu” to ensure the deployment resumed successful.

The following are the steps of the user to resume the deployment:

  • Wait for system DVMS INIT_DONE (QNX only).

  • Start up content_server to export du package to dulink space.

  • Start up sample_driveupdate to resume the deployment, the following are the step of sample_driveupdate:

    • Dulink related initialized.

    • Register to DU Master.

    • Ducc related initialized.

    • Monite the deployment status.

DU-TII deployment resume, DU-TII will resume the executing metadata command, and if it is installing partition:

  • For full update, when DU-TII update an image to a partition with full type, DU-TII will save deployment context with the index of metadata command in metadata.json, the offset of image and the offset of partition in every writing 100MB data to partition. so DU-TII will try to continue the update with the index of progress, offset of image and offset of partition.

  • For delta update, when DU-TII update an image to a partition with delta type, DU-TII will read nvdiffOffsets block by block (1MB), and then handle nvdiffOffsets one by one, and then read/write data one by one (1MB each time), DU-TII save deployment context with the index of metadata command in metadata.json, the offset of the total nvdiffOffsets, the offset of the 1MB nvdiffOffsets, the offset of the delta data after every 100MB data written. DU-TII will try to continue the update with the index of metadata command in metadata.json, the offset of the total nvdiffOffsets, the offset of the 1MB nvdiffOffsets, the offset of the delta data.

DU deployment resume flow

DU deployment resume flow#

Example code about Dulink related initialized in sample_driveupdate.c:

if (dulinkInit(CLIENT_NAME, duConnInfo.remotePath) != DU_OK)
{
    DU_ERR("Failed to init DULINK\n");
    return CONTENT_ERR_GENERIC;
}

if (exportDULinkNodes(NULL, 0, DULINK_FILES_TABLE, DULINK_FILES_TABLE_MAX,
        DULINK_NOTIFY_TABLE, DULINK_NOTIFY_TABLE_MAX) != DU_OK)
{
    DU_ERR("Failed to export all DU Link nodes\n");
    return CONTENT_ERR_GENERIC;
}

initContentProvider(&content_provider);

if (dulinkOpen(duConnInfo.remotePath, duConnInfo.trType, duConnInfo.seType,
                (PDUTR_TR_PARAM) &duConnInfo.trParamBuf,
                (PDUTR_SEC_PARAM) &duConnInfo.secParamBuf,
                duConnInfo.connType, &gRefId) != DU_OK)
{
    DU_ERR("Failed to connect DULINK\n");
    return CONTENT_ERR_GENERIC;
}

Example code about Register to DU Master in sample_driveupdate.c:

duRet = registerToMaster(DUMASTER_PATH)
if (duRet != DU_OK)
{
    DU_ERR("Error %#x to register to DU Master\n", duRet);
    return CONTENT_ERR_GENERIC;
}

Example code about Ducc related initialized in sample_driveupdate.c:

duRet = DUCC_Init(DUTR_TR_TYPE_NVSCI, DUTR_SEC_TYPE_NONE,
                  &dutrCCParams, &dutrCCSecParams, &gpDucc);
if (duRet != DU_OK)
{
    DU_ERR("Error initialize C&C, err:%#x\n", duRet);
    goto end;
}

for (retry = 1U; retry <= DUCC_MAX_RETRY; retry++)
{
    duRet = DUCC_Get_Current_RunLevel(gpDucc, &runlevel);
    if (duRet == DU_OK)
    {
        break;
    }
    else
    {
        DU_INFO("ret:%#x on DUCC_Get_Current_RunLevel()\n", duRet);
        if (retry < DUCC_MAX_RETRY)
        {
            DU_INFO("DUCC is not ready, sleep %us and retry\n", sleepSec);
            (void) sleep(sleepSec);
        }
        else
        {
            DU_ERR("Error fetching runlevel, make sure sample is running"
                " on master Tegra!\n");
            duRet = CONTENT_ERR_GENERIC;
        }
    }
}

Example code about Monite the deployment status in sample_driveupdate.c:

for (;;)
{
    if (DUCC_Get_Current_Status(gpDucc, &status) != DU_OK)
    {
        DU_ERR("Failed to fetch current status!\n");
        goto fail;
    }
    switch (status.state)
    {

        case STATE_DORMANT:
        case STATE_NO_CONNECTIVITY:
        case STATE_UPDATE_AVAILABLE:
            if (bPrintStatus)
            {
                DU_LOG("Current state: %s\n", DUCC_STATE_TABLE[status.state]);
            }
            break;
        case STATE_UPDATE_IN_PROGRESS:
            if (bPrintStatus)
            {
                DU_LOG("Current state: %s, progress %d%%\n",
                        DUCC_STATE_TABLE[status.state], status.progress);
            }
            break;
        case STATE_UPDATE_FAILED:
        case STATE_FATAL_ERROR:
            bUpdateError = true;
            DU_LOG("Current state: %s, exit sample app\n",
                    DUCC_STATE_TABLE[status.state]);
            goto done;
        case STATE_UP_TO_DATE:
            DU_LOG("Current state: %s, exit sample app\n",
                    DUCC_STATE_TABLE[status.state]);
            goto done;
        default:
            DU_ERR("Invalid state %d\n", status.state);
            goto fail;
    }
    switch (status.pendingAction)
    {
        case PA_NONE:
            break;
        case PA_RUNLEVEL:
            DUCC_Request_RunLevel(gpDucc, status.pendingActionArgs);
            break;
        case PA_USERACTION:
        default:
            DU_ERR("Invalid pending action %d\n", status.pendingAction);
            goto fail;
    }
    sleep(INTERVAL_PROGRESS);
}

DRIVE Update APIs#

The DRIVE Update provides the following APIs for the customer OTA application to implement the complete OTA solution for NVIDIA DRIVE™ AGX Orin Platform.

DU Master Interface#

DU Master provides user the following interface via DU Link network.

Interface Path

Command String

Description

/master/cmd

deploy metadata={metadata_file} content_root={content_root}

This command tells DU Master to begin update installation. {metadata_file} points to a DU Link path where the top level metadata file is to be read from. {content_root} points to a DU Link path where the package files are to be read from.

/master/cmd

abort

This command tells DU to abort from the current update procedure in progress.

Note

  • The “abort” command is used to abort from the current update procedure in progress. If there is no deployment issued by “deploy” command, “abort” command would result in errors.

  • User can query current DUCC state via DUCC_Get_Current_Status() API before sending “abort” command. It is optional. If the current state is STATE_UPDATE_IN_PROGRESS, the state would change to STATE_UPDATE_FAILED on success of “abort” command. If the current state is not STATE_UPDATE_IN_PROGRESS, the state after “abort” is not predictable.

  • After “abort”, user can request content provider plug-in to stop serving package files in DU-Link. The user can set the runlevel back to RL_DORMANT. These two operations are optional, depending on the use case designed by the user.

  • Once a deployment is aborted, it cannot be resumed.

  • Aborting an update procedure may leave inactive bootchain in dirty state because DRIVE Update does not reset the inactive bootchain to the original status on “abort” command. It is the users’ responsibility to make sure not switching to a dirty bootchain.

Persistent Context Store Interface#

Persistent Context Store plug-in provides the interface to store context to the persistent storage so that the context can be persistent across reboots even if bootchain is switched.

Interface Path

Operations

Description

/ctx_store/context

Read/Write

Read the path to retrieve the context stored last time, and write the path to update the context content.

BHC Interface#

BHC plug-in provides user the following command interface via DU Link network.

Interface Path

Operations

Description

/bhc/cmd

Write only

Write “validate” command to start the validation by executing the user implemented functions with the API of BHC plug-in skeleton.

Write “clear_error” command to clear the error state of the result for the last boot health check operation.

/bhc/result

Read only

Read it to query the validation result string “PASS” or “FAIL”.

The default BHC API shared library libnvdubhc_api.so packaged in the Guest OS filesystem is an empty implementation which always returns true as the validation result. The source code files dubhc_api.c are released as sample program for the user to implement his own function to perform the validation for his own requirements. The program interface in dubhc_api.c as following:

dubhc_api.c

/*!
 * User defined Boot Health Check callback function.
 *
 * @return true
 *          Success on boot health check.
 * @return false
 *          Failure on boot health check.
 */
bool duBootHealthCheckUserCallback(void)
{
    // Fill your tests here, default returns success
#ifndef DU_BHC_FAILURE
    return true;
#else
    return false;
#endif
}

The user needs to build his own libnvdubhc_api.so and replace the original one before creating images or flashing the target board.

DUCC API#

DUCC is the Command and Control (C&C) interface used to interact and control the complete stack of Drive OTA solution. It is delivered in a form of a client library implementing C&C API’s to be used by OTA applications. Through DUCC API, which is declared in the ducc.h, OTA is able to inform OTA when it is safe or desirable to perform operations which may impact functionality and/or performance of the vehicle. It can also query for update availability or installation progress status, as well as version info and release notes associated with the installed or pending updates. In the end DUCC allows the end-user to interact with the update installation. Client can controll the update with runlevel and learn about the status of update.

Note

For Linux, see Security Hardening IPC Parameters to develop customer application that use the IPC Channel.

Runlevel#

Runlevels define the maximum performance and functionality that Drive OTA is allowed to impact on the vehicle in order to complete its operations. Runlevels are cumulative, meaning each runlevel allows an increase in potential system functionality and/or performance impact. RL_DORMANT is the lowest runlevel, and RL_UNRESTRICTED is the highest. Each runlevel is described explictly in the ducommon.h.

Runlevel transition do not have to be requested in any particular order and it is possible to transit from any runlevel to any others.

Status#

DUCC allows the OTA applications to query for current DRIVE Update status, which includes information such as whether the system is up to date with software updates, whether there are updates available, or whether the updates are in the process of being installed. DUCC status contains 3 component: State, Progress and Pending Action. Details are declared in the ducc.h.

The transition of DUCC state is automatically according to it’s runlevel and software availability.

DUCC state transition

DUCC state transition#

DUCC state transition with condition

DUCC state transition with condition#

DU Plug-in API#

DU Plug-in APIs are declared in duplugin.h which helps user to development his own DU plug-ins. Please refer DU Plug-ins Interface Specification for more information.

Other Interfaces#

DRIVE Update provides the interfaces to use Authenticator plug-in, Decompressor plug-in, please refer Authenticator HOWTO and Decompressor HOWTO, respectively, for more details.

Application Note#

DU Plug-ins Interface Specification#

This section describes the interfaces used by Drive Update Plug-ins to allow it to add features and expand functionality of Drive Update. All of the required and some optional exported DU-Link nodes are listed, their functionality is described, supported commands and states are provided.

Note

Only the minimum interface requirements for each plug-in type are defined, and specific plug-ins can have extended interfaces.

Common Plug-in Interface#

The common interface is required to be implemented by all plug-ins. It allows DU framework to utilize new plug-ins using a standardized interface.

Plug-in Power Up Sequence#

Each plug-in runs in its own context. On startup, each plug-in must conform to the following sequence:

  1. Plug-in must powerup at RL_DORMANT runlevel

  2. Plug-in must register with the DU-Master upon successful DU-Link connection, as described in section Plug-in Registration.

  3. Plug-in state must be set to “INIT” until its initialization is complete, at which point the state will change to “IDLE”.

  4. If plug-in supports context restore, it must restore its context when instructed by DU-Master as per section Plug-in Context Save and Restore Operations.

Plug-in Registration#

All plug-ins must register with DU Master via registerToMaster() API declared in duplugin.h upon successful connection to DU-Link.

Plug-in Context Save and Restore Operations#

Since software/firmware installations often require system reboots as part of the update process, each plug-in has an option to support context persistence over reboot. DU framework facilitates context persistence by providing a DU-Link path where a plugin can store its context and retrieve it back after reboot (including reboots to a new bootchain).

Plug-in context is stored in a binary form in a plugin specific format. Saving context is a simple operation of writing a DU-Link node path specified in the plugin’s persistent_ctx_path node. If context persistence is supported, DU Master will write an appropriate path to persistent_ctx_path on initialization while plug-in is still in RL_DORMANT, which should trigger the plugin to re-initialize using the context read from the provided path. Plug-in may save a new copy of its context to the provided path at any time deemed appropriate. The Persistent Context Store plug-in takes care of storing it and making it available for restore.

Note

Context storage must be performed using a single DU-Link write in order to make it an atomic operation for power-fail-safe functionality.

Controller Type Plug-in#

There will only be one controller plug-in in the system and it is always provided by Drive Update as the DU-Master.

Installer Plug-ins#

This section describes the interface which is required for all Installer plug-ins, in addition to the common plug-in interface described in the Common Plug-in Interface section.

Installer Plug-in Overview#

An Installer plug-in is a Drive Update plug-in which allows Drive Update to apply software or firmware updates. Installer plug-in interface is DU-Link based interface, which exposes a file-system-like set of nodes which can be read from and/or written to. Drive Update interacts with installers solely through this interface by writing to and reading from the exported DU-Link nodes.

An Installer plug-in typically depends on and interacts with two other DU-Link plug-ins: a Controller and a Content Provider. The Controller (DU Master) issues commands to the Installer and monitors its state/status, while the installer accesses content of the updates by reading from a Content Provider plug-in path provided as part of the “deploy” command. A high level block diagram of a typical installer deployment is shown in the figure below.

Typical Installer Deployment

Typical Installer Deployment#

The principle of operation of an installer is to:

  1. Receive installation commands from the controller, including the DU-Link path for update content.

  2. Perform the required installation commands as per the update content retrieved from the Content Provider using the DU-Link path provided as part of installation command.

  3. While installing, provide the controller with status/progress updates, any required runlevel increases, and current installation state information.

  4. An Installer exports a number of DU-Link nodes which serve as the installer’s sole interface to interact with Drive Update. The following sections describe all the nodes exported by an Installer and their functionality.

Command Interface#

Installer Command Interface nodes are shown in Table 4. All of the nodes listed in Table 4 are required.

Installer Command Interface Exported Nodes#

Node Name

Type (D/F)

Permissions ACL

Description

cmd

F

* \[R,-\]
/master \[R,W\]

Reading this node shows the current command being executed. Writing to this node tells the installer to execute a command.

cmd.list

F

* \[R,!W\]

Read only file node containing a list of supported commands. A list of required and optional commands is given in Table 8.

progress

F

* \[R,!W\]

Read only file node containing the current installation progress percentage (integer, range 0-100).

progress.notify

F

* \[R,W\]

Reading this node lists all DU-Link nodes to be notified of new progress value(one path listed per line). Writing “+PATH” will add a new node path to be notified, “-PATH” will remove the path from the list.

Supported Installer commands are shown in the following table. Only “deploy” command is required, however “abort” command is strongly recommended (if not supported, the installer can only proceed with installation in RL_UNRESTRICTED). “commit” and “revert” commands are optional, depending on installer capabilities, however they should either both be supported or neither.

Supported Installer Commands#

Command String

Description

deploy metadata={metadata_file}

This command tells the installer to begin update installation. {metadata_file} points to a du-link path where the top level metadata file is to be read from (from a content provider). Additional parameters may be passed by name in the same command, for example “content_root={path}”.

commit

This command commits the newly installed payload. The commit step is defined in the payload metadata. This command can only be issued when state is PENDING_COMMIT.

revert

This command instructs the installer to discard a newly deployed but uncommitted image. This command can only be issues when the installer state is PENDING_COMMIT

abort

This command instructs the installer to abort current installation. This command cannot be issued when state is IDLE or REVERTING

clear_error

This command instructs the plugin to clear the error state, and to proceed to the next valid state (most often IDLE, but up to individual plugin)

Available Installer states are defined in the following table. Only IDLE and INSTALLING are required, remaining states are optional. A list of supported states should always be exposed via “state.list” node.

Supported Installer States#

Installer State

Description

INIT

This is an optional state which indicated that an installer is initializing and/or loading context.

IDLE

In this state, Installer is not doing anything - it’s idle/paused.

PENDING_RL

In this state, Installer is in the process of installing an update, however the current runlevel is preventing progress of the installation. Current progress percentage can be read from “progress” node.

PENDING_RESTART

In this state, Installer is in the process of installing an update, however the installer requires a system restart to continue. Current progress percentage can be read from “progress” node.

PENDING_COMMIT

In this state, the installation of new image is complete, but a commit command is required to activate it, or a revert command to discard the newly deployed image

INSTALLING

In this state, Installer is installing the update and its progress percentage can be read from “progress’ node.

REVERTING

In this state, Installer is performing a revert operation. Its progress percentage can be read from “progress’ node.

ERROR

The plugin enters this state is the command fails after a successful write of a said command to cmd node. The plug-in stays in this state until a “clear_error” command is written to the cmd node.

There are two way a command can fail:

  1. Synchronously – a write callback for the cmd node returns a failure. This failure mode should be used for errors which can be determined quickly and in a well bound time limit, for example syntax checking, or argument checking. Write callback should never be gating for a long time while the command executes.

  2. Asynchronously – enter the ERROR state. This failure mode should be used when a command fails after the cmd node write callback successfully returns, for example an installer “deploy” command fails during the installation.

Version Information Interface#

Every Installer exports versioning information in a DU-Link subfolder names “ver”. The exported version nodes are shown in the following table. Inactive payload nodes are optional if dual boot configuration is not supported. The ver/cmp subfolder houses all .cmp nodes.

Version Information Exported Nodes#

Node Name

Type (D/F)

Permissions ACL

Description

ver

D

* \[R,-\]

This is a directory containing all versioning data exposed by the installer

ver/installer

F

* \[R,!W\]

Current installer version

ver/installer.cmp

F

* \[-,-\]
/master \[R,W\]

A version comparison node for current installer version. To compare, write a version string to compare to this node and read this node back to see whether the written version is newer, equal, or older than current version. For example, if installer version is “1.0”, writing “2.0” would cause the read to return “2.0>1.0”, writing “1.0.0” would read back “1.0.0=1.0”

ver/payload

F

* \[R,!W\]

Currently installed payload version.

ver/cmp/payload.cmp

F

* \[-,-\]
/master \[R,W\]

A version comparison node for currently installed payload version. To compare, write the version string to compare to this node and read this node back to see whether the written version is newer, equal, or older than current version. For example, if installer version is “1.0”, writing “2.0” would cause the read to return “2.0>1.0”, writing “1.0.0” would read back “1.0.0=1.0”. Non numerical versions work the same way.

ver/inactive_payload

F

* \[R,!W\]

Currently installed inactive payload version. Inactive payload is defined as payload installed in the inactive bootchain. During installation to inactive bootchain, this version reads “INVALID”. This node is only present in systems with A/B boot systems, which have an active and inactive boot partition.

ver/cmp/inactive_payload.cmp

F

* \[-,-\]
/master \[R,W\]

A version comparison node for currently installed inactive payload version. To compare, write the version string to compare to this node and read this node back to see whether the written version is newer, equal, or older than current version. For example, if inactive_payload is “1.0”, writing “2.0” would cause the read to return “2.0>1.0”, writing “1.0.0” would read back “1.0.0=1.0”. Non numerical versions work the same way. This node is only present in systems with A/B boot systems, which have an active and inactive boot partition.

Last Deployment Information Interface#

In order to communicate the success or failure of last attempted deployment, each installer exports the “last_deployed” set of read only nodes shows in the following table. The content of these nodes is only updated when a deploy command completes (and state returns to IDLE).

Last Attempted Deployment Information Nodes#

Node Name

Type (D/F)

Permissions ACL

Description

last_deployed

D

* \[R,-\]

This directory contains information on most recent completed deployment attempt (not the currently being deployed payload).

last_deployed/metadata

F

* \[R,!W\]

This node contains the metadata file name used in last completed deploy command

last_deployed/payload

F

* \[R,!W\]

This node contains the payload version of last deployment attempt

last_deployed/payload.cmp

F

* \[R,!W\]

A version comparison node for last attempted deployment payload version. To compare, write the version string to compare to this node and read this node back to see whether the written version is newer, equal, or older than current version. For example, if last_deployed/payload is “1.0”, writing “2.0” would cause the read to return “2.0>1.0”, writing “1.0.0” would read back “1.0.0=1.0”. Non numerical versions work the same way, for example if current installed payload version is “Ferrari” and you write “RedBull” to the .cmp node, it could read back “RedBull>Ferrari”.

last_deployed/result

F

* \[R,!W\]

This node contains the result of last attempted payload deployment. Possible values are SUCCESS, FAILED, ABORTED. Value ABORTED is used for reverted installations.

Content Provider Type Plug-ins#

Content provider plug-ins are responsible for exporting update payload, file based content by exporting those files to be read via DU Link by other plug-ins. All content provider plug-ins must provide common plug-in interface as per the Common Plug-in Interface section. Content provider plug-in supported states are shown in the following table.

In addition to the required nodes, content provider shall export content on demand, exporting the files as read-only file nodes when available and unlinking them when content is no longer needed or available. It is recommended that the content should be exported in a subdirectory of the content provider plugin.

Note that content providers may export additional nodes to facilitate interactions with other plug-ins, but those are all optional and will not be used by the DU Master as part of DU framework operation.

Supported Content Provider Plug-in States#

Content Provider State

Description

INIT

This is an optional state which indicated that the plug-in is initializing and/or loading context.

IDLE

This state indicates the content provider is online but not serving any content.

CONFIGURED

This state indicated the content provider is online and serving content.

File Transform Type Plug-ins#

File transform plug-ins serve a similar role as content provider plug-ins, except that rather than providing original content, they provide transformed content from the actual content providers.

Theory of operation for file transform plug in is shown in the figure below. The installer in this case is reading content from the file transform plug-in, instead of the content provider.

File Transform Plugin Operation

File Transform Plugin Operation#

Example file transfer plug-ins are:

Decryptor – decrypts original content and provides decrypted version of the file to the consumer plug-in.

Decompressor - applies decompression algorithm to the original content and provides uncompressed content to the consumer plug-in.

Authenticator – while technically not modifying the content, authenticator passes through the original content but only if it passes authentication. Reading content from the authenticator will fail if the content itself fails authentication.

File transform plug-ins offer the same interface as the content-provider, with an additional cmd nodes shown in the following table. The purpose for the cmd node is to allow the file transform plug-in to be configured via a Master payload action command, while content providers plug-ins typically are configured externally by client applications such as OTA (not via DU Master). File Transform Plug-in states are listed in Table 12.

File Transform Plug-in Required Interface Nodes#

Node Name

Type (D/F)

Permissions ACL

Description

cmd

F

* \[R,-\]
/master \[R,W\]

Reading this node shows the current command being executed. Writing to this node tells the plugin to execute a command.

cmd.list

F

* \[R,!W\]

Read only file node containing a list of supported commands. A list of required and optional commands is given in Table 11.

Supported File Transform Plug-in Commands#

Command String

Description

configure metadata={metadata_file}

This command tells the file transform plugin to configure itself to serve content as per specified {metadata_file}. The metadata file should list all content to be served, its source location, and any required transforms. Additional parameters may be passed by name in the same command, for example “content_root={path}”. File transform plugin will transition to CONFIGURED state after this command and stay in this state until configuration is cleared. This command may only be written if the plug-in state is IDLE.

clear_config

This command tells the file transform plugin to clear its configuration and to stop serving any transformed content (unlink all served files). File transform plugin will transition to IDLE state after this command.

clear_error

This command instructs the plugin to clear the error state, and to proceed to the next valid state (most often IDLE, but up to individual plugin)

Supported File Transform Plug-in States#

File Transform Provider State

Description

INIT

This is an optional state which indicated that the plug-in is initializing and/or loading context.

IDLE

This state indicates the content provider is online but not serving any content.

PENDING_RL

This state indicates that the file-transform plug-in has unsatisfied requests pending (e.g. du-link read requests) but it’s unable to satisfy them at the current runlevel. pending_rl node should indicate the minimum runlevel required to proceed.

CONFIGURING

This state indicated that the plugin is configuring (not yet serving content). Once configured, the state shall change to CONFIGURED.

CONFIGURED

This state indicates the file transform plugin is online and serving content.

ERROR

The plugin enters this state is the command fails after a successful write of a said command to cmd node. The plug-in stays in this state until a “clear_error” command is written to the cmd node.

There are two way a command can fail:

  1. Synchronously – a write callback for the cmd node returns a failure. This failure mode should be used for errors which can be determined quickly and in a well bound time limit, for example syntax checking, or argument checking. Write callback should never be gating for a long time while the command executes.

  2. Asynchronously – enter the ERROR state. This failure mode should be used when a command fails after the cmd node write callback successfully returns.

Metadata Provider Type Plug-ins#

Metadata provider plugs in export read only medatata information. All metadata provider plug-ins must provide common plug-in interface as per Common Plug-in Interface. In addition to the required nodes, metadata providers may expose any number of nodes. An example of metadata provider would be Vehicle Info plug in which would expose nodes such as VIN, model & year, etc.

Validator Type Plug-ins#

A validator type plug-in exposes a PASS/FAIL type test functionality to other plug-ins. Example of validator type plug-ins include Boot Health Check.

All validator plug-ins must export all common plug-in interface nodes as per Common Plug-in Interface. Additionally, validator plug-ins must export nodes shown in Table 13. Validator type plug-in states are shown in Table 15.

Validator Plug-in Required Interface Nodes#

Node Name

Type (D/F)

Permissions ACL

Description

cmd

F

* \[R,-\]
/master \[R,W\]

Reading this node shows the current command being executed. Writing to this node tells the plugin to execute a command.

cmd.list

F

* \[R,!W\]

Read only file node containing a list of supported commands. A list of required and optional commands is given in Table 14.

result

F

* \[R,!W\]

This node contains the result of last validation test in a format:

  • “{id}:PASS” or “{id}:FAIL”

Where {id} is the value of the “id” parameter passed with the validate command (see Table 14). If no id is passed, the format is simply “PASS” or “FAIL”.

result.notify

F

* \[R,-\]
/master \[R,W\]

Reading this node lists all DU-Link nodes to be notified of new result content (one path listed per line). Writing “+PATH” will add a new node path to be notified, “-PATH” will remove the path from the list.

Supported Validator Plug-in Commands#

Command String

Description

validate metadata={metadata_file} id={string}

This command tells the validator plugin to perform any validation tests as described in the metadata file (or built-in default tests is metadata parameter is skipped). Optional parameter “id” is used to identify test results. Additional parameters may be passed by name in the same command, for example “content_root={path}”. Validator plugin will transition to VALIDATING state after this command and stay in this state until validation is completed.

clear_error

This command instructs the plugin to clear the error state, and to proceed to the next valid state (most often IDLE, but up to individual plugin)

Supported Validator Plug-in States#

Content Provider State

Description

INIT

This is an optional state which indicated that the plug-in is initializing and/or loading context.

IDLE

This state indicates the validator plug-in is ready to run validation tests.

VALIDATING

This state indicated the validator plug-in is running validation tests

ERROR

The plugin enters this state is the command fails after a successful write of a said command to cmd node. The plug-in stays in this state until a “clear_error” command is written to the cmd node.

There are two way a command can fail:

  1. Synchronously – a write callback for the cmd node returns a failure. This failure mode should be used for errors which can be determined quickly and in a well bound time limit, for example syntax checking, or argument checking. Write callback should never be gating for a long time while the command executes.

  2. Asynchronously – enter the ERROR state. This failure mode should be used when a command fails after the cmd node write callback successfully returns, for example if “validate” command fails after running tests.

Persistent Context Store Type Plug-ins#

The function of a persistent context store type plug-in is to store binary content persistent across reboots, including reboots to new bootchains. This functionality is used by Drive Update plug-ins to save context necessary to persist after scheduled reboot or after an unexpected power failure.

Authenticator HOWTO#

Authenticator is a plug-in of file transform type, which can be used to authenticate the signed update package with the OEM public key which is normally stored in secure NOR flash.

Note

Authenticator is enforced for all builds (Linux and QNX). Each DU package for all builds must be signed with a private key before deployment.

Authentication enforcement may be disabled via disable-auth-enforcement setting in device tree.

Note

There is no way to disable the authenticator. What can be disabled is authentication enforcement in most scenarios. Disabling the authentication enforcement means that Drive OS no longer enforces the DRIVE Update package authentication for most scenarios, however the package signature would still be checked if the package contains a signature. Any signature that exists in a package must be a valid signature. Additionally, any package that revokes a public key must be signed.

Package type

Standard

Safety

Disable Authentication Enforcement

Package with no signature and no revoke command

Auth Pass

Auth Fail

Auth Pass

Package with no signature and revoke command

Auth Fail

Auth Fail

Auth Fail

Package with correct signature (regardless of revoke command)

Auth Pass

Auth Pass

Auth Pass

Package with incorrect signature (regardless of revoke command)

Auth Fail

Auth Fail

Auth Fail

How to Disable Authentication Enforcement#

Edit tegra264-driveupdate.dtsi file (Thor) or tegra234-driveupdate.dtsi (Orin) to add this setting corresponding to your board in PDK, then re-bind and re-flash the board.

For example:

/drive/drive-foundation/platform-config/hardware/nvidia/platform/t264/automotive/kernel-dts/common/tegra264-driveupdate.dtsi  // Thor
/drive-foundation/platform-config/hardware/nvidia/platform/t23x/automotive/kernel-dts/common/qnx/tegra234-driveupdate.dtsi    // Orin (QNX)
/drive-foundation/platform-config/hardware/nvidia/platform/t23x/automotive/kernel-dts/common/linux/tegra234-driveupdate.dtsi  // Orin (Linux)

Find drive update section:

driveupdate {
    auth-key = ...

Add a new line if “disable-auth-enforcement” is not presented, or change its value to “1”.

disable-auth-enforcement = "1";

The end result would be like this

driveupdate {
    disable-auth-enforcement = "1";
    auth-key = ...

After the modification, re-bind and flash the device.

Note

DRIVE Update Package Authentication Enforcement feature shall not be disabled via the disable-auth-enforcement Device Tree key entry, unless the customer identifies and mitigates, or assumes all risks associated with all safety and security threats which would otherwise be mitigated by DU package authentication enforcement. Examples of such threats include, but are not limited to:

  1. Deployment of maliciously constructed updates, for example an update which will instruct DU to perform a denial of service by entering an infinite reboot loop. Such update can be deployed by any compromised process running on Guest OS without special permissions.

  2. Tampering with the update content during a deployment, resulting in a partial or modified update flow and/or content

  3. Deploying a mix-and-match update which includes some partitions from older releases, and some partitions from newer releases. Such combination would still boot as all partitions would contain a valid signature, but since the partition combination is not a valid one, the resulting system cannot be considered validates and/or safe.

  4. Any compromised process within Guest OS can issue arbitrary commands to DRIVE Update, including platform reset requests. This can be used to disrupt operation of the system, or it can be used by an attacker who temporarily compromised a process to gain permanence by embedding itself within Tegra attached storage(s).

All security threat modeling performed by NVIDIA for DriveOS assumes DU authentication is enabled and enforced, meaning only updates which are securely signed outside of the vehicle environment would be accepted/executed by DRIVE Update.

Signed DRIVE Update Package#

The signed DU package contains all the files that need to be installed as listed in section DRIVE Update Package, along with their corresponding hash files and an Authenticator Configuration Metadata File.

The chain of trust starts from the Authenticator Configuration Metadata File, which is signed and contains authentication method to authenticate all the files in DRIVE Update package, as shown in the following figure.

Authenticator Configuration Metadata

Authenticator Configuration Metadata#

Authenticator Configuration Metadata#

Authenticator Configuration metadata contains the following sections in the top level:

Key

Description

metaVersion

Integer version number for the metadata file. It is 1 at present.

Files

A list of files signed by authenticator.

Below is the syntax of each file item in the “Files” section.

Key

Description

src

The path of the source file to be signed by Authenticator. It is a DU-Link path of the original package file served by content provider plug-in.

dst

The destination file that Authenticator will transform the source file to. It contains the following two sub attributes:

  • filename: the DU-Link path of the destination file

  • read_acl: access control list of DU plug-ins that have read permission to this file

Please refer Example of Signed DRIVE Update Package for more information.

auth_alg

Authentication algorithm, which can be one of the following:

  • SHA256: Use the SHA256 hash of the whole file.

  • BLK_BHASH: The file is block hashed.

alg_data

The hash data of the corresponding authentication algorithm. If auth_alg is SHA256, then it is the value of the hash value of the whole file. If auth_alg is BLK_BHASH, it is the DU-Link path of the .bhash file of the original file, which contains a list of SHA256 hash values of the file block by block.

Please refer Example of Signed DRIVE Update Package for more information.

BHASH Metadata#

BHASH Metadata contains the following sections in the top level:

Key

Description

metaVersion

Integer version number for the metadata file. It is 1 at present.

blk_size

The block size in bytes used to generate the block hash values.

auth_alg

The authentication algorithm used to calculate the hash. “SHA256” and “SHA512” are supported.

no_of_blks

Total number of the blocks that the file is divided into.

list_of_hashes

A list of the hash values of all blocks in sequence.

Please refer Example of Signed DRIVE Update Package for more information.

Authenticator Signature File#

Authenticator Configuration Metadata file auth_conf.json will be signed with OEM private key and Authenticator Signature file auth_conf.json.sig will be generated.

When generating the signature, auth_conf.json file will be prepended with the magic buffer of 20 bytes long as shown below:

  • 6 bytes magic string (“NVDU-AUTH-CONFIG”)

  • 4 bytes of 0xFF

The structure of the signed file auth_conf.json.sig is as following:

  • The magic number (“NVDU-SIG” + NULL)

  • Version information in uint_8 size

  • Signature Algorithm in uint_8 size. It should be 0x01 which stands for RSA3K.

  • Length of the signature in bytes represented in network order uint_16. It is 384(0x0180)

  • Signature of auth_conf.json file represented in uint_8[]

The following is an example of a python function how to sign auth_conf.json:

'''
If import from Crypto failed, try the following command to install the dependence

* pip3 uninstall pycrypto && pip3 install pycryptodome
'''
from Crypto.PublicKey import RSA
from Crypto.Signature import pss
from Crypto.Hash import SHA256

# magic buffer before the auth config file (auth_conf.json)
SIGNER_MAGIC = b"NVDU-AUTH-CONFIG" + b"\xFF"*4
# magic number before the signature
NVIDIA_MAGIC = b"NVDU-SIG\x00"
# signer version, uint8_t type, range: 0~255
SIGNER_VERSION = 1
# signature algorithm indicator, uint8_t type, range: 0~255
ALGORITHM_TABLE = {
    "RSA3K" : 1,
}

def RSA_sign(file_name, input_key_file):
    key = RSA.importKey(open(input_key_file).read())
    with open(file_name, 'rb') as f:
        block = f.read()
        block = SIGNER_MAGIC + block
    hash_obj = SHA256.new(block)
    signature = pss.new(key).sign(hash_obj)
    with open(file_name+'.sig', 'wb+') as f:
        f.write(NVIDIA_MAGIC)
        f.write(SIGNER_VERSION.to_bytes(1, 'big'))
        f.write(ALGORITHM_TABLE['RSA3K'].to_bytes(1, 'big'))
        f.write(len(signature).to_bytes(2, 'big'))
        f.write(signature)

in which the input file_name is auth_conf.json and input_key_file is the OEM private key.

Example of Signed DRIVE Update Package#

Here is a simple example of signed DRIVE Update package. Assuming the original package contains the following files:

  • du_master.json

  • list_of_files.json

  • tii-a [directory]

    • small_image.img (48KiB)

    • large_image.img (5.12MiB)

And blk_size of 1048576 bytes (1MiB) is used for BLK_HASH algorithm.

The signed package generated from the above will contain the following files:

  • du_master.json

  • list_of_files.json

  • auth_conf.json

  • auth_conf.json.sig

  • tii-a [directory]

    • small_image.img (48KiB)

    • large_image.img (5.12MiB)

    • large_image.img.bhash

The auth_conf.json is Authenticator Configuration Metadata file, and it will look like the following:

{
    "metaVersion": 1,
    "Files": [
        {
            "src": "$CONTENT_ROOT$/du_master.json",
            "dst": {
                "filename": "/auth/content/du_master.json",
                "read_acl": [
                    "/master"
                ]
            },
            "auth_alg": "SHA256",
            "alg_data": {
                "HASH": "dd2d5161ac9d17289bb86825f5d2b772b12fe4c393ea906b6cde01e43f5391cf"
            }
        },
        {
            "src": "$CONTENT_ROOT$/tii-a/small_image.img",
            "dst": {
                "filename": "/auth/content/tii-a/small_image.img",
                "read_acl": [
                    "/tii"
                ]
            },
            "auth_alg": "SHA256",
            "alg_data": {
                "HASH": "77a087d323ee5497fb102001c60ffb01bdbbb5932340a215c7a85664e9d4bf81"
            }
        },
        {
            "src": "$CONTENT_ROOT$/tii-a/large_image.img",
            "dst": {
                "filename": "/auth/content/tii-a/large_image.img",
                "read_acl": [
                    "/tii"
                ]
            },
            "auth_alg": "BLK_HASH",
            "alg_data": {
                "HASH": "/auth/content/tii-a/large_image.img.bhash"
            }
        },
        {
            "src": "$CONTENT_ROOT$/tii-a/ large_image.img.bhash",
            "dst": {
                "filename": "/auth/content/tii-a/ large_image.img.bhash",
                "read_acl": [
                    "/auth"
                ]
            },
            "auth_alg": "SHA256",
            "alg_data": {
                "HASH": "acfa424ee18dda3693213e37f31af5c5eb280dd338be79eda2d31dbe1a4cb5ca"
            }
        }
    ]
}
  • The maximum number of files supported in auth_conf.json is 300.

  • The maximum size of auth_conf.json supported is 64KB.

In the above example:

  • The “read_acl” of small_image.img and large_image.img is [“tii-a”], which indicates that these two files can be read by DU TII only. The “read_acl” of large_image.img.bhash is [“/auth”] because BHASH file only needs to be read by Authenticator.

  • The “auth_alg” of small_image.img is “SHA256” because the file size is smaller than the block size of 1MiB.

  • The “auth_alg” of large_image.img is “BLK_HASH” because the file size is larger than the block size. The BHASH file large_image.img.bhash should be verified with SHA256 algorithm too.

The following is an example of BHASH file large_image.img.bhash:

{
    "metaVersion": 1,
    "blk_size": 1048576,
    "auth_alg": "SHA256",
    "no_of_blks": 6,
    "list_of_hashes": [
        "7d019de69e4489b5586d00672695bf4d8a15679464d5ee470555898c88bf141b",
        "955fc0756b5ba34a94ed5b513be11265b426d1ac4d19521ab99530b1235bd599",
        "65d557df9b2dd118859b12bb3f087a63950f610c567501feb9e946c4e1a8ca94",
        "9700344482a974c290d6860626dc7c59182a87505c983987654485f47666ff99",
        "e4d1926f7e4e72f337bfbb1f1fdc73fbfd278f2074e2d568b9dbdad8b1a47c9b",
        "58e2ee691a7de401833d3e20586b9024802fbeb521f4e11b2af706f4eb003611"
    ]
}

There are 6 blocks in total because large_image.img is of 5.12MiB size which contains five 1MiB blocks and one 0.12MiB block.

The maximum supported BHASHes in a file is limited to 32768 OR the maximum supported size of a BHASH file is 1MB.

Note

With the “blk_size” of 1048576 and the BHASH file size limit of 1MB, the maximum size of an image that is supported is 13.46GB.

Authenticator should be configured in du_master.json. Refer Update Workflow With Authenticator for more information.

Update Workflow With Authenticator#

The update workflow in OTA application can be implemented similarly as section Update Workflow.

Note

  • OTA application must input the path to auth_conf.json file by adding the “auth=$ROOT/auth_conf.json” parameter to the deploy command. for example: “deploy metadata=$ROOT/du_master.json auth=$ROOT/auth_conf.json content_root=$ROOT”

  • Please refer to DUPKG_Authentication_HOWTO for how to generate a valid Authentication DU Package.

The difference mainly resides in du_master.json. The following is an example du_master.json file with Authenticator enabled. File root content will be changed to /auth/content in Authenticator DU Package.

{
    "metaVersion": 3,
    "restoreSequence": [
        "*/ddu",
        "*/du-client",
        "*/content",
        "/auth",
        "/tii",
        "/bhc",
        "/bootmgr"
    ],
    "actions": [
        {
            "actionId": 0,
            "description": "Deploy images to TA",
            "gatedBy": [],
            "pluginType": "installer",
            "pluginPath": "/tii",
            "startOnState": ["IDLE"],
            "exitOnStateTransitionTo": ["IDLE"],
            "failOnStateTransitionTo": ["ERROR"],
            "logOnStart": "Start Deploy images to TA",
            "logOnExit": "TA images updated",
            "logOnFail": "Failed to deploy images to TA",
            "cmd" : "deploy metadata=/auth/content/tii-a/metadata.json"
        },
        {
            "actionId": 1,
            "description": "Reboot TA to new chain",
            "gatedBy": [0],
            "pluginType": "installer",
            "pluginPath": "/bootmgr",
            "startOnState": ["IDLE"],
            "exitOnStateTransitionTo": ["IDLE"],
            "failOnStateTransitionTo": ["ERROR"],
            "logOnStart": "Start reboot TA to new chain",
            "logOnExit": "TA rebooted",
            "logOnFail": "Failed to reboot TA to new chain",
            "cmd" : "deploy metadata=/auth/content/reboot.json"
        },
        {
            "actionId": 2,
            "description": "Invoke boot health check on TA",
            "gatedBy": [1],
            "pluginType": "validator",
            "pluginPath": "/bhc",
            "startOnState": ["IDLE"],
            "exitOnStateTransitionTo": ["IDLE"],
            "failOnStateTransitionTo": ["ERROR"],
            "logOnStart": "Start TA boot health check",
            "logOnExit": "Passed TA boot health check",
            "logOnFail": "Failed to pass TA boot health check",
            "cmd" : "validate",
            "onFail": "bhc_fail"
        },
        {
            "actionId": 3,
            "description": "Set default chain on TA",
            "gatedBy": [2],
            "pluginType": "installer",
            "pluginPath": "/bootmgr",
            "startOnState": ["IDLE"],
            "exitOnStateTransitionTo": ["IDLE"],
            "failOnStateTransitionTo": ["ERROR"],
            "cmd" : "deploy metadata=/auth/content/set_default_chain.json"
        }
    ],
    "bhc_fail": [
        {
            "actionId": 0,
            "description": "Switch back to old chain on TA",
            "gatedBy": [],
            "pluginType": "installer",
            "pluginPath": "/bootmgr",
            "startOnState": ["IDLE"],
            "exitOnStateTransitionTo": ["IDLE"],
            "failOnStateTransitionTo": ["ERROR"],
            "cmd" : "deploy metadata=/auth/content/reboot.json"
        }
    ]
}

DUPKG Authentication HOWTO#

DUPKG Tool with Authentication template use to package the images and sign the whole package with the RSA private key. Update VM on the target device will validate the package before deployment to ensure package is not damaged after release.

Generate Authentication DU Package#

Create SSH Key Pair for Authentication#

Note

  • If you already have a SSH key, skip this section

  • If you don’t have a SSH key, you can follow this section to generate a new SSH key to use for authentication.

  • RSA public key will convert and update to the DTS file

  • RSA private key will transfer to DUPKG Tool for signing the package

  • Create a new SSH RSA key pair

ssh-keygen -t rsa -b 3072
Update Public Key to Device Tree#
  • Convert the public key to auth-key format for DTS

use the following Python3 script to convert the RSA public key to hex string for device tree

from Crypto.PublicKey import RSA
pem = "id_rsa.pub" # change to your rsa public key
key = RSA.importKey(open(pem, "r").read())
s = "{0:X}{1:08X}".format(key.n, key.e)
dts_auth_key = " ".join(["0x"+s[i:i+2] for i in range(0, len(s), 2)])
print(dts_auth_key)
  • Update the auth-key array to DTS file in SDK

find the tegra264-driveupdate.dtsi (Thor) / tegra234-driveupdate.dtsi (Orin) from SDK and replace the auth-key data use the output from last step,the dts file is located in

/drive/drive-foundation/platform-config/hardware/nvidia/platform/t264/automotive/kernel-dts/common/tegra264-driveupdate.dtsi  // Thor
/drive-foundation/platform-config/hardware/nvidia/platform/t23x/automotive/kernel-dts/common/qnx/tegra234-driveupdate.dtsi    // Orin (QNX)
/drive-foundation/platform-config/hardware/nvidia/platform/t23x/automotive/kernel-dts/common/linux/tegra234-driveupdate.dtsi  // Orin (Linux)

Find drive update section, “auth-key”

driveupdate {
    auth-key = <0xBF 0xCC ... 0x00 0x01 0x00 0x01>;
    ...
}
Generate Package#

Make sure you have built the SDK image successfully, then running the following command to generate DU Package with Authentication.

Generate Authentication DU Package for QNX

# DUPKG Version: 1.6.0
TEGRA_A_SRC=<path_to_qnx_source_image>
PRIVATE_KEY_PATH=<path_to_authenticator>/id_rsa
OUTPUT_FOLDER=<path_to_empty_folder>
TEMPLATE=dupkg_single_tegra_template

python3 dupkg.py gen --in TII_META_VER=metav2 VALIDATE_OPTION=True TEGRA_A_SRC=$TEGRA_A_SRC AUTHENTICATOR_OPTION=AuthPkg PRIVATE_KEY_PATH=$PRIVATE_KEY_PATH --template $TEMPLATE --out $OUTPUT_FOLDER

Generate Authentication DU Package for Linux

# DUPKG Version: 1.6.0
TEGRA_A_SRC=<path_to_linux_source_image>
PRIVATE_KEY_PATH=<path_to_authenticator>/id_rsa
OUTPUT_FOLDER=<path_to_empty_folder>
TEMPLATE=dupkg_single_tegra_template

python3 dupkg.py gen --in TII_META_VER=metav2 VALIDATE_OPTION=True TEGRA_A_SRC=$TEGRA_A_SRC AUTHENTICATOR_OPTION=AuthPkg PRIVATE_KEY_PATH=$PRIVATE_KEY_PATH --template $TEMPLATE --out $OUTPUT_FOLDER

Apart from directly generating authenticated DU package DUPKG also supports sign or re-sign an existing DU package with dupkg_sign_template. By listing the input argument there are extra variables which can be configured for DU packaged generated with different templates.

 Input Variable   | Req / Opt   | Description
------------------+-------------+-----------------------------------------------------------------------------------------------
 DUPKG_DIR        | Required    | Path to DUPKG folder to be signed containing Tegra images, du_master.json and etc
 SIGN_TEMPLATE    | Required    | Template used for the unsigned DUPKG generation
 PRIVATE_KEY_PATH | Optional    | The path to private key file. Required if enable Authenticator
 TEGRASIGN_PATH   | Optional    | The path to the tegrasign_v3.py tool in the PDK. Required if enable Authenticator and use HSM

 Extra Variable        | Req / Opt   | Description
-----------------------+-------------+-----------------------------------------------------------------------------------------------------------------------------------------------------
 UPDATE_RECOVERY_CHAIN | Optional    | If update the recovery chain [True | False]. Default is True. This is an option for DU package generated with dupkg_only_install_template

For example to sign a DU package generated with dupkg_only_install_template:

DUPKG_DIR=<path_to_DU_package> SIGN_TEMPLATE=dupkg_only_install_template PRIVATE_KEY_PATH=<path_to_authenticator>/id_rsa OUTPUT_FOLDER=<path_to_empty_folder>

python3 dupkg.py gen –in DUPKG_DIR=$DUPKG_DIR SIGN_TEMPLATE=$SIGN_TEMPLATE PRIVATE_KEY_PATH=$PRIVATE_KEY_PATH UPDATE_RECOVERY_CHAIN=False –template dupkg_sign_template –out $OUTPUT_FOLDER

Deploy Authentication DU Package#

Deploy Process#

Deploy the DU Package use sample_driveupdate tool on the target GuestOS, the package files will trigger the DU-Auth plugin to validate the package with the public key from device tree. Package files will actually deploy to the target only when validate pass, otherwise, DU-Auth plugin will reject the deploy.

Deploy DU Package with Authentication

Deploy DU Package with Authentication#

Deploy to Target#
  1. copy the sample_driveupdate, content_server and DU package to target

  2. deploy on target use the following commands

./content_server <path_to_package> &
./sample_driveupdate -p /content/files --auth

Example Deploy Log

# ./content_server <path_to_package> &
# ./sample_driveupdate -p /content/files --auth
Deploy mode is pull
Current state: STATE_DORMANT
Update is waiting for higher run level 3
Current state: STATE_UPDATE_IN_PROGRESS, progress 33%
Update is waiting for higher run level 4
Current state: STATE_UPDATE_IN_PROGRESS, progress 33%
...
Current state: STATE_UP_TO_DATE, exit sample app
[Result]Deploy OK!

Bootchain Clone HOWTO#

User can use bootchain clone method to either recover inactive chain or update the second bootchain for dual bootchain updates, by cloning active partitions to inactive bootchain. This can be done with Bootchain Clone Commands in DU TII metadata. The update steps are described at Perform Updates.

Clone Bootchain#

Clone Bootchain only works when the active chain is A or B:

  • When active chain is A, it clones from A chain to B chain

  • When active chain is B, it clones from B chain to A chain

DRIVE Update can clone the whole images from active bootchain to inactive bootchain with clone_bootchain command, this command does not have any arguments and it will clone following partitions:

  • clone active chain qspi_chain to inactive chain qspi_chain (about 9MB)

  • clone active chain emmc_chain to inactive chain emmc_chain(about 28GB)

  • clone active chain ufs_chain to inactive chain ufs_chain (if device have one, about 52GB)

The metadata to perform clone bootchain is simple as bellow:

{
    "metaVersion": 2,
    "procedure": [
        {
            "cmd": "clone_bootchain"
        }
    ]
}

Note

  • The clone_bootchain command is only guaranteed to work when all bootchain partitions are read-only.

  • Users should ensure no write operations occur on the read-write partitions during the clone procedure. This includes but not limited to rw_overlay and nvlog.

  • Users could unmount read-write partitions during the clone procedure, and mount it back after clone is done.

Clone Partitions#

The following is an example to clone some of active partitions to inactive bootchain.

{
    "metaVersion":2,
    "procedure":[
        {
            "cmd":"install_lock"
        },
        {
            "cmd":"clone_l2_pt",
            "partition_name":"pt"
        },
        {
            "cmd":"clone_l2_images",
            "partition_type":"single",
            "partition_name":"mb1-bootloader"
        },
        {
            "cmd":"clone_l2_images",
            "partition_type":"single",
            "partition_name":"psc-bl"
        },
        {
            "cmd":"clone_l2_images",
            "partition_type":"single",
            "partition_name":"mb1-bct"
        },
        {
            "cmd":"clone_l2_images",
            "partition_type":"single",
            "partition_name":"mem-bct"
        },
        {
            "cmd":"clone_l2_images",
            "partition_type":"single",
            "partition_name":"mb2-bootloader"
        },
        {
            "cmd":"clone_l2_images",
            "partition_type":"single",
            "partition_name":"spe-fw"
        },
        {
            "cmd":"clone_l2_images",
            "partition_type":"single",
            "partition_name":"tsec-fw"
        },
        {
            "cmd":"clone_l2_images",
            "partition_type":"single",
            "partition_name":"psc-fw"
        },
        {
            "cmd":"clone_l2_images",
            "partition_type":"single",
            "partition_name":"mts-mce"
        },
        {
            "cmd":"clone_l2_images",
            "partition_type":"single",
            "partition_name":"bpmp-fw"
        },
        {
            "cmd":"clone_l2_images",
            "partition_type":"single",
            "partition_name":"sc7-fw"
        },
        {
            "cmd":"clone_l2_images",
            "partition_type":"single",
            "partition_name":"psc-rf"
        },
        {
            "cmd":"clone_l2_images",
            "partition_type":"single",
            "partition_name":"mb2-rf"
        },
        {
            "cmd":"clone_l2_images",
            "partition_type":"single",
            "partition_name":"bpmp-fw-dtb"
        },
        {
            "cmd":"clone_l2_images",
            "partition_type":"single",
            "partition_name":"rce-fw"
        },
        {
            "cmd":"clone_l2_images",
            "partition_type":"single",
            "partition_name":"ist-ucode"
        },
        {
            "cmd":"clone_l2_images",
            "partition_type":"single",
            "partition_name":"bpmp-ist"
        },
        {
            "cmd":"clone_l2_images",
            "partition_type":"single",
            "partition_name":"ist-config"
        },
        {
            "cmd":"clone_l2_images",
            "partition_type":"single",
            "partition_name":"ist-testimg"
        },
        {
            "cmd":"clone_l2_images",
            "partition_type":"single",
            "partition_name":"ist-runtimeinfo"
        },
        {
            "cmd":"clone_l2_images",
            "partition_type":"single",
            "partition_name":"ist-resultdata"
        },
        {
            "cmd":"clone_l3_gpt",
            "container_pname":"custom"
        },
        {
            "cmd":"clone_l2_images",
            "partition_type":"single",
            "partition_name":"secure-os"
        },
        {
            "cmd":"clone_l2_images",
            "partition_type":"single",
            "partition_name":"fsi-fw"
        },
        {
            "cmd":"clone_l2_images",
            "partition_type":"single",
            "partition_name":"pvit"
        },
        {
            "cmd":"clone_l2_images",
            "partition_type":"single",
            "partition_name":"pva-fw"
        },
        {
            "cmd":"clone_l2_images",
            "partition_type":"single",
            "partition_name":"kernel"
        },
        {
            "cmd":"clone_l3_nvpt",
            "container_pname":"qnx-gos0"
        },
        {
            "cmd":"clone_l3_nvpt_images",
            "container_pname":"qnx-gos0",
            "partition_type":"single",
            "partition_name":"1_kernel-dtb"
        },
        {
            "cmd":"clone_l3_nvpt_images",
            "container_pname":"qnx-gos0",
            "partition_type":"single",
            "partition_name":"1_kernel"
        },
        {
            "cmd":"clone_l2_images",
            "partition_type":"single",
            "partition_name":"usr-fs"
        },
        {
            "cmd":"clone_l2_images",
            "partition_type":"single",
            "partition_name":"gos0-ifs2"
        },
        {
            "cmd":"clone_l2_images",
            "partition_type":"single",
            "partition_name":"debug_overlay"
        },
        {
            "cmd":"clone_l3_nvpt",
            "container_pname":"qnx-update"
        },
        {
            "cmd":"clone_l3_nvpt_images",
            "container_pname":"qnx-update",
            "partition_type":"single",
            "partition_name":"2_kernel-dtb"
        },
        {
            "cmd":"clone_l3_nvpt_images",
            "container_pname":"qnx-update",
            "partition_type":"single",
            "partition_name":"2_kernel"
        },
        {
            "cmd":"install_unlock"
        }
    ]
}

Delta Update HOWTO#

Delta updates is a Drive Update feature that allow users to update images using the delta of the original and new image. This reduces the update time as the delta image size is much smaller than that of the full image.

Most images released as part of DriveOS are small except the QNX6 FS image which is 4 GB. The tool is optimal to be used with images of bigger sizes like QNX6 FS images.

Following sections list the steps need to be followed to generate a delta image and perform delta updates.

Note

For security reasons, PVIT update needs to be included in the metadata.json.

To include PVIT, please add below example section to metadata.json and update list_of_files.json to include A_PVIT_Image_zerosign.bin as well.

{
    "cmd":"install_l2_images",
    "partition_type":"single",
    "erase_pad_flag":"1",
    "partition_name":"pvit",
    "img_type":"full",
    "img_fname":"$CONTENT_ROOT$A_PVIT_Image_zerosign.bin"
},
{
    "cmd":"validate_l2_images",
    "partition_name":"pvit",
    "hash_algorithm":"sha512",
    "data_size":12848,
    "hash":"<updated the hash of this file>"
},

If you don’t want to include PVIT, it shall be disabled. To disable PVIT, please include “ENABLE_PVIT=n” when binding the partition prior to flashing.

Note

Delta update does not support for Mb1 partition.

Delta Generator#

The delta image is generated using “nvdiff” binary which is provided for x86 Linux host. The binary can be run as:

$ nvdiff <old_fs>.img <new_fs>.img delta_fs.img 4m

The delta_fs.img is the image generated which can be applied on the <old_fs>.img. “4m” is the block size parameter, this command set the block size to 4MB, default block size is “8m”.

Note

The <old_fs> and <new_fs> used in this file are just referring to old and new fs images and the tool does not expect the files to be named this way. These will need to be replaced by the files you pass to generate the delta.

DU TII Metadata Commands#

DU TII metadata commands of install_l{*}_images are used for Delta update. The “img_type” parameter should be “delta” to indicate delta update.

Note that the data_size should be the <new_fs>.img full size and the hash should be the <new_fs>.img sha256 or sha512 string

The following is an example metadata to perform delta update on gos0-fs image.

{
    "metaVersion": 2,
    "procedure": [
        {
            "cmd": "install_lock"
        },
        {
            "cmd": "install_l2_images",
            "erase_pad_flag": "0",
            "img_type": "delta",
            "partition_type": "single",
            "partition_name": "gos0-fs",
            "img_fname": "delta_fs.img"
        },
        {
            "cmd": "validate_l2_images",
            "partition_name": "gos0-fs",
            "data_size": 4294967296,
            "hash_algorithm": "sha256",
            "hash": "271030c74635cc3b08ddb34362506075b3065859dc03524440bb8a62b80db49e"
        },
        {
            "cmd":"install_l2_images",
            "partition_type":"single",
            "erase_pad_flag":"1",
            "partition_name":"pvit",
            "img_type":"full",
            "img_fname":"$CONTENT_ROOT$A_PVIT_Image_zerosign.bin"
        },
        {
            "cmd":"validate_l2_images",
            "partition_name":"pvit",
            "hash_algorithm":"sha512",
            "data_size":12848,
            "hash":"<updated the hash of this file>"
        },
        {
            "cmd": "install_unlock"
        }
    ]
}

Please make sure that the delta is applied on the right version of the image. If you flash the device using bootburn and generate delta on images generated using create_bsp tools then delta is not generated on a right image. Two FS images generated from the same directory at different time stamps will not be the same.

If you are unsure, better way to test is using the metadata file below:

{
    "metaVersion": 2,
    "procedure": [
        {
            "cmd": "install_lock"
        },
        {
            "cmd": "install_l2_images",
            "erase_pad_flag": "1",
            "img_type": "full",
            "partition_type": "single",
            "partition_name": "gos0-fs",
            "img_fname": "<old_fs>.img"
        },
        {
            "cmd": "install_l2_images",
            "erase_pad_flag": "0",
            "img_type": "delta",
            "partition_type": "single",
            "partition_name": "gos0-fs",
            "img_fname": "delta_fs.img"
        },
        {
            "cmd": "validate_l2_images",
            "partition_name": "gos0-fs",
            "data_size": 4294967296,
            "hash_algorithm": "sha256",
            "hash": "271030c74635cc3b08ddb34362506075b3065859dc03524440bb8a62b80db49e"
        },
        {
            "cmd":"install_l2_images",
            "partition_type":"single",
            "erase_pad_flag":"1",
            "partition_name":"pvit",
            "img_type":"full",
            "img_fname":"$CONTENT_ROOT$A_PVIT_Image_zerosign.bin"
        },
        {
            "cmd":"validate_l2_images",
            "partition_name":"pvit",
            "hash_algorithm":"sha512",
            "data_size":12848,
            "hash":"<updated the hash of this file>"
        },
        {
            "cmd": "install_unlock"
        }
    ]
}

Here the <old_fs> image is flashed first to make sure the partition matches the image we are using to generate the delta.

Note

User should make sure the partition content is same as <olds_fs>.img before applying the delta, so if a deployment makes the layout change, User should be careful to use delta update or avoid to use delta update.

Generate Optimal FS Delta (Linux image only)#

Note

  • The nvdiff_fsimg.sh script used in this section is released as reference only and not safety certified.

EXT4 FS allocates super blocks, inodes etc differently every time. The nvdiff_fsimg.sh script is provided as a sample script for generating the optimal delta image on host for Linux. The command line utility readlink is required.

The nvdiff_fsimg.sh script generates delta_fs.img and <orig_fs.img>_mod.img as the output.

nvdiff_fsimg.sh script is part of the SDK release at

drive-linux/samples/driveupdate/delta_tools

nvdiff tool is part of the SDK release at

drive-foundation/tools/driveupdate/delta_tools

Step 1: Copy over the tools nvdiff_script.sh, nvdiff, old_fs.img, new_fs.img to your host PATH. Make sure that the binary “nvdiff” is in your PATH.

Step 2: Run the nvdiff_fsimg.sh script on the host with the following command:

$ sudo sh nvdiff_fsimg.sh <old_fs>.img <new_fs>.img ext4

Step 3: Generate the SHA256/SHA512 of the <orig_fs.img>_mod.img image

# for SHA256
sha256 <orig_fs.img>_mod.img
# for SHA512
sha512 <orig_fs.img>_mod.img

Step 4: Create the metadata file and perform a delta update. Make sure to update the partition_name, img_fname, data_size, hash value etc as per your images.

Note

To make sure EXT4 root filesystem partition remain unchange after booting.

  1. Set root filesystem partition permission to read-only. Add OS_ARGS_ROOT_MOUNT_PER=ro in bind_partition command.

  2. In PCT storage configurations, turn-off EXT4 resizing for root filesystem by adding resize=no

    [partition]
    name=gos0-fs
    allocation_policy=sequential
    filesystem_type=ext4
    size=LINUX_ROOTFS_SIZE
    partition_attribute=<GID_GUEST0_VM+1>
    filename=<PDK_TOP>/drive-linux/filesystem/targetfs.img
    resize=no
    ...
    

Push Mode HOWTO#

Description#

Automotive customers traditionally use UDS to flash ECU’s, and they require this ability for Tegra based system. UDS requires a “push model” where the UDS programmer pushes update data to the system (UDS writes to DU), where DU does not have the full control over what order the data will be written in.

Note

  • The partitions (except BRBCT) in the first level PT cannot be updated in Push mode. These partitions need to be updated with install_* DU TII commands when Push mode is disabled.

  • The partitions in the first level PT cannot be validated in Push mode.

Note

When Update BRBCT, we should write a whole copy of BRBCT (8KB) at once. In Orin, the copy cannot have OEM public key changed and cannot contain revoke bits.

Note

DU only handle one write or validate at a time on push mode.

Note

For gpt, DU will export dulink nodes “primary-gpt.bin” and “second-gpt.bin” node to map primary gpt and second gpt.

Push Mode Deployment Flow#

The following diagram shows the DU package deployment flow using the Push client as the OTA application.

Diagram

Diagram#

To implement the Push client compliant to the above workflow:

  • Follow the steps 1, 2, 3, and 4 in section Update Workflow to initialize and configure DUCC and DU Link connection, export package files to DU Link, and trigger DU Master to start deploy.

  • TII will enable push mode on “start_push_update” metadata command. Push client needs to wait until TII enable push mode, and this can be done as the following Pseudocode code:

#define CLIENT_NAME          "du-client"
#define EXPORT_PUSH_CB       "push_cb"
#define TA_PUSH_MODE_NOTIFY  "/tii/push_mode.notify"

/*!
 * @brief Deploy function need to register the push_cb to "/tii/push_mode.notify" node
 */
static DU_RCODE deployPackage
(
    char *pPkgPath,
    bool  bExportNeeded,
    bool  bPushMode,
    bool  bControlledMode
)
{
    // ...

    DU_LOG("Deploy mode is %s\n", bPushMode ? "push" : "pull");
    if (bPushMode)
    {
        duRet = dulinkExportFile(EXPORT_PUSH_CB, &cbAttr, pushCB, (void *)pkgLinkPath);
        if (duRet != DU_OK)
        {
            DU_ERR("Error on export %s\n", EXPORT_PUSH_CB);
            goto fail;
        }

        len = snprintf(cbPath, sizeof(cbPath), "+%s/%s/%s", parentPath, CLIENT_NAME, EXPORT_PUSH_CB);
        if (len >= (int32_t)sizeof(cbPath))
        {
            DU_ERR("%s is truncated to %d\n", cbPath, len);
            duRet = DULINK_ERR_BUFFER_TOO_SMALL;
            goto fail;
        }

        duRet = dulinkWrite(TA_PUSH_MODE_NOTIFY, 0, strlen(cbPath), cbPath, &retLen);
        if (duRet != DU_OK)
        {
            DU_ERR("Error on register %s to %s\n", cbPath, TA_PUSH_MODE_NOTIFY);
            goto fail;
        }
        bRmCbPath = true;
    }
    // ...
fail:
    // ...
    return duRet;
}


/*!
 * @brief Callback to be triggered when push mode is enabled
 */
static DU_RCODE pushCB
(
    const char          *pRequestPath,
    const char          *pOriginPath,
    void                *pCtx,
    uint64_t             offset,
    uint64_t             length,
    void                *pBuf,
    DULINK_CB_OPERATION  operation,
    uint64_t            *pRetVal
)
{
    DU_RCODE   duRet = DU_OK;
    char      *pPkgPath = (char *) pCtx;
    pthread_t  threadId;

    if (offset != 0)
    {
        DU_ERR("Invalid offset to cmd\n");
        duRet = DULINK_CB_ERR_INVALID_ARGUMENT;
        goto bailout;
    }

    switch (operation)
    {
        case DULINK_CB_WRITE:
        {
            if (strcmp(pBuf, "enabled") == 0)
            {
                DU_INFO("Start push update!\n");
                if (pthread_create(&threadId, NULL, performPush, pPkgPath) != 0)
                {
                    DU_ERR("Error on pthread_create\n");
                }
                (void) pthread_detach(threadId);
            }
            break;
        }
        case DULINK_CB_READ:
        case DULINK_CB_SIZE:
        default:
        {
            duRet = DULINK_CB_ERR_INVALID_ARGUMENT;
            break;
        }
    }

bailout:
    return duRet;
}
  • Once DU TII enables push mode successfully, Push client can write the image data to the partition storage via DU Link nodes. The DU Link nodes are exported by DU TII, mapping to corresponding inactive partition storages. The name convention of the DU Link nodes are:

    • /tii/content/<partition_name>.bin for L1 partitions, for example, /tii/content/bct.bin.

    • /tii/content/<inactive_bootchain>/<partition_name>.bin for L2 partitions, for example, /tii/content/A-chain/A_mem-bct.bin.

    • /tii/content/<inactive_bootchain>/<container_name>/<partition_name>.bin for L3 partitions, for example, /tii/content/A-chain/A_qnx-gos0/A_1_kernel-dtb.bin.

  • Push client should manage the mapping between partitions and image files by itself to ensure that the partition is updated with the correct image file.

Updating a PT partition may result in partition layout change, therefore Push client must request DU TII to reload PT as soon as it finishes the update of the PT partition before it updates any later partitions. This can be done as the following:

dulinkWrite("/tii/push_mode", 0, sizeof("reload"), "reload", &retLen);

When Push client complete the partition updates, it should disable DU TII push mode, so that DU TII can resume execution of subsequent metadata commands. This can be done as the following:

dulinkWrite("/tii/push_mode", 0, sizeof("disabled"), "disabled", &retLen);
  • Follow the Step 5 in section Update Workflow to wait until the deployment is completed.

Example DU TII Metadata#

The following is an example of DU TII Metadata for Push mode.

{
    "metaVersion": 2,
    "procedure": [
        {
            "cmd": "install_lock"
        },
        {
            "cmd": "start_push_update"
        },
        {
            "cmd": "install_unlock"
        }
    ]
}

The workflow of the above metadata file is as the followings:

  • Lock inactive bootchain with install_lock command. Inactive chain will not be able to boot up after lock.

  • DU TII enables push mode on start_push_mode metadata command.

    • TII stops executing the subsequent validation commands

    • TII mounts all inactive chain partitions and expose the partition storage as DU Link file nodes with write only permission.

    • The user updates inactive partitions by writing to the DU Link file nodes mapped to corresponding inactive partition storages. Any written partitions are marked as dirty and will be marked as clean once it is validated by user.

An image update map with validation information is provided by users. A sample of push_image_map.json is shown as below.

{
    "L1-partitions":[],
    "A-chain":[
        {
            "partition":"/tii/content/bct.bin",
            "image":"tii-a/A_bct_BR_zerosign.bct"
        },
        {
            "partition":"/tii/content/A_qspi_chain.bin",
            "image":"tii-a/A_1_PT.bin"
        },
        {
            "validate_p":"/tii/content/A_qspi_chain.bin",
            "hash_algorithm":"sha256",
            "data_size":262144,
            "hash":"186e1206dcb8ac26f773d27e602b5a8dcf7358be4176970e2a9fe168af37a4e4"
        },
        {
            "reload":"/tii/push_mode"
        },
        {
            "partition":"/tii/content/A-chain/A_mb1-bootloader.bin",
            "image":"tii-a/A_2_mb1_t234_dev_zerosign.bin"
        },
        {
            "validate_p":"/tii/content/A-chain/A_mb1-bootloader.bin",
            "hash_algorithm":"sha256",
            "data_size":246272,
            "hash":"93d79f65f52610f1abb268e2bb56828ba173167bf1289d42859bb5a217b011a8"
        }
    ],
    "B-chain":[
        {
            "partition":"/tii/content/bct.bin",
            "image":"tii-a/A_bct_BR_zerosign.bct"
        },
        {
            "partition":"/tii/content/B_qspi_chain.bin",
            "image":"tii-a/A_1_PT.bin"
        },
        {
            "validate_p":"/tii/content/B_qspi_chain.bin",
            "hash_algorithm":"sha256",
            "data_size":262144,
            "hash":"186e1206dcb8ac26f773d27e602b5a8dcf7358be4176970e2a9fe168af37a4e4"
        },
        {
            "reload":"/tii/push_mode"
        },
        {
            "partition":"/tii/content/B-chain/B_mb1-bootloader.bin",
            "image":"tii-a/A_2_mb1_t234_dev_zerosign.bin"
        },
        {
            "validate_p":"/tii/content/B-chain/B_mb1-bootloader.bin",
            "hash_algorithm":"sha256",
            "data_size":246272,
            "hash":"93d79f65f52610f1abb268e2bb56828ba173167bf1289d42859bb5a217b011a8"
        }
    ]
}

The workflow of on demand validation is as the followings:

  • When TII enables push mode successfully, Push client should set TII enter validating mode with below command.

dulinkWrite("/tii/push_mode", 0, sizeof("validating"), "validating", &retLen);
  • Once TII enter validating mode, Push client can validate partitions by writing the validation informations include hash_algorithm, data_size and hash to partithon node via DU LINK. An example would be to send the following JSON file like: { “validate_p”:”/tii/content/A_qspi_chain.bin”, “hash_algorithm”:”sha256”, “data_size”:262144, “hash”:”fde0fd6bf5d9fd6271be30546effa52fba87a83dc2de02be76708e9af5c1eeac” },

Note

“validate_p” indicates the partition want to validate, this JSON element is needed only for push client. TII requires the remaining three elements: “hash_algorithm”, “data_size”, and “hash”.

  • After validation succeed, Push client should set TII into enable mode with below command to update next partition.

dulinkWrite("/tii/push_mode", 0, sizeof("enabled"), "enabled", &retLen);

Note

Push client must set TII to validating mode each time when want to do a validation, and set TII back to enable mode after validation succeed. Push client can ony set TII enter validating mode from enable mode and switch back to enable mode from validating mode, set TII into enable mode from disable mode is not allowed.

Note

When Push mode is enabled, the progress of deployment is not updated because Drive Update is not aware of the total size of the payload to be updated by the user.

  • The user disables push mode by writing “disabled” to TII /tii/push_mode DU Link file node. TII unmounts all of the DU Link nodes of inactive partitions, and then complete command “start_push_update” with success.

    • DU TII validates updated partitions according to the validation information in image update map. All validated partitions are marked as clean.

Note

When write/validate/read partitions failed in push mode, if user doesn’t want to write/validate/read partitions in push mode, user is recommended to abort the deployment to let the deployment failed but not disable push mode to complete the command “start_push_update” and let the deployment continue.

DUPKG for Push Mode#

Generate Push Mode DU Package#

Make sure you have built the SDK image successfully, then running the following command to generate DU Package with validation.

Generate Push Mode DU Package for QNX

# DUPKG Version: 1.6.0
TEGRA_A_SRC=<path_to_source_image>
OUTPUT_FOLDER=<path_to_empty_folder>
TEMPLATE=dupkg_push_template

python3 dupkg.py gen --in TII_META_VER=metav2 VALIDATE_OPTION=True TEGRA_A_SRC=$TEGRA_A_SRC --template $TEMPLATE --out $OUTPUT_FOLDER

Generate Push Mode DU Package for Linux

# DUPKG Version: 1.6.0
TEGRA_A_SRC=<path_to_source_image>
OUTPUT_FOLDER=<path_to_empty_folder>
TEMPLATE=dupkg_push_template

python3 dupkg.py gen --in TII_META_VER=metav2 VALIDATE_OPTION=True TEGRA_A_SRC=$TEGRA_A_SRC --template $TEMPLATE --out $OUTPUT_FOLDER
Deploy to Target#
  1. copy the sample_driveupdate, content_server and DU package to target

  2. deploy on target use the following commands

./content_server <path_to_package> &
./sample_driveupdate -p /content/files --push

Example Deploy Log

# ./content_server <path_to_package> &
# ./sample_driveupdate -p /content/files --push
Deploy mode is push
Current state: STATE_DORMANT
Update is waiting for higher run level 4
Current state: STATE_UPDATE_IN_PROGRESS, progress 0%
Reading image mapping from /content/files/tii-a/push_image_map.json
Image    0: /content/files/tii-a/A_2_1_PT.bin, partition: /tii/content/B-chain/B_qnx-update.bin
Current state: STATE_UPDATE_IN_PROGRESS, progress 100%
Current state: STATE_UP_TO_DATE, exit sample app
[Result]Deploy OK!

Push Mode HOWTO Dtb#

Description#

User can use push mode with meta_only == 1 to request DRIVE Update to export partitions content configured in device tree.

Configure device tree before flashing the board#

Configure the nodes info to the dts tegra264-driveupdate.dtsi (Thor) / tegra234-driveupdate.dtsi (Orin) to “/chosen/driveupdate/”.

Below is the example of Thor:

export_nodes_list {
        node1 {
                partition = "qspi_chain";
                size = "1024";
                offset = "1024";
        };
        node2 {
                partition = "ufs_chain";
                size = "1024";
                offset = "1024";
        };
};
  • node1 will be related to partition qspi_chain in inactive chain offset == 1024, size == 1024.

  • node2 will be related to partition ufs_chain in inactive chain offset == 1024, size == 1024.

Below is the example of Orin:

export_nodes_list {
        node1 {
                partition = "emmc_chain";
                size = "1024";
                offset = "1024";
        };
        node2 {
                partition = "emmc_chain";
                size = "1024";
                offset = "1024";
        };
        node3 {
                partition = "ufs_chain";
                size = "1024";
                offset = "1024";
        };
};
  • node1 will be related to partition emmc_chain in inactive chain offset == 1024, size == 1024.

  • node2 will be related to partition emmc_chain in inactive chain offset == 1024, size == 1024.

  • node3 will be related to partition ufs_chain in inactive chain offset == 1024, size == 1024.

This is the location of device tree

/drive/drive-foundation/platform-config/hardware/nvidia/platform/t264/automotive/kernel-dts/common/tegra264-driveupdate.dtsi  // Thor
/drive-foundation/platform-config/hardware/nvidia/platform/t23x/automotive/kernel-dts/common/qnx/tegra234-driveupdate.dtsi    // Orin (QNX)
/drive-foundation/platform-config/hardware/nvidia/platform/t23x/automotive/kernel-dts/common/linux/tegra234-driveupdate.dtsi  // Orin (Linux)

Note

Only export the partition in inactive chain in this push mode.

Note

The partition doesn’t include the chain label, DRIVE Update will add inactive chain label to the partition.

Note

The max number of exported nodes is 64.

Note

Export gpt partition in this push mode is not supported.

Note

When export a node related to mb1, data read would be incorrect.

Note

The offet + size of node can’t exceed the size of partition.

Note

The nodes’ offset and size can overlay each other.

Request DU to export the nodes configured in dtb#

User should send a deployment request to DU to export the nodes configured in DTB. The following is an example of metadata.json:

{
    "metaVersion":2,
    "procedure":[
        {
            "cmd":"install_lock"
        },
        {
            "cmd":"start_push_update",
            "meta_only": 1
        },
        {
            "cmd":"install_unlock"
        }
    ]
}

Read the partition content#

During deployment, if DRIVE Update successes to go to push mode, the deployment will be blocked, the value of dulink node “/tii/push_mode” will become “enabled”, and then we can see the nodes “node1”, “node2”, “node3” in /tii/content/.

For example, if we dulinkRead /tii/content/node1 with offset == 0, size == 512, then we will get the content of inactive chain partition “emmc_chain” with offset == 1024, size == 512.

Disable the push_mode and unblock the deployment#

When Push client complete the partition reads, it should disable DU TII push mode, so that DU TII can resume execution of subsequent metadata commands. This can be done as the following:

dulinkWrite("/tii/push_mode", 0, sizeof("disabled"), "disabled", &retLen);

Note

Push Mode with meta_only == 1 is not supported in 7.0.1.0.

DUS Client HOWTO#

DUS_Client HOWTO#

DUS Client provides a lib(libnvdusclient.so) for users to communicate with driveupdate server in HV RTOS. For Linux, see Security Hardening IPC Parameters to develop customer application that use the IPC Channel.

Note

  • As DU TII uses DUS client API with pre-defined IVC channe by default at boot, if user need to use DUS client, they can disable DU TII. User can define below macro to disable all the units (include DU TII) in Guest OS.

ENABLE_GUEST_OS_DU_APP := n
  • If user uses above macro to disable Guest OS units, they will lose the security feature in all the Guest OS drive update units, such as dutii, etc.

  • If user needs to use DUCC interface, please make sure this macro is set to “y”. It’s set “y” by default.

ENABLE_GUEST_OS_DU_APP := y

APIs and Data Structures definitions#

Please refer dus_common_data.h and dus_client.h.

Initialize the dusclient config#
  • duscInit will help to initialize the IVC channel by name(“nvdriveupdate_ivc_1”) and reserve the Mempool by ID(73).

    • It is thread-safe as the dependent nvsciipc will guarantee only 1 thread can access the IVC channel.

duscInit();
Deinitialize the dusclient config#
  • duscDeinit should be called when the users need to stop or quit the communication with DUS

    • It will release the IVC channel and Mempool.

duscDeinit();
Execute the IVC command#
  • duscExecute will send and receive IVC/Mempool data to/from DU server.

    • It will also help to parse the input from caller and output from the DU server.

*DUSCLIENT_ERROR duscExecute(uint32_t cmd, uint8_t targetBootchain, uint8_t *pPayload, uint32_t payloadLen, uint8_t *pBuf, uint32_t *pBufLen);

  • cmd: IVC command ID, required for running IVC command.

  • targetBootchain: Target bootchain, required for Apply Payload Command.

  • pPayload: Payload address, required for the Apply Payload Command.

  • payloadLen: Payload length, required for the Apply Payload Command.

  • pBuf: Buffer for receiving data from DU Server, optional, provided if user need to receive data from DU Server.

  • pBufLen: The size of pBuf, optional, provided if user need to receive data from DU Server.

duscExecute(CMD_GET_PT_LOG, CHAIN_INVALID, NULL, 0, (uint8_t *)pt, &ptLength);
...
duscExecute(CMD_APPLY_PAYLOAD, targetBootchain, payloadBuf, payloadFileLen, NULL, NULL);

Update GPT Partitions#

DRIVE Update provides DU TII metadata commands for GPT partition updates, please refer DU TII metadata Syntax for more information.

Except for push mode, the DU TII metadata commands for GPT images would be included by default in metadata.json generated by dupkg tool.

{
    "metaVersion":2,
    "procedure": [
        {
            "cmd": "install_lock"
        },
        {
            "cmd": "install_l3_gpt",
            "container_pname": "custom",
            "prim_gpt_fname": "A_1_customGPT_pri00_03.bin",
            "sec_gpt_fname": "A_1_customGPT_bak00_03.bin"
        },
        {
            "cmd": "install_l3_gpt_images",
            "container_pname": "custom",
            "partition_type": "group",
            "img_group": [
                {
                    "partition_name": "samplep1",
                    "img_type": "full",
                    "img_fname": "samplep1.img",
                    "erase_pad_flag": "1"
                },
                {
                    "partition_name": "samplep2",
                    "img_type": "full",
                    "img_fname": "samplep2.img",
                    "erase_pad_flag": "1"
                },
                {
                    "partition_name": "samplep3",
                    "img_type": "full",
                    "img_fname": "samplep3.img",
                    "erase_pad_flag": "1"
                }
            ]
        },
        {
            "cmd":"validate_l3_gpt_images",
            "container_pname": "custom",
            "partition_name":"samplep1",
            "hash_algorithm":"sha256",
            "data_size":2888,
            "hash":"a4e2a83b57d57558fcb250f0f7d37cbdb232df6ea5d197fdc5b16fc2c3808670"
        },
        {
            "cmd":"validate_l3_gpt_images",
            "container_pname": "custom",
            "partition_name":"samplep2",
            "hash_algorithm":"sha256",
            "data_size":2888,
            "hash":"a4e2a83b57d57558fcb250f0f7d37cbdb232df6ea5d197fdc5b16fc2c3808670"
        },
        {
            "cmd":"validate_l3_gpt_images",
            "container_pname": "custom",
            "partition_name":"samplep3",
            "hash_algorithm":"sha256",
            "data_size":2888,
            "hash":"a4e2a83b57d57558fcb250f0f7d37cbdb232df6ea5d197fdc5b16fc2c3808670"
        },
        {
            "cmd": "install_unlock"
        }
    ]
}

Make sure the GPT partition table is flashed before attempting to run install_l3_gpt_images; otherwise, the command fails with “partition not found” errors.

Note

For how to add GPT L3 partitions, please refer “GPT L3 Support” section in NVIDIA DriveOS QNX SDK API Reference. (NVIDIA DriveOS QNX SDK API Reference → Virtualization Guide → Supported Platform Configurations → AV PCT Configuration → Storage Layout for Update VM → GPT L3 Support)

Revoke Key HOWTO#

Users can revoke the key flashed on the target by updating the inactive chain, L1PT partition boot component header and the BRBCT partition.

Revoke Key Update#

User can use the Drive Update Package generated with dupkg_revoke_key_template and then deploy the Drive Update Package to the target.

Use ‘dupkg lsin –template dupkg_revoke_key_template’ to see input arguments:

 Input Variable       | Req / Opt   | Description
----------------------+-------------+-----------------------------------------------------------------------------------------------
 TEGRA_A_SRC          | Required    | Path to folder containing Tegra images, filesToFlash.txt
 VALIDATE_OPTION      | Optional    | If enable validate command [True | False]
 ERASE_PADDING_FLAG   | Optional    | If enable erase padding [0 | 1]
 AUTHENTICATOR_OPTION | Optional    | Set "AuthPkg" if enable Authenticator, Default is NormalPkg
 PRIVATE_KEY_PATH     | Optional    | The path to private key file. Required if enable Authenticator
 TEGRASIGN_PATH       | Optional    | The path to the tegrasign_v3.py tool in the PDK. Required if enable Authenticator and use HSM
 SHA_ALG              | Optional    | The SHA algorithm using for validation. Default is SHA256
 OS_VERSION           | Optional    | The OS version of images to generate DU package. Default is 6.0.8.0

Deploy the Drive Update Package generated with dupkg_revoke_key_template include the follow:

  1. Update images signed by new OEM public key to inactive chain.

  2. For Orin, Update the L1PT BCH and BRBCT. For Thor, update the inactive chain BRBCT and update one L1PT copy BCH.

  3. Reboot to inactive chain.

  4. Invoke boot health check.

  5. Set default chain to inactive.

  6. For Thor, update the other L1PT copy BCH.

Note

In Thor, the Revoke key cannot revoke the OEM key used in active chain and the OEM key used in the brbct image. So, if the user wants to revoke the OEM key used in active chain, then the user should switch to other OEM key in active chain and then try to revoke the OEM key.

Streaming From External Device#

The default Content Server released by DRIVE Update always exports the files from the local filesystem of Guest OS, as per the list_of_files.json file. If the user wants to perform updates by streaming DU package files from external device via network, instead of from Guest OS, then the Remote Content Provider plug-in should be implemented to support exports the files to DU Link from network locations.

The Remote Content Provider is running in Guest OS. The sample implementation is packaged in the DriveOS release build in the ${NV_WORKSPACE}/samples/driveupdate/remote_content_provider folder. Refer to the README.txt for information about how to build and use it.

Sample Applications#

DRIVE Update provides sample applications to help users to develop their own applications.

Note

None of the sample source code is safety certified. The sample applications should not be used in production but only provide a demonstration for user to implement his own applications. For Linux, see Security Hardening IPC Parameters to develop customer application that use the IPC Channel.

sample_driveupdate#

It is a sample DRIVE Update client application which can be used as a reference to implement the basic Update Workflow in OTA application.

It works together with the sample Content Server or Remote Content Provider.

sample_driveupdate provides interaction mode, this is specifically useful for the safety environment.

Typical deployment steps in safety environment are:

  1. Start sample_driveupdate in interaction mode in DVMS init state.

  2. (Optional) Set DVMS to operational mode.

  3. Start deploy by typing: package /content/files –auth.

  4. (Optional) User can do abort and re-deploy.

  5. (Optional) If reboot, repeat step 1, 2 to continue previous deployment.

  6. Set DVMS to deinit, now user can exit sample_driveupdate.

Currently support operations in sample_driveupdate.

help(--help, -h)
        Print this help info

shell <cmdline>
        Execute shell command

package(--package, -p) <DUPKG> [options]
        Trigger installation of particular DUPKG
        The DUPKG should be already present in DULINK space
        By DUPKG specification, du_master.json should be present directly under given dulink path
        This parameter can be used with remote_content_privoder to use their functionality to host DUPKG
        Example usage: package /content/files
    -t, --auth
        Force check authenticate packages
    -u, --push
        This flag indicates this update would run in push mode
        In push mode, sample_driveupdate would actively write to storage
        [NOTE]sample_driveupdate only support push updates for TA
    -c, --target-controlled
        This flag indicates this update would interact with user
        User will explicitly type "y" to raise run level

abort(-a)
        Force abort any on-going installation

query_bootchain(-q)
        Query which bootchain either Tegra is on
        A is Chain-A and B is Chain-B

part_ver(--part_ver, -g)
        Print all the partitions version in PVIT

set_runlevel(--set_runlevel, -s) <runlevel>
        Set Runlevel from 0 to 6
        Example usage: set_runlevel 3

print_status(--print_status, -d) on/off
        Enable/Disable regular deployment status print
        [NOTE] Command only be supported in interaction mode
        Example usage: print_status on

du_read(--du_read, -r) src dst(optional)
        dulinkRead a node to a local file(dst)
        Example usage: du_read /content/node
        Example usage: du_read /content/node /home/nvidia/file

du_write(--du_write, -w) data dst
        dulinkWrite data to node(dst)
        Example usage: du_write abc /content/node

du_list(--du_list, -l) directory
        List the nodes in directory
        Example usage: du_list /content

exit
        Exit sample

Content Server#

A sample application of content provider plug-in which serves local package files to DU-Link.

Content Server provides user the following interface via DU Link network.

Interface Path

Command String

Description

/content/cmd

serve local_path={local_ path}

This command tells Content Server to export files located at {local_path} under “content” subdirectory of the Content Server. Only files listed in list_of_files.json are exported. Content Server transitions to CONFIGURED state after this command and stay in this state until configuration is cleared. This command may only be written if the plug-in state is IDLE.

/content/cmd

stop_serving

This command tells the Content Server to stop serving any content (unlink all served files under “content” subdirectory). Content Server transitions to IDLE state after this command.

The examples of update package organization, metadata and sample source code in this document, are all based on the sample Content Server.

Note in safety build, content server can only start in DVMS init phase.

Remote Content Provider#

It is a sample content provider plug-in which can serve files based on URL to DU-Link. Refer Streaming From External Device for more information.

Note in safety build, remote content server can only start in DVMS init phase.

Sample Installer#

Sample Installer is intended to be an example for developers writing installer plugins for Drive Update. It exports all DU Link nodes required in the Drive Update installer plugin spec, and can perform a simple mock installation which installs a file to the local directory where the sample is being run.

Note

  • In safety build, Sample Installer can only start in DVMS init phase.

  • In safety build, we need enable dulink port for Sample Installer, for example:

drive-foundation-safety/platform-config/hardware/nvidia/platform/t23x/automotive/kernel-dts/common/qnx/tegra234-driveupdate.dtsi

plugin {
        remote-path = "/plugin";
        compatible = "nvidia,dulink-connection";
        type = "DOWNLINK";
        tr-type = "NVSCI";
        tr-params = "nvdu_gos_ipc_g_0", "nvdu_gos_ipc_g_1";
};

BHC User Test Function#

It is an example of BHC interface usage. Refer BHC Interface for more information.

Delta Update Tools#

These are sample application tools for Delta Update. Please refer Delta Update HOWTO for more information.

Decompressor HOWTO#

Decompressor is a file transformer type plug-in. To support streaming services, the files are compressed and decompressed at block level.

Decompressor Configuration JSON (decomp_config.json)#

The configuration file contain the following information,

  • metaVersion: Version of this metadata file

  • Files: Contains information on a list of files that needs to be decompressed

Each file inside the list of Files, will contain the following information,

  • src: Path to source file

  • dst: Information of the exported file under decompressor

    • filename: Path of the exported file under decompressor

    • read_acl: ACL permission of the destination fileThe decompressor configuration file will look as below

{
    "metaVersion": 1,
    "metaId": "NV-DU-DECOMPRESSOR-CONFIG",
    "Files": [
        {
            "src": "$CONTENT_ROOT$/file1.zip",
            "dst": {
                "filename": "/decomp/content/file1",
                "read_acl": ["/auth"]
            }
        },
        {
            "src": "$CONTENT_ROOT$/file2.zip",
            "dst": {
                "filename": "/decomp/content/file2",
                "read_acl": ["/tii"]
            }
        },
        {
            "src": "$CONTENT_ROOT$/file3.zip",
            "dst": {
                "filename": "/decomp/content/file3",
                "read_acl": ["/tii"]
            }
        }
    ]
}
  • The maximum number of files supported in decomp_config.json is 150.

  • The maximum size of decomp_config.json supported is 64KB.

Note

The destination file exported by Decompressor is not writeable

Decompressor will always read from Authenticator (except when authentication is disabled, see How to Disable Authentication). Following are the possibilities in the data flow,

  • For all files other than L2 & L3 images, either:

    • CONTENT_SERVER→AUTHENTICATOR→DECOMPRESSOR→AUTHENTICATOR→READING_PLUG_IN

    • CONTENT_SERVER→AUTHENTICATOR→READING_PLUG_IN

  • For L2 & L3 images, either:

    • CONTENT_SERVER→AUTHENTICATOR→DECOMPRESSOR→TII

    • CONTENT_SERVER→TII

Compressed File Header Structure#

Each compressed file will have a header at the start of the file and will be constructed in “Little” endian format. Header contains the following information,

Byte(s)

Name

Description

11

Magic Field

Schema identifier. Always set to value ”NVDU-DECOMP”.

1

Version

Schema version of header file. Currently 0x01.

1

Compression method

Compression method used. Supported compression methods are

  • 0x00: No compression

  • 0x01: zlib (deflate) – zip format

8

Uncompressed size

Uncompressed size of the file

8

Offset

Address to start of Data OR size of the header

4

Block size

Size of the blocks considered for compression

4

No. of blocks

Total number of blocks compressed in this file

8

Block1 compressed size

Compressed size of Block 1

8

∑(Block1,Block2) compressed size

Compressed size of sum of Block 1 and Block 2

8

∑(Block1,Block3) compressed size

Compressed size of sum of (Block 1 to Block 3)

8

.

.

8

.

.

8

.

.

8

∑(Block1,BlockN) compressed size

Compressed size of sum of (Block 1 to Block N)

Data

Note

The size of the header varies depending on the number of blocks compressed.

DDU Tools HOWTO#

Direct Drive Update(DDU) Tools is a python script tool which can run under Linux Host to update the target system remotely over the Internet. It also can run under Linux Target to update local system.

Generate DU package by DUPKG Tool#

Please refer DUPKG Authentication HOWTO.

Figure out Target IP#

If you running DDU tool on host PC. Be sure you have already noted down you remote target’s IP. Following commands are examples to run on target terminal.

Get remote target IP under Linux

$ ip a show eth0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}'
# example: 10.190.1.50

Get remote target IP under QNX

$ ifconfig eq0 | grep 'inet '
inet 10.110.30.105 netmask 0xfffffe00 broadcast 10.190.1.50
# example: 10.190.1.50

Install DDU Tools to local#

DDU Tools could be installed from Release SDK.

# example: Extract DDU Tools to Linux Host
# DDU Tools should be already available with SDK installation. If the DDU Tools is not available, find the specific debian package
# example: A debian package named with this format "nv-driveos-foundation-release-sdk-core-flash-tools*.deb"
$ cp <path_to_your_deb> <your_workspace>
# Export Install dir
$ export NV_WORKSPACE=<your_workspace>
$ sudo -E dpkg -i <your_deb>
# Note: this is an example to install single deb, you could use your own way to install

After install SDK to local enviroment

# Go to the SDK installation path
$ cd <path to>/drive-foundation/tools/driveupdate/directdu

Use DDU Tools to Install DUPKG to Remote Target#

If you perform DDU while OTA is in progress. It will fail.

Install DUPKG to Remote Target

# We recommmand to use python3
$ python3 direct_driveupdate.py -v -p <path to DUPKG> -t <Target Ip> -l log
# example: python3 direct_driveupdate.py -v -p ./out_dupkg -t 10.190.1.50 -l log

Update finish.

$ python3 direct_driveupdate.py -v -p ./out_dupkg -t 10.190.1.50 -l log
Progress: [****************************************] 100 %

Recovery Mode HOWTO#

Users can update L1PT and non-L1PT partitions independently in recovery mode by using the L1PT Repartition Template and Only Install Template. In recovery mode, chain C is active, and chain A should remain inactive.

Note

For a description of the update procedure, see Perform Updates.

For details on how to use the templates:

Only Install Template

  1. When generating the template, add the UPDATE_RECOVERY_CHAIN=False parameter:

    $ python3 dupkg.py gen --in \
      TII_META_VER=metav2 \
      VALIDATE_OPTION=True \
      TEGRA_A_SRC=$TEGRA_A_SRC \
      AUTHENTICATOR_OPTION=AuthPkg \
      PRIVATE_KEY_PATH=$PRIVATE_KEY_PATH \
      UPDATE_RECOVERY_CHAIN=False \
      --template dupkg_only_install_template \
      --out $OUTPUT_FOLDER
    
  2. After updating using the template, manually reboot to the new chain.

L1PT Repartition Template

  • This template does not support Auth enforcement. If you need to use this template, disable Auth enforcement.

Customizing Chain C for DRIVE Update#

Because the default chain C image does not include DRIVE Update plug-ins, additional customization is required to package and launch the required components.

The following steps outline how to customize the chain C image for DRIVE Update:

  1. Add the required DRIVE Update components to the chain C image.

    By default, the chain C image does not include DRIVE Update binaries to allow for flexibility during development. To enable update functionality in chain C, copy the following plug-ins to /usr/bin:

    • dulink_router

    • dumaster

    • ctx_store

    • bootmgr

    • dutii (dutii.t26x or dutii.t23x)

    • du_auth

    • nvpkcs11_kat

    These binaries are available in the release Docker image at the following location:

    /drive/drive-linux/filesystem/contents/bin
    
  2. Flash and boot into chain C.

    After flashing the system and booting into chain C, start the Security Service and DRIVE Update plug-ins in the following sequence, which assumes the plug-ins were placed in /usr/bin:

    /usr/bin/nvpkcs11_kat &
    sleep 0.5
    /usr/bin/dulink_router &
    sleep 0.5
    /usr/bin/dumaster &
    sleep 0.5
    /usr/bin/ctx_store &
    sleep 0.5
    /usr/bin/dubhc_plugin &
    sleep 0.5
    /usr/bin/bootmgr &
    sleep 0.5
    /usr/bin/mcc_daemon &
    sleep 0.5
    /usr/bin/dutii &
    sleep 0.5
    /usr/bin/du_auth &
    sleep 0.5
    
  3. Perform the DRIVE Update.

    After all plug-ins are running, complete the DRIVE Update process by following the instructions in Perform Updates.

Update L1PT partition#

In recovery mode it could update partition of level 1 partition table (L1PT) and the layout could be changed. The target is to be repartitioned for the update and the repartition action is indicated by the argument “repartitioning = 1” in metadata. User could also manually set the repartitioning to 0 not to repartition the target for the update.

The following is an example of metadata to update L1PT partition with repartition in recovery mode:

{
    "metaVersion":2,
    "procedure":[
        {
            "cmd":"install_l1_pt",
            "partition_name":"pt",
            "pt_path":"$CONTENT_ROOT$2_PT.bin",
            "repartitioning":"1"
        },
        {
            "cmd":"validate_l1_pt",
            "partition_name":"pt",
            "hash_algorithm":"sha256",
            "data_size":524288,
            "hash":"84ae40cd43a8aa36c42f92c3b2207946d2abd165c420b68a21f82de76d4532a5"
        }
    ]
}

Update Non-L1PT partitions#

After the L1PT update the rest of parititons can be updated, which is chain A in recovery mode. By default emmc will be discarded. Later it set default chain to chain A and reboot to it.

Get Partition Version HOWTO#

Partition version is a Drive Update feature that allow users to get the partition version stored in Partitions Version Info Table (PVIT).

Following sections list the steps about how to parse PVIT to get partition version.

Format of PVIT#

The following is a overview of PVIT’s format.

Format of PVIT

Format of PVIT#

  • PVIT BCH: 8192 bytes, the header as PVIT is a NV partition.

  • Table Identifier: 100 bytes, unique number to identify a package.

  • num_entries: 1 byte, number of partition entried in the table.

  • Table version, 4 bytes, version of the table.

  • the following is the format of each entry:

    • Uniqu Name: 26 bytes, the follow is the detail of Uniqu Name

      • The first byte is Ptlevel.

      • The second byte is partition GuestID.

      • The rest bytes is partition name including null termination.

    • Pad1: 2 bytes, must be set to 0x00.

    • Version: 4 bytes, partition version.

    • Attributes: 1 byte, partition attributes, bit 0 set specify NV partition and bit 1 set specify has BCH.

    • bin_size: 8 bytes.

    • Pad2: 3 bytes, must be set to 0x00.

    • SHA512: 64 bytes, SHA of final binary excluding header(BCH) if any.

Note

  • L2 partition GuestID are 0xFF or 0x32.

  • MAX 150 partitions version entries in PVIT.

Note

  • Currently, PVIT only includes L2 and L3 partition version.

How to read the PVIT#

DU-TII exports the PVIT in A, B, C chain to dulink space: “/tii/A_pvit”, “/tii/B_pvit”, “/tii/C_pvit”, if partition not existed, then DU-TII will not export the related node. we can read all the content of PVIT via dulinkRead these nodes (total size if 256KB).

Example to parse PVIT to get partition#

Following is sample code to define struct to parse PVIT:

#define PVIT_MAX_ENTRIES    150U
#define PVIT_LOAD_OFFSET    (24UL * 1024UL)
#define UNIQUE_NAME_SIZE    26U
#define VERSION_SIZE        4U
#define SHA_SIZE            64U
#define PAD_1_SIZE          2U
#define PAD_2_SIZE          3U
#define BIN_SIZE            8U
#define TABLE_ID_SIZE       100U
#define RESERVED_SIZE       3U
#define TABLE_VERSION_SIZE  4U

struct __attribute__((__packed__)) pvit_rec {
    uint8_t unique_name[UNIQUE_NAME_SIZE];
    uint8_t pad1[PAD_1_SIZE];
    uint8_t version[VERSION_SIZE];
    uint8_t attributes;
    uint8_t pad2[PAD_2_SIZE];
    uint8_t bin_size[BIN_SIZE];
    uint8_t sha[SHA_SIZE];
};

struct __attribute__((__packed__)) pvit_header {
    uint8_t table_identifier[TABLE_ID_SIZE];
    uint8_t number_of_entries;
    uint8_t reserved[RESERVED_SIZE];
    uint8_t table_version[TABLE_VERSION_SIZE];
};
struct __attribute__((__packed__)) tegrabl_partition_version_info_table {
    struct pvit_header pvit_table_info;
    struct pvit_rec pvit_entry[PVIT_MAX_ENTRIES];
};

Following is sample code to parse PVIT:

Read PVIT:

dulinkRead("/tii/A_pvit", 0, sizeof(pvitBuf), pvitBuf, &retLen);

Skip BCH:

pvit_t  *pPvit;
pPvit = (pvit_t *) (pvitBuf + 8192);

Parse the entries to get partition version one by one:

for (i = 0U; i < pPvit->pvit_table_info.number_of_entries; i++)
{
    (void) memset(partName, 0, UNIQUE_NAME_SIZE);
    ptLevel = pPvit->pvit_entry[i].unique_name[0];

    if (ptLevel == 2U)
    {
        (void) memcpy(partName, (char *) (pPvit->pvit_entry[i].unique_name) + 2,
                        UNIQUE_NAME_SIZE - 2U);
    }
    else if (ptLevel == 3U)
    {
        partName[0] = pPvit->pvit_entry[i].unique_name[1] + '0';
        partName[1] = '_';
        (void) memcpy(partName + 2, (char *) (pPvit->pvit_entry[i].unique_name) + 2,
                        UNIQUE_NAME_SIZE - 2U);
    }

    DU_LOG("%u. partition name: %s, version: 0x%x-0x%x-0x%x-0x%x\n", i,
            partName,
            pPvit->pvit_entry[i].version[0],
            pPvit->pvit_entry[i].version[1],
            pPvit->pvit_entry[i].version[2],
            pPvit->pvit_entry[i].version[3]);
}

Dual Tegra Configuration#

Description#

This document shows how to configurate Dual Thor to allow automotive customers to perform DU update. This is assuming that Dual Thor is A and B, which communicate via switch.

Note

The Guest OS of Thor A and B needs some changes in the dts file for the Dual Thor DU update to work.

Thor Guest OS Device Tree#

  • Thor A: Please refer to tegra264-driveupdate-A.dtsi as an example.

  • Thor B: Please refer to tegra264-driveupdate-A.dtsi as an example.

/drive/drive-foundation/platform-config/hardware/nvidia/platform/t264/automotive/kernel-dts/common/tegra264-driveupdate-A.dtsi  // Thor A
/drive/drive-foundation/platform-config/hardware/nvidia/platform/t264/automotive/kernel-dts/common/tegra264-driveupdate-B.dtsi  // Thor B
  • tegra264-driveupdate-A.dtsi is included in tegra264-p3960-0030-sw01-t1-av-l-linux-gos.dts and tegra264-p3960-0030-sw01-numa-t1-av-l-linux-gos.dts.

  • tegra264-driveupdate-B.dtsi is included in tegra264-p3960-0030-sw01-t2-av-l-linux-gos.dts and tegra264-p3960-0030-sw01-numa-t2-av-l-linux-gos.dts.

/drive/drive-foundation/platform-config/hardware/nvidia/platform/t264/automotive/kernel-dts/p3960/tegra264-p3960-0030-sw01-t1-av-l-linux-gos.dts
/drive/drive-foundation/platform-config/hardware/nvidia/platform/t264/automotive/kernel-dts/p3960/tegra264-p3960-0030-sw01-numa-t1-av-l-linux-gos.dts
/drive/drive-foundation/platform-config/hardware/nvidia/platform/t264/automotive/kernel-dts/p3960/tegra264-p3960-0030-sw01-t2-av-l-linux-gos.dts
/drive/drive-foundation/platform-config/hardware/nvidia/platform/t264/automotive/kernel-dts/p3960/tegra264-p3960-0030-sw01-numa-t2-av-l-linux-gos.dts

Update Steps#

The update steps are described at Perform Updates.

Configure DU_MCC HOWTO#

Currently DRIVE Update bootmgr uses an MCU library to communicate with MCU to request for board reset, set next bootchain, set default bootchain. MCU library’s location is defined in MCC_LOCATION, when bootmgr boots up, bootmgr will load the MCU library via MCC_LOCATION. So, the user can define their own MCU library and then move the library to “/usr/lib/libdu_mcc.so” in Guest OS VM fs. For Linux, see Security Hardening IPC Parameters to develop customer application that use the IPC Channel.

Note

If there is a libdu_mcc.so in the path, then replace it. If there is not a libdu_mcc.so in the path, then move the library there.

Security Control HOWTO#

This section describes security enforcement and how to disable security enforcement in the device tree. The device tree is in the tegra264-driveupdate.dtsi` file (Thor) or tegra234-driveupdate.dtsi file (Orin).

For example:

/drive/drive-foundation/platform-config/hardware/nvidia/platform/t264/automotive/kernel-dts/common/tegra264-driveupdate.dtsi  // Thor
/drive-foundation/platform-config/hardware/nvidia/platform/t23x/automotive/kernel-dts/common/qnx/tegra234-driveupdate.dtsi    // Orin (QNX)
/drive-foundation/platform-config/hardware/nvidia/platform/t23x/automotive/kernel-dts/common/linux/tegra234-driveupdate.dtsi  // Orin (Linux)

Note

If users choose to disable security enforcement by disabling the device tree node, they must accept the security risk caused by it.

Enforce DRIVE Update Package Digital Signature#

Users can disable enforcement by changing the “disable-auth-enforcement” value to “1” in the device tree. If “disable-auth-enforcement” is not present in the device tree, users can add it and set the value to “1”.

The following example shows how to disable this enforcement in the device tree:

driveupdate {
    disable-auth-enforcement = "1";

User Is Not Allowed to Access the Active Bootchain in Push Mode#

Users can disable this enforcement to access active bootchain in push mode by changing the “allow-read-activechain” value to “1” in the device tree. If “allow-read-activechain” is not present in the device tree, add the parameter and set the value to “1”.

The following example shows how to disable this enforcement in the device tree:

driveupdate {
    allow-read-activechain = "1";

User Is Not Allowed to Access the Inactive Bootchain in Push Mode#

Users can disable this enforcement to access inactive bootchain in push mode by changing the “allow-read-inactivechain” value to “1” in the device tree. If “allow-read-inactivechain” is not present in the device tree, add the parameter and set the value to “1”.

The following example shows how to disable this enforcement in the device tree:

driveupdate {
    allow-read-inactivechain = "1";

User Is Not Allowed to Update Unsigned BR-BRBCT#

Users can disable this enforcement to update unsigned BR-BRBCT by changing the “allow-update-unsigned-customer-data” value to “1” in the device tree. If “allow-update-unsigned-customer-data” is not present in the device tree, add the parameter and set the value to “1”.

The following example shows how to disable this enforcement in the device tree:

driveupdate {
    allow-update-unsigned-customer-data = "1";