.. _SD.Bootloader.UpdateAndRedundancy: .. include:: /content/swdocs.rsts .. spelling:: agx autosync BUP ies nv tx xCAFE Update and Redundancy !!!!!!!!!!!!!!!!!!!!! |NVIDIA(r)| |Jetson(tm)| Linux supports Bootloader update and redundancy on all Jetson platforms. The Bootloader update process performs a safe Bootloader update and ensures that a workable Bootloader partition remains available during an update. It accomplishes this using **A/B update**, a feature that maintains two sets of Bootloader partitions, **Slot A** and **Slot B**, each of which is a complete set of the partitions that contain boot images. **Root file system redundancy** (“rootfs redundancy”) is a feature built upon A/B update, which provides Bootloader redundancy. It automatically maintains the same Bootloader image in both Bootloader slots, allowing a Jetson device to boot from the unused slot if the current slot is corrupted. A/B update and rootfs redundancy reduce the risk of boot failure when Bootloader is updated and when the images in the current Bootloader slot become corrupted. Rootfs redundancy is disabled by default. To enable it, see `Enabling Bootloader Redundancy <#enabling-bootloader-redundancy>`__. A/B Slot Layout @@@@@@@@@@@@@@@ The principle of shadow copying enables multiple placeholders. All of the placeholders but one hold backup copies. Each backup copy is a candidate to boot from. However, based on runtime decisions, the correct copy of the binary is loaded to continue with the boot process. These two shadow copies are commonly referred to as Slot A and Slot B. This two-slot implementation is as follows: .. todo:: This is very hard to understand because it uses undefined terms, and the progression of ideas is not logical. To start with, for example, it says that the principle of shadow copying enables multiple placeholders. Placeholders? What are placeholders? It looks like I (the reader) need to understand that, or nothing that follows will make sense. But I search the rest of the document and find that the term is never used again. I search for "shadow copy," hoping that the explanation of that will shed some light on placeholders, but I find that this term is never used again, either. I took a shot at rewording this more clearly. If we can use this, it probably needs revision, since I really can't understand the original. "A/B slot layout keeps two sets of boot partitions, called slot A and slot B. Normally both slots contain the same software and firmware; one is used to boot and the other is kept as a backup. If a boot fails because the boot copy has become corrupted, the Jetson device can resort to the backup copy. When the boot software is updated, the device initially updates only the backup copy; then it switches the roles of the slots and tries to boot from the updated slot. If this boot succeeds it updates the former boot slot, now the backup slot; if that boot fails it switches the slots' roles again and reboots from the original boot slot." This explanation is written to be logical and self-contained, but because the original text is neither, it duplicates some information presented before and after. Rewriting one part of the explanation will require rewriting others. The following diagram shows the slot implementation in conceptual form. .. todo:: Change CBoot in the following diagram to cpu-bootloader, etc. .. figure:: UpdateAndRedundancy/SlotImplementationLayout.svg :figwidth: 300px A/B System Update @@@@@@@@@@@@@@@@@ An A/B slot update affects these components: - `Partition Selection <#partition-selection>`__ - `Update Engine <#update-engine>`__ Partition Selection ################### A/B system updates use two sets of partitions (slots). Each slot has several attributes: - The slot that the running system booted from is called the **current slot**. The other slot is called the **unused slot**. The system exchanges the roles of the current and unused slot in the course of an update, or when the software fails repeatedly during or immediately after a boot. - The slot that the system will use the next time it boots is called the **active slot**. In "steady state" device the bootable slot is also the active slot. When the system is being updated it may be different. - A slot's **bootable attribute** indicates whether the slot contains a system from which the device should be able to boot. When the system is running the current slot is bootable; the unused slot may have an older, identical, or newer version of the system, and may or may not be bootable. - A slot's **successful attribute** indicates whether the system has successfully booted from the slot. The user space **Update Engine** (UE) sets it the first time a newly updated slot boots successfully to the kernel. It is reset when the slot is updated or a boot attempt from the slot fails (because the slot has been updated with a nonfunctional system or has become corrupted). If a bootable slot fails to boot a certain number of times, Bootloader clears its successful and bootable attributes and switches the roles of the current and unused slots. The formerly unused, now current slot normally contains boot software that is either one update old (if the device was just updated with nonfunctional software) or current (if the current slot has suffered data corruption). Slot status information is kept in a structure stored in the **slot metadata** (SMD) partition: .. figure:: UpdateAndRedundancy/SlotMetadataStructure.svg :figwidth: 650px Where: - ``magic`` holds a fixed value that identifies the SMD partition. - ``version`` holds the version number of the software in this slot. - ``num_slots`` holds the number of slots, which should be 2. - ``boot_slot_info`` is an array of structures which contain information about the slot. In each slot: - ``priority`` holds the priority of this slot. .. todo:: This is a circular definition. - ``suffix`` holds a string, either ``"_a"`` or ``"_b"``, that is suffixed to the names of the partitions in this slot to distinguish them from those in the other slot. .. todo:: Later we say that the suffix of slot A is null for compatibility with non-redundant systems. - ``retry_count`` holds the number of boot retries remaining before Bootloader clears the current slot’s ``successful`` and ``bootable`` attributes and tries to boot from the unused slot. - ``boot_successful`` holds this slot’s successful attribute. The bootable slot is the slot whose ``priority`` and ``retry_count`` are both greater than 0. .. todo:: This won't make sense until ``priority`` is explained. The current slot is the slot with the highest priority and a ``retry_count`` greater than 0. The next boot operation attempts to boot from this slot. Update Engine ############# A/B system update uses the Update Engine to update the A/B slots, and to prepare the system to boot an updated version of Bootloader. The Update Engine performs these actions: 1. Reads ``bl_update_payload`` and writes data to the unused slot’s partitions as instructed by the payload. 2. Calls the ``boot_control`` interface in a predefined workflow. 3. Switches the roles of the current and unused slots. 4. Reboots the system. 5. Updates images on the unused, previously current slot to ensure that both slots contain the update. For more information, see: - `Update Engine Usage <#update-engine-usage>`__ - `Running the Update Engine <#running-the-update-engine>`__ Bootloader Implementation @@@@@@@@@@@@@@@@@@@@@@@@@ The A/B system uses the boot slot metadata to store the slot status. It communicates between the Update Engine and Bootloader. Bootloader runs the state machine to select the boot slot. It handles the update failure cases as follows: .. todo:: What is this paragraph supposed to accomplish? It's not clear what relationship the four constituent sentences have with each other. .. figure:: UpdateAndRedundancy/UpdateFailure.svg :figwidth: 650 px .. todo:: A marginal note in the Word file, dated 4/02/2020: "Jimmy: Please check the diagram for correctness. We published your “sketch” in r32.3 for lack of time. I have now updated the version that conforms to our style guidelines." MB1 uses the slot metadata to find the current slot. It caches the current slot number, 0 (slot A) or 1 (slot B), along with a “valid” flag, in scratch register 99 to be used by MB2, UEFI, or later stage loaders. .. todo:: Where does the "valid" flag come from? Earlier we described each element in the SMD partition, and a "valid" flag was not among them. +------------------------------------+ | Scratch register 99 layout | +----------+-------------------------+ | Bits | Contents | +==========+==========+==============+ | 31-30 | Flag | +----------+-------------------------+ | 29-26 | Slot A retry count | +----------+-------------------------+ | 25-22 | Slot B retry count | +----------+-------------------------+ | 21-19 | Maximum number of slots | +----------+-------------------------+ | 18-16 | Current slot number | +----------+-------------------------+ | 15-0 | Magic pattern 0xCAFE | +----------+-------------------------+ If MB1 does not find a current slot, the device hangs. The name of the partition that is being loaded is derived as follows:: partition_name = _” slot value = “” for slot 0 slot value = “_b” for slot 1 .. todo:: This is an instance of duplicative data. It appears to say the same thing as the description of ``suffix`` under "Partition Selection," but in completely different terms. To be sure they are not missing anything the reader must parse both descriptions, figure out exactly what they are saying, and compare them point by point. In well-organized technical writing each idea is presented once, in the most appropriate manner and place, except in rare instances where duplication serves a specific purpose. Partition Settings ################## The A/B partitions must be named like this: - ``mb1`` - ``mb1_b`` - ``mb2`` - ``mb2_b`` - ``cpu-bootloader`` - ``cpu-bootloader_b`` - etc .. todo:: This is another duplication of the slot naming explanation, in yet another form. The empty suffix for Slot A ensures backward compatibility with legacy partition loading mechanisms that are unaware of A/B slots. Update Engine States #################### The Update Engine (UE), ``nv_update_engine``, uses the slot metadata to instruct Bootloader what slot to boot from. The following sections describe the possible states of the UE. - **Normal**: The system has booted from the current slot. No updates have been applied. The current slot is bootable and successful, and is the active slot. The unused slot is bootable, and has the same contents as the bootable slot. This table shows the status of a system in this state with slot B current and slot A unused. Note that because slot A is current, it has a higher priority than slot B. ====== ======== =========== ======== ========== ======== Slot Priority Retry count Bootable Successful Active ====== ======== =========== ======== ========== ======== Slot A 14 7 0 or 1 1 0 Slot B 15 7 1 1 1 ====== ======== =========== ======== ========== ======== .. todo:: The table shows that the unused slot is successful and may or may not be bootable. I don't understand this. The unused slot has the same contents as the bootable slot, so it should be bootable; but it has not been booted, so it should not be successful. - **Update in progress**: The system has booted from the current slot, and is updating the unused slot. The active slot is bootable and successful. The unused slot is not Bootable because it is in the process of being updated. This table shows the status of a system in this state with slot B current. If the system must reboot in this state, it reboots from slot B. ====== ======== =========== ======== ========== ======== Slot Priority Retry count Bootable Successful Active ====== ======== =========== ======== ========== ======== Slot A 0 0 0 0 0 Slot B 15 7 1 1 1 ====== ======== =========== ======== ========== ======== - **Update complete, reboot pending**: The roles of the current and unused slots are about to be switched. The system will then attempt to boot from the current (formerly unused) slot. The updated slot is made bootable and active, but is not yet marked as successful. Bootloader attempts to boot from the updated slot the specified number of times. This table shows the status of a system in this state with slot A newly updated and the reboot (from slot A) pending. ====== ======== =========== ======== ========== ======== Slot Priority Retry count Bootable Successful Active ====== ======== =========== ======== ========== ======== Slot A 15 7 1 0 1 Slot B 14 7 1 1 0 ====== ======== =========== ======== ========== ======== - **System booted from a newly updated slot**: The formerly current, now unused slot is still marked bootable and successful. The now current slot is bootable and active, but not yet successful. This table shows the status of a system in this state with slot A newly updated and booted for the first time. ====== ======== =========== ======== ========== ======== Slot Priority Retry count Bootable Successful Active ====== ======== =========== ======== ========== ======== Slot A 15 6 1 0 1 Slot B 14 7 1 1 0 ====== ======== =========== ======== ========== ======== After a successful boot and some system checks, the Update Engine marks the now current slot successful. - **Slot duplication in progress**: Having successfully booted the updated slot, the system duplicates its contents to the unused slot. The unused slot is marked not bootable before the update begins, and is marked bootable after it concludes successfully. If the system must reboot while in this state, it boots from the newly updated, now current slot. This table shows the status of a system in this state with slot duplication from slot A to slot B in progress. ====== ======== =========== ======== ========== ======== Slot Priority Retry count Bootable Successful Active ====== ======== =========== ======== ========== ======== Slot A 15 6 1 0 1 Slot B 0 0 0 0 0 ====== ======== =========== ======== ========== ======== - **Slot duplication complete**: The current slot is marked bootable and successful. The unused, newly duplicated slot is marked bootable and successful, but with lower priority. This table shows the status of a system in this state. ====== ======== =========== ======== ========== ======== Slot Priority Retry count Bootable Successful Active ====== ======== =========== ======== ========== ======== Slot A 15 7 1 1 1 Slot B 14 7 1 1 0 ====== ======== =========== ======== ========== ======== - **Boot Failure and Recovery**: The system fails to boot from the current slot due to a nonfunctional update, data corruption, or I/O errors. .. todo:: This is not a state, it is a process! The following description is thus inaccurate. Should we recast it as a series of states, or just describe the process? After the specified number of failed attempts to boot from the current slot, Bootloader clears the current slot's bootable successful attributes, and boots from the unused slot. This table shows the status of a system that has failed to boot from slot A and has recovered by booting from slot B. ====== ======== =========== ======== ========== ======== Slot Priority Retry count Bootable Successful Active ====== ======== =========== ======== ========== ======== Slot A 0 0 0 0 0 Slot B 14 7 1 1 1 ====== ======== =========== ======== ========== ======== .. todo:: Throughout, we're describing a not-active slot in two ways: as not active (active=0), the complementary status, and as "unused," a distinct state. The two descriptions are equivalent, but using both makes the process harder to understand. Which is preferred? In this state the Update Engine is not allowed to duplicate the active slot to the unused slot, nor is it allowed to modify the partition table or the contents of partitions not assigned to slot A or B. Duplication is not allowed until the system has updated the unused slot and booted from it successfully. When the Update Engine is Launched @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ The update engine is launched in these situations: - The user enters the following command, which launches the Update Engine to update software:: $ sudo nv_update_engine --install The Update Engine updates the software by applying a Bootloader update payload (BUP). The BUP must be named ``bl_update_payload``. and must be placed under the directory ``/opt/ota_package``. .. todo:: "Under" means "somewhere in the directory tree descending from this directory." Is that intended? If the BUP must be *in* the specified directory, we should say "in." - The boot service enters the following command to launch the Update Engine during a system boot:: $ sudo nv_update_engine --verify The Update Engine loads the slot metadata, evaluates the current state, and runs a predefined workflow. In a normal boot the Update Engine is in the normal boot state, where no update is applied and a duplicate is not required, so the Update Engine simply exits. If the system is in another boot state, it takes action as appropriate. .. todo:: At the start of the preceding section we described normal, etc., as states of the Update Engine. Here we're describing them as "boot states." Which term is preferred? Enabling Bootloader Redundancy @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ There are two ways of enabling Bootloader redundancy: - Create an SMD image and configure the redundancy settings. - Enable Bootloader redundancy directly with the ``nv_update_engine`` tool. To enable redundancy by creating an SMD image ############################################# 1. Modify the SMD configuration file ``smd_info.cfg`` to enable A/B slots. 2. Run ``nv_smd_generator`` on the host to generate an SMD image with the updated SMD configuration file. Instructions for generating an SMD image are in `SMD Image Generator <#smd-image-generator>`__. 3. Run ``flash.sh`` to flash all partitions to the Jetson device. To enable redundancy with the nv_update_engine ############################################## - Launch ``nv_update_engine`` on the Jetson device to enable A/B update on the flashed device with A/B disabled SMD image. .. todo:: We're enabling A/B update with an "A/B disabled" SMD image? The SMD structure has no element for indicating enabled/disabled status, but if the SMD somehow *is* disabled, that seems to imply that A/B update is disabled. Please clarify. For using ``nv_update_engine`` are in `Running the Update Engine <#running-the-update-engine>`__. Bootloader Tools @@@@@@@@@@@@@@@@ NVIDIA provides tools for ease of use in the Bootloader update process. Boot Control ############ ``nvbootctrl`` loads the SMD image and dumps the slot information. It is intended for debugging use. You can also use it to set the active slot, forcing the boot slot to change for the next boot. To display the command usage, enter the command with no parameters:: $ sudo nvbootctrl .. todo:: When we document a command we should describe its usage. Bootloader Update Payload Generator ################################### .. todo:: From a marginal note dated 9/29/2020: "This says that the script generates a single BUP (for a single device) whose name is unspecified. The corresponding procedure in bootloader_update_nano_tx1.docx, “Generating the Bootloader Update Payload,” describes a somewhat different procedure with the same script (or at least, a script with the same name) and says that it generates multiple BUPs (for multiple devices with the same processor) whose names are specified. Both procedures are described as applicable on all platforms, and should be described in both topics. This information is missing: 1. Location of the file generated by the single-BUP procedure in the Nano/TX1 topic. 2. Reasons why the reader might decide to use one procedure or the other." The Bootloader Update Payload (BUP) is the payload that is applied by the update engine during an update. The BUP is generated by the host tool ``build_l4t_bup.sh``, kept with ``flash.sh`` in the Linux for Jetson Board Support Package (BSP). This section describes procedures for generating a multi-spec BUP or a single-spec BUP. A **multi-spec** BUP includes firmware binaries and BCT images for each supported Jetson device. When you run the updater, it uses the appropriate binary of each type for the device you are updating. A **single-spec** BUP includes firmware binaries and BCT images for just one type of device). It is appropriate if you are updating just one type of Jetson device. To generate a multi-spec BUP $$$$$$$$$$$$$$$$$$$$$$$$$$$$ - Enter the commands:: $ cd $ sudo ./l4t_generate_soc_bup.sh [-u ] [‑p ] [-d] .. todo:: From a marginal note dated 11/19/2020: How can this command have a parameter? If we’re generating a multi-spec BUP, it’s for every processor; that’s what a multi-spec BUP *is*. Where: - ```` is the pathname of the directory that contains the PDK installation package. ``flash.sh`` is in this directory. - ```` is the RSA private key file for your Jetson carrier board. If it is a relative pathname, it is interpreted relative to ``/bootloader/``. - -d makes the script run in debug mode, which keeps all boot firmware blob images in ``bootloader/signed`` and ``bootloader/multi-signed``. - ```` is a string that contains command line options to be passed to ``flash.sh`` to generate the BUP. If the string contains whitespace characters, it must be enclosed in quotes. - ```` is ``t234`` for an |Jetson AGX Orin(tm)| series device, or ``t19x`` for an |NVIDIA(r)| |Jetson Xavier(tm) NX| series or |Jetson AGX Xavier(tm)| series device. .. todo:: I assume. The procedure stores the BUP in the file:: /bootloader//bl_update_payload For more information, see `Generating the Bootloader Update Payload (BUP) <#generating-the-bootloader-update-payload-bup>`__. To generate a single-spec BUP $$$$$$$$$$$$$$$$$$$$$$$$$$$$$ - Enter the command:: $ sudo [env={value}, …] ./build_l4t_bup.sh [options] Where: - ```` is the value of ``$(BOARD)`` for your Jetson module and configuration, as shown by the table in :ref:`Jetson Modules and Configurations ` in the topic :ref:`Quick Start `. - ```` is the partition where the root file system is to be flashed. The procedure stores the BUP in the file:: /bootloader//bl_update_payload For more information, see `Generating the Bootloader Update Payload (BUP) <#generating-the-bootloader-update-payload-bup>`__. Where the BUP File is Stored ############################ Both procedures store the BUP file at:: /bootloader//bl_update_payload Where ```` is: - For Jetson AGX Orin devices: ``payloads_t23x`` .. todo:: I assume. - For Jetson Xavier NX series and Jetson AGX Xavier series devices: ``payloads_t19x`` The multi-spec procedure stores a BUP at each of these locations for the respective group of processors. The single-spec procedure stores a BUP at just one location for the appropriate type of processor. You must place the appropriate BUP file on the target system under this directory before the Update Engine is run:: /opt/ota_package/ SMD Image Generator ################### Run the SMD image generator, ``nv_smd_generator``, on a host system to generate the default SMD image ``slot_metadata.bin`` to be flashed into the SMD partition. To launch the image generator, enter the command:: $ nv_smd_generator Where: - ```` is the SMD configuration file. - ```` is the image file that the image generator is to create. For example:: $ sudo nv_smd_generator smd_info.cfg slot_metadata.bin In the Linux for Jetson Board Support Package, ``nv_smd_generator``, the default SMD configuration file ``smd_info.cfg``, and the default image file ``slot_metadata.bin``, are installed under the directory ``/bootloader``. .. todo:: Again, "under" the directory or "in" the directory? By default, ``smd_info.cfg`` is set to make Slot A the only available slot. This effectively disables redundancy:: < VERSION 4 > # Set the maximum boot slot retry count # Please make sure this field is set before slot info config < MAX_BL_RETRY_COUNT 7 > # # Config 1: Disable A/B support (Default) # # slot info order is important! # 15 _a 1 # # Config 2: Enable redundancy support (by removing comments ##) # ##< REDUNDANCY_USER 1 > # # To disable bootloader autosync, use < BL_AUTOSYNC_DISABLE 1> # REDUNDANCY_ENABLE or REDUNDANCY_USER must be defined before BL_AUTOSYNC DISABLE! ##< BL_AUTOSYNC_DISABLE 1 > # slot info order is important! # ##15 _a 1 ##14 _b 1 Use Config 2 to create the SMD image and enable rootfs redundancy. To enable A/B update and rootfs redundancy $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ 1. Comment out the configuration that disables A/B update by adding ‘#’ to the beginning of the parameter line below Config 1:: 15 _a 1 2. “Uncomment” the configuration that enables A/B update by removing ‘##’ from the beginning of the parameter lines below Config 2:: ##15 _a 1 ##14 _b 1 Now the Bootloader-related partitions, the ``kernel`` partition, and the ``kernel-dtb`` partition all have A/B slots. 3. If you want to enable rootfs redundancy as well as A/B update, uncomment the ```` statement. Replace ``x>`` with a number that specifies the type of redundancy support you want: - 0: For Bootloader only, i.e, from MB1 and MB2 through UEFI. - 1: For Bootloader and images in the ``kernel`` and ``kernel-dtb`` partitions. 4. Bootloader slot duplication is enabled by default. You can disable it by uncommenting the configuration:: ##< BL_AUTOSYNC_DISABLE 1 > Maximum Boot Slot Retry Count $$$$$$$$$$$$$$$$$$$$$$$$$$$$$ ``MAX_BL_RETRY_COUNT`` specifies the maximum boot slot retry count. Its default value is 7. You can set any value between 0 and 7. .. note:: Rootfs redundancy is disabled by default because only one file system partition (``APP``) is created. NVIDIA can provide guidance on enabling rootfs redundancy. .. todo:: From a marginal note, 4/30/2021: Should this be changed to “enabling Bootloader redundancy," along with the corresponding section heading? Running the Update Engine @@@@@@@@@@@@@@@@@@@@@@@@@ You run the Update Engine script on the Jetson device. To enable/disable rootfs redundancy ################################### - To enable redundancy, enter the command:: $ sudo nv_update_engine –-enable-ab - To disable redundancy, enter the command:: $ sudo nv_update_engine –-disable-ab The command fails if the current boot slot is not 0. To Update Bootloader #################### 1. Enter this command on the Jetson device to switch to superuser mode:: $ sudo su 2. Enable rootfs redundancy (a one-time command):: $ nv_update_engine --enable-ab 3. If no BUP directory exists, create one by running the command:: $ mkdir /opt/ota_package 4. To copy the BUP from the host system to the BUP directory, enter the command:: $ scp /opt/ota_package/ Where: - ```` is the location where the BUP is built on the host system. You can also use a USB key to copy the BUP from the host system to the target system. .. todo:: "USB key" implies something having to do with signing or encryption. I think this means "You can also use a flash drive..." - For information about how to generate the BUP, see `Generating the Bootloader Update Payload <#generating-the-bootloader-update-payload>`__. 5. To launch the Update Engine to update Bootloader on the unused slot, enter the command:: $ nv_update_engine --install Update Engine State Machine @@@@@@@@@@@@@@@@@@@@@@@@@@@ This diagram shows the Update Engine state machine's flow: .. figure:: UpdateAndRedundancy/UpdateEngineStateDiagram.svg :figwidth: 650 px .. todo:: This diagram conveys essentially the same information as the section "Update Engine States." Why don't we combine the two, or remove one or the other? Jimmy, email 9/02/2021: "Due to UEFI to replace CBoot, there may be some updates in this diagram. We are now still in experiment stage. Please hold for now. Wei can post you the final result in late October." If we are to keep it, it needs rework. The current diagram exists only as a PNG whose resolution is too low to render the small type readably. Several releases ago I have an equivalent diagram that I drew in Visio, which I could now render as an SVG, but it was rejected as inaccurate for reasons that were never clear to me. There's a much longer marginal note in bootloader_update_agx_tx2.docx, in Perforce, that describes this diagram's shortcomings. Manually Modifying Boot Slots @@@@@@@@@@@@@@@@@@@@@@@@@@@@@ The NVIDIA tool ``nvbootctrl`` switches the boot slots and modifies the SMD partition as needed for testing and development purposes. However, you may also want to switch boot slots or modify the SMD partition manually from user space. To manually modify the boot slots ################################# 1. Enter this command to switch to superuser mode:: $ sudo su 2. Enter this command:: $ nvbootctrl Where ```` one of the values in the following table. +----------------------------------+----------------------------------+ | Command | Description | +==================================+==================================+ | get-number-slots | Printer the number of slots. | +----------------------------------+----------------------------------+ | get-current-slot | Prints the currently running | | | slot. | +----------------------------------+----------------------------------+ | mark-boot-successful | Marks the current slot as GOOD. | | | | | | .. todo:: | | | This is the first | | | reference to a GOOD property. | | | Does this mean successful? | | | | +----------------------------------+----------------------------------+ | set-active-boot-slot | On next boot, loads and executes | | | ````. | +----------------------------------+----------------------------------+ | set-slot-as-unbootable | Marks ```` as invalid. | +----------------------------------+----------------------------------+ | is-slot-bootable | Returns 0 if ```` is | | | bootable. | +----------------------------------+----------------------------------+ | is-slot-marked-successful | Returns 0 if ```` is marked| | | GOOD. | +----------------------------------+----------------------------------+ | get-suffix | Prints the suffix for ````.| +----------------------------------+----------------------------------+ | is-autosync-enabled | Prints enablement status of slot | | | duplication. (It is enabled by | | | default.) | +----------------------------------+----------------------------------+ | toggle-autosync | Toggles enablement of slot | | | duplication. | +----------------------------------+----------------------------------+ | dump-slots-info | Prints information about the | | | slots. | +----------------------------------+----------------------------------+ | ``` is the zero-based slot number. | +---------------------------------------------------------------------+ The default setting for both slot 0 and slot 1 is “bootable,” with slot 0 having higher priority. .. todo:: Since slot status is described as a property controlled by a state machine, it's not clear what "by default" means. When a slot has been flashed but not yet booted, that is, in the "Update complete, reboot pending" state? Or in the normal state? To show the current boot slot ############################# - Enter this command:: # root@tegra-ubuntu:/home/nvidia# nvbootctrl get-current-slot The command displays a single digit, 0 (slot A) or 1 (slot B). .. todo:: Must the user execute this command as an administrator? That's an unusual requirement, and when it's necessary, examples more usually show a command being run from the dollar sign prompt with ``sudo``. Actually needing the pound sign prompt is so unusual that I'd expect it to be used in an example only when it is truly needed, but then I'd also expect the unusual requirement to be pointed out in a note as well. To show the slot status ####################### - Before enabling rootfs redundancy, enter the command:: # root@tegra-ubuntu:/home/nvidia# nvbootctrl dump-slots-info The command displays the status of the current boot slot:: magic:0x43424e00, version: 3 features: 0 num_slots: 1 slot: 0, priority: 15, suffix: \_a, retry_count: 7, boot_successful: 1 slot: 1, priority: 0, suffix: , retry_count: 0, boot_successful: 0 - After enabling rootfs redundancy. enter the command:: # nvbootctrl dump-slots-info The command displays the status of the current boot slot:: magic:0x43424e00, version: 3 features: 3 num_slots: 2 slot: 0, priority: 15, suffix: \_a, retry_count: 7, boot_successful: 1 slot: 1, priority: 14, suffix: \_b, retry_count: 7, boot_successful: 1 Sample Boot Log @@@@@@@@@@@@@@@ The boot slot is selected by MB1. MB1 can produce a log that records the selection process. To produce the log, use a debug build of MB1 with messages enabled. .. todo:: This it never explained. The phrase "debug build" occurs nowhere else in the document, and "MB1 log" doesn't occur at all. Where can you find a debug build of MB1, or how can you create one? Where is the log written -- to the debug console, to stdout, to a file? How do you enable messages? If we're feeling really talkative, what other diagnostic features does the debug build of MB1 have, and how does one control them? Are there debug builds of other components, and if so, how are they obtained and used? (Much of this information may belong elsewhere.) The original text also says, "Messages from MB2 are always available." In contrast to the missing information about MB1, this is *unnecessary* information, since MB2 has nothing to do with slot selection (or if it does, the connection has not been revealed). The following sample log shows that slot 1 (slot B) is selected as the boot slot:: [0000.040] I> Welcome to MB1-coldboot(dev-version : 14.00.170822-t186-M-00.00-96e265a3) [0000.048] I> rst_source : 0xb [0000.051] I> rst_level : 0x1 [0000.053] I> Read lock all AES keyslots [0000.057] I> Read lock all RSA keyslots [0000.061] I> Clear SE keyslots left open by BR [0000.065] I> Last mts-fallback status: 0x00000000 [0000.070] I> Boot-device: eMMC [0000.094] I> sdmmc ddr50 mode [0000.098] I> A/B: bin_type (19) slot 0 [0000.102] I> Binary(19) of size 512 is loaded @ 0x40043400 [0000.108] I> Boot chain chosen: 1 [0000.111] I> Boot chain chosen: 1 [0000.114] I> magic:0x43424e00, version: 259, num_slots: 2 [0000.119] I> slot: 0, pri: 14, suffix: \_a, retry: 7, boot_succ: 1 [0000.125] I> slot: 1, pri: 15, suffix: \_b, retry: 6, boot_succ: 1 [0000.131] I> Loading MB1-BCT to SysRAM [0000.135] I> A/B: bin_type (0) slot 1 [0000.138] I> Boot-device: eMMC . . . . . . [0000.888] I> Welcome to MB2(TBoot-BPMP)(version: 01.00.160913-t186-M-00.00-mobile-09b4fbd4) [0000.897] I> Default Heap @ [0xd486400 - 0xd488400] [0000.901] I> DMA Heap @ [0x84a00000 - 0x85300000] [0000.906] I> bit @ 0xd480000 [0000.909] I> BR-BCT relocated to 0xd7020000 [0000.913] I> Boot-device: eMMC [0000.917] I> sdmmc bdev is already initialized [0000.922] I> pmic: reset reason (nverc) : 0x0 [0000.926] I> Reading GPT from 512 for device 00000003 [0000.932] I> Reading GPT from 8388096 for device 00000003 [0000.939] I> Found 13 partitions in 00000003 device [0000.944] I> Reading GPT from 512 for device 00010003 [0000.950] I> Found 27 partitions in 00010003 device [0000.956] I> A/B: bin_type (16) slot 1 [0000.959] I> Loading partition bpmp-fw_b at 0xd7800000 [0000.964] I> Reading two headers - addr:0xd7800000 blocks:1 [0000.970] I> Addr: 0xd7800000, start-block: 58762425, num_blocks: 1 [0000.985] I> Binary(16) of size 528848 is loaded @ 0xd7800000 . . . . . . .. todo:: Very long examples are disfavored because they take up too much space, demand too much study from the reader, and tend to hide rather than illustrate the specific points that the reader needs to understand. Highlighting features of interest can reduce the last difficulty, but Sphinx does not provide for highlighting in code blocks. And although we could do it in ePublisher, in this case we didn't bother. Generating the Bootloader Update Payload (BUP) @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ .. todo:: This process already appears to have been described in "Bootloader Update Payload Generator." I haven't analyzed the two to figure out whether they contain information about different things, different information about the same thing, or the same information about the same thing. In any case, if there is a substantial reason for having both, both need to explain clearly why there are two sections and how they differ. I copy edited the first section thoroughly; this one, more lightly. A Bootloader Update Payload (BUP) is used to implement Bootloader update. It contains firmware binaries of each type needed to update a Jetson device. This section describes the procedure for generating a single-spec BUP, which contains just one binary of each type and can be used to update just one Jetson device configuration. There is also a procedure for generating a multi-spec BUP, which includes multiple firmware binaries and BCT images of each type, and can be used to update any supported type of Jetson device. When you run the updater, it uses the appropriate binary of each type for the device you are updating. See the section `To generate a multi-spec BUP <#to-generate-a-multi-spec-bup>`__, below, for information. To generate a single-spec BUP ############################# - To create a BUP image to be stored in a file for a carrier board that is not connected to the host system: - For a Jetson AGX Orin carrier board: .. todo:: TBD - For a Jetson Xavier NX carrier board with the indicated values of ``FAB``, ``BOARDID``, ``FUSELEVEL``, and ``BOARDSKU``:: $ cd $ sudo FAB=100 BOARDID=3668 FUSELEVEL=fuselevel_production BOARDSKU=0001 ./build_l4t_bup.sh jetson-xavier-nx-devkit-emmc mmcblk0p1 .. todo:: The original showed BOARDSKU in the command but didn't mention it in the text. What is it? The only other mention is a one-liner in each of the "Adaptation and Bring-Up" topics. - For a Jetson AGX Xavier carrier board with the indicated values of ``FAB``, ``BOARDID``, and ``FUSELEVEL``:: $ cd $ sudo FAB=400 BOARDID=2888 FUSELEVEL=fuselevel_production BOARDSKU=0001 BOARDREV=H.0 ./build_l4t_bup.sh jetson-agx-xavier-devkit mmcblk0p1 .. todo:: These commands appear to apply only to Jetson reference carrier boards; BOARDID would not make sense otherwise. But they also appear to apply only to production, and production devices almost always use custom-made boards. Furthermore, the process of generating a BUP appears to be necessary only for custom carrier boards. Thus the procedure appears to be useful only for rare applications where a reference carrier board is used in production. Is that so? If it is, why don't we describe an equivalent procedure for custom boards? For that matter, why do we describe this procedure at all? It seems natural to treat it as a rather obscure special case of the procedure for a custom board. - To create a BUP image for a board that is connected to the host system: 1. Place the target board into :ref:`Force Recovery Mode `. 2. Enter the commands:: $ cd $ sudo ./build_l4t_bup.sh mmcblk0p1 Where is: - For Jetson AGX Orin: **TBD** - For Jetson Xavier NX series: ``jetson-xavier-nx-devkit-emmc`` - For Jetson AGX Xavier series: ``jetson-agx-xavier-devkit`` .. todo:: Jetson Orin TBD. - To create the PKC signed BUP image for a carrier board connected to the host system: 1. Place the target board into `Force Recovery Mode `__. 2. Enter the commands:: $ cd $ sudo ./build_l4t_bup.sh -s -u mmcblk0p1 Where: - ```` is the location of the parent directory of the PDK installation package, in which ``flash.sh`` is stored. - ```` is the RSA private key file for your board. It must be located under ``/bootloader directory`` or you must specify its absolute pathname. - is: - For Jetson AGX Orin series: **TBD** - For Jetson Xavier NX series: ``jetson-xavier-nx-devkit-emmc`` - For Jetson AGX Xavier series: ``jetson-agx-xavier-devkit`` .. todo:: Jetson Orin TBD. To generate a multi-spec BUP ############################ .. todo:: This section was in the old document's "Jetson Nano and Jetson TX1 Update and Redundancy," and was referenced in "Jetson Xavier NX / AGX Xavier TX2 Update and Redundancy." - Enter the commands:: $ cd $ sudo ./l4t_generate_soc_bup.sh [-u ] [-p ] [-d] t19x .. todo:: Must the last parameter be ``t23x`` for Jetson Orin? Where: - ```` is the pathname of the directory that contains the PDK installation package. ``flash.sh`` is in this directory. - ```` is the RSA private key file for your Jetson carrier board. If it is a relative pathname, it is interpreted relative to the ``/bootloader/`` directory. - ```` is a string of command line options to be passed to ``flash.sh`` to generate the BUP. If the string contains whitespace characters, it must be enclosed in quotes. - ``-d`` causes the script to run in debug mode, which keeps all boot firmware blob images in ``bootloader/signed`` and ``bootloader/multi-signed``. Location of Generated BUP Files ############################### Both procedures store the generated BUP(s) in the director(ies): - For Jetson Xavier NX series and Jetson AGX Xavier series: ``/bootloader/payloads_t19x``