diff --git a/balena-yocto-scripts b/balena-yocto-scripts index 1ce733b3..7c73eefe 160000 --- a/balena-yocto-scripts +++ b/balena-yocto-scripts @@ -1 +1 @@ -Subproject commit 1ce733b37d5c143e1f68e28ff9fa9ac4ef709b87 +Subproject commit 7c73eefe9aac870b5fd9050e5d429dd56b0ab4ff diff --git a/layers/meta-balena b/layers/meta-balena index 5e157d7d..e6c20376 160000 --- a/layers/meta-balena +++ b/layers/meta-balena @@ -1 +1 @@ -Subproject commit 5e157d7d2954d406666df9d0681c2fbe63a838fa +Subproject commit e6c2037615db74af70250c5d3351c44e2ee31fbb diff --git a/layers/meta-balena-jetson/recipes-bsp/uefi/edk2-container_1.0.bb b/layers/meta-balena-jetson/recipes-bsp/uefi/edk2-container_1.0.bb index 633db94c..e050433e 100644 --- a/layers/meta-balena-jetson/recipes-bsp/uefi/edk2-container_1.0.bb +++ b/layers/meta-balena-jetson/recipes-bsp/uefi/edk2-container_1.0.bb @@ -27,9 +27,6 @@ SRC_URI = " \ file://0001-Seeed-J4012-Integrate-with-balenaOS-on-L4T-36.3_patch.txt \ file://0001-Seeed-J3010-Integrate-with-balenaOS-on-L4T-36.3_patch.txt \ file://0001-edk2-nvidia-Remove-pva-fw-from-required-list_patch.txt \ - file://0001-feat-add-a-null-version-of-the-FwVariableLib_patch.txt \ - file://0002-fix-don-t-try-to-erase-early-vars-partition-in-Jetso_patch.txt \ - file://0003-fix-reset-the-meas-buffer-after-computing-the-first-_patch.txt \ file://0001-StandaloneMmOptee-Don-t-assert-if-var-store-integrit_patch.txt \ " @@ -50,11 +47,6 @@ do_compile () { IMAGETAG="${PN}:$(date +%s)-${MACHINE}" - if [ -z "$(DOCKER_API_VERSION=1.22 docker images -q ${IMAGETAG} 2> /dev/null)" ]; then - echo "Build tag ${IMAGETAG} found, clean up all build" - DOCKER_API_VERSION=1.22 docker rmi -f ${IMAGETAG} - fi - DOCKER_API_VERSION=1.22 docker build --tag ${IMAGETAG} ${B}/ --build-arg "DEVICE_TYPE=${MACHINE}" DOCKER_API_VERSION=1.22 docker run --rm -v ${WORKDIR}/out:/out -v "${HOME}":"${HOME}" -e EDK2_DOCKER_USER_HOME="${HOME}" -e DEVICE_TYPE="${MACHINE}" ${IMAGETAG} su /bin/bash -c "/build/build.sh && cp /build/nvidia-uefi/images/uefi_Jetson_DEBUG.bin /out/uefi_jetson.bin && cp /build/nvidia-uefi/images/BOOTAA64_Jetson_DEBUG.efi /out/BOOTAA64.efi" } diff --git a/layers/meta-balena-jetson/recipes-bsp/uefi/files/0001-AGX-Orin-32GB-Integrate-with-balenaOS-on-L4T-36.3_patch.txt b/layers/meta-balena-jetson/recipes-bsp/uefi/files/0001-AGX-Orin-32GB-Integrate-with-balenaOS-on-L4T-36.3_patch.txt index d76b0e96..c6288321 100644 --- a/layers/meta-balena-jetson/recipes-bsp/uefi/files/0001-AGX-Orin-32GB-Integrate-with-balenaOS-on-L4T-36.3_patch.txt +++ b/layers/meta-balena-jetson/recipes-bsp/uefi/files/0001-AGX-Orin-32GB-Integrate-with-balenaOS-on-L4T-36.3_patch.txt @@ -1,7 +1,7 @@ -From 1d89db43997d5d9da55a88491a6a63826c37f3a0 Mon Sep 17 00:00:00 2001 +From 98de665db6d2a9eb3b12289449b125f69f3d10d2 Mon Sep 17 00:00:00 2001 From: Alexandru Costache -Date: Mon, 1 Jul 2024 09:21:33 +0000 -Subject: [PATCH] 2 AGX-Orin 32GB: Integrate with balenaOS on L4T 36.3 +Date: Tue, 16 Jul 2024 09:17:34 +0000 +Subject: [PATCH] AGX-Orin 32GB: Integrate with balenaOS on L4T 36.3 With this patch, the Nvidia bootloader parses resinos_uEnv.txt, extra_uEnv.txt and bootcount.env in order to load the @@ -14,14 +14,14 @@ compatible with the dtb selection mechanism implemented in the Supervisor for the rest of the boards that use u-boot. Upstream-status: Inappropriate [configuration] -Signed-off-by: Alexandru Costache +Signed-off-by: Alexandru Costache +Date: Mon, 1 Jul 2024 09:21:33 +0000 +Subject: [PATCH] 2 AGX-Orin 32GB: Integrate with balenaOS on L4T 36.3 + +With this patch, the Nvidia bootloader parses resinos_uEnv.txt, +extra_uEnv.txt and bootcount.env in order to load the +extlinux.conf and the selected dtb from the current active +rootfs. + +The A/B rootfs switch logic implemented in this change +is the same as the one that exists in balenaOS u-boot and is +compatible with the dtb selection mechanism implemented in the +Supervisor for the rest of the boards that use u-boot. + +Upstream-status: Inappropriate [configuration] +Signed-off-by: Alexandru Costache +--- + .../Application/L4TLauncher/L4TLauncher.c | 583 +++++++++++++++++- + .../Application/L4TLauncher/L4TLauncher.h | 15 +- + 2 files changed, 578 insertions(+), 20 deletions(-) + +diff --git a/Silicon/NVIDIA/Application/L4TLauncher/L4TLauncher.c b/Silicon/NVIDIA/Application/L4TLauncher/L4TLauncher.c +index ab86f3e0..1d5d16ee 100644 +--- a/Silicon/NVIDIA/Application/L4TLauncher/L4TLauncher.c ++++ b/Silicon/NVIDIA/Application/L4TLauncher/L4TLauncher.c +@@ -1125,6 +1125,147 @@ CheckCommandString ( + return EFI_NOT_FOUND; + } + ++ ++STATIC ++EFI_STATUS ++EFIAPI ++CheckDtbExists ( ++ IN EFI_HANDLE DeviceHandle, ++ IN UINT32 BootChain, ++ IN CONST CHAR16 *BalenaOSRootFs, ++ IN CONST CHAR16 *DtbPath ++ ) ++{ ++ EFI_STATUS Status; ++ EFI_DEVICE_PATH *FullDevicePath; ++ EFI_DEVICE_PATH *TmpFullDevicePath; ++ EFI_FILE_HANDLE FileHandle = NULL; ++ EFI_HANDLE RootFsHandle; ++ ++ if (NULL == BalenaOSRootFs || NULL == DtbPath) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ Status = FindPartitionInfo (DeviceHandle, BalenaOSRootFs, BootChain, NULL, &RootFsHandle); ++ if (EFI_ERROR (Status)) { ++ ErrorPrint (L"%a: Unable to find partition info\r\n", __FUNCTION__); ++ return Status; ++ } ++ ErrorPrint(L"%a: got here 1\r\n", __FUNCTION__); ++ FullDevicePath = FileDevicePath (RootFsHandle, DtbPath); ++ if (NULL == FullDevicePath) { ++ ErrorPrint (L"%a: Failed to create file device path\r\n", __FUNCTION__); ++ return EFI_OUT_OF_RESOURCES; ++ } ++ ErrorPrint(L"%a: got here 2\r\n", __FUNCTION__); ++ TmpFullDevicePath = FullDevicePath; ++ Status = EfiOpenFileByDevicePath (&TmpFullDevicePath, &FileHandle, EFI_FILE_MODE_READ, 0); ++ if (EFI_ERROR (Status)) { ++ ErrorPrint (L"%a: Failed to open dtb file. Reason: %r\r\n", __FUNCTION__, Status); ++ } ++ ErrorPrint(L"%a: got here 3\r\n", __FUNCTION__); ++ if (FileHandle != NULL) { ++ FileHandleClose (FileHandle); ++ } ++ ErrorPrint(L"%a: got here 4\r\n", __FUNCTION__); return Status; ++} ++ ++STATIC ++EFI_STATUS ++EFIAPI ++ProcessExtrauEnv ( ++ IN EFI_HANDLE DeviceHandle, ++ IN UINT32 BootChain, ++ IN CONST CHAR16 *BalenaOSRootFs, ++ OUT CHAR16 **CustomFdtName ++) ++{ ++ EFI_STATUS Status; ++ EFI_HANDLE BootPartHandle; ++ EFI_DEVICE_PATH *FullDevicePath; ++ EFI_DEVICE_PATH *TmpFullDevicePath; ++ EFI_FILE_HANDLE FileHandle = NULL; ++ CHAR16 *FileLine = NULL; ++ CHAR16 *DtbName = NULL; ++ BOOLEAN Ascii; ++ CHAR16 *LineCopy = AllocateZeroPool(MAX_DTB_PATH_LEN); ++ UINT64 len; ++ ++ // Set default dtb as fail-safe ++ *CustomFdtName = AllocateZeroPool(MAX_DTB_PATH_LEN); ++ UnicodeSPrint (*CustomFdtName, MAX_DTB_PATH_LEN, L"boot\\%s\0", DEFAULT_AGX_ORIN_DTB_NAME); ++ ++ Status = FindPartitionInfo (DeviceHandle, BALENA_BOOT_PARTITION, BootChain, NULL, &BootPartHandle); ++ if (EFI_ERROR (Status)) { ++ ErrorPrint (L"%a: Unable to find boot partition\r\n", __FUNCTION__); ++ return Status; ++ } ++ FullDevicePath = FileDevicePath (BootPartHandle, BALENA_EXTRA_UENV_FILE); ++ ++ if (NULL == FullDevicePath) { ++ ErrorPrint (L"%a: Failed to create file device path to extra_uEnv.txt\r\n", __FUNCTION__); ++ return EFI_OUT_OF_RESOURCES; ++ } ++ ++ TmpFullDevicePath = FullDevicePath; ++ Status = EfiOpenFileByDevicePath (&TmpFullDevicePath, &FileHandle, EFI_FILE_MODE_READ, 0); ++ ++ if (EFI_ERROR (Status)) { ++ ErrorPrint (L"%a: Failed to open file extra_uEnv.txt: %r\r\n", __FUNCTION__, Status); ++ return Status; ++ } ++ ++ while (!FileHandleEof (FileHandle)) { ++ if (FileLine != NULL) { ++ FreePool (FileLine); ++ FileLine = NULL; ++ } ++ ++ FileLine = FileHandleReturnLine (FileHandle, &Ascii); ++ ++ if (NULL == FileLine) { ++ break; ++ } ++ ++ UnicodeSPrint (LineCopy, MAX_DTB_PATH_LEN, L"%s\0", FileLine); ++ Print(L"Processing entry: %s\n", LineCopy); ++ ++ len = StrLen(LineCopy); ++ ++ if (len < 21 /* dtb name should have at least 1 character + extension */) { ++ ErrorPrint(L"DTB name is too short. Using default dtb.\n"); ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ DtbName = StrStr(LineCopy, L"custom_fdt_file="); ++ ++ if (NULL != DtbName) { ++ DtbName += StrLen(L"custom_fdt_file="); ++ UnicodeSPrint(*CustomFdtName, MAX_DTB_PATH_LEN, L"boot\\%s\0", DtbName); ++ Print(L"Selected dtb name is: %s\n", *CustomFdtName); ++ Status = CheckDtbExists(DeviceHandle, BootChain, BalenaOSRootFs, *CustomFdtName); ++ ErrorPrint(L"Got here 6 after dtb exists;\n"); ++ if (EFI_ERROR(Status)) { ++ ErrorPrint(L"Selected dtb not found! Using the default DTB for this device type\n"); ++ UnicodeSPrint(*CustomFdtName, MAX_DTB_PATH_LEN, L"boot\\%s\0", DEFAULT_AGX_ORIN_DTB_NAME); ++ return Status; ++ } ++ } ++ ErrorPrint(L"Got here 7\n"); ++ if (FileLine != NULL) { ErrorPrint(L"Got here before Freepool;\n"); ++ FreePool (FileLine); ErrorPrint(L"Got here before FileHandle set to Null;\n"); ++ FileLine = NULL; ++ } ErrorPrint(L"FileLine was freed\n"); ++ } ++ if (FileHandle != NULL) { ErrorPrint(L"Got here before FileHandle close\n"); ++ FileHandleClose (FileHandle); ErrorPrint(L"Done FileHandle close\n"); ++ } ++ ++ ErrorPrint(L"Got here 8 will return efi success;\n"); ++ return EFI_SUCCESS; ++} ++ ++ + /** + Process the extlinux.conf file + +@@ -1142,8 +1283,10 @@ EFIAPI + ProcessExtLinuxConfig ( + IN EFI_HANDLE DeviceHandle, + IN UINT32 BootChain, ++ IN CONST CHAR16 *BalenaOSRootFs, + OUT EXTLINUX_BOOT_CONFIG *BootConfig, +- OUT EFI_HANDLE *RootFsHandle ++ OUT EFI_HANDLE *RootFsHandle, ++ IN BOOLEAN RunningUpdatedBootSlot + ) + { + EFI_STATUS Status; +@@ -1154,8 +1297,11 @@ ProcessExtLinuxConfig ( + CHAR16 *Timeout = NULL; + CHAR16 *CbootArg = NULL; + CHAR16 *PostCbootArg = NULL; ++ CONST CHAR16 *RootL = L"root=LABEL="; + BOOLEAN Ascii; + UINTN Index; ++ CHAR16 *UpdatedCmdline = NULL; ++ UINTN argsSize; + + ZeroMem (BootConfig, sizeof (EXTLINUX_BOOT_CONFIG)); + +@@ -1163,12 +1309,10 @@ ProcessExtLinuxConfig ( + return EFI_INVALID_PARAMETER; + } + +- Status = FindPartitionInfo (DeviceHandle, ROOTFS_BASE_NAME, BootChain, NULL, RootFsHandle); +- if (EFI_ERROR (Status)) { +- ErrorPrint (L"%a: Unable to find partition info\r\n", __FUNCTION__); +- return Status; +- } ++ ErrorPrint (L"%a:Running the updated (target) bootchain slot: %s\r\n", __FUNCTION__, RunningUpdatedBootSlot ? L"true" : L"false"); + ++ /* Load extlinux.conf from the selected BalenaOS root filesystem */ ++ Status = FindPartitionInfo (DeviceHandle, BalenaOSRootFs, BootChain, NULL, RootFsHandle); + Status = OpenAndReadFileToBuffer ( + *RootFsHandle, + EXTLINUX_CONF_PATH, +@@ -1240,6 +1384,23 @@ ProcessExtLinuxConfig ( + + Status = CheckCommandString (CleanLine, EXTLINUX_KEY_FDT, &BootConfig->BootOptions[BootConfig->NumberOfBootOptions-1].DtbPath); + if (!EFI_ERROR (Status)) { ++ /* extlinux.conf contains a "FDT default" entry */ ++ if (0 == StrnCmp(BootConfig->BootOptions[BootConfig->NumberOfBootOptions-1].DtbPath, EXTLINUX_GENERIC_FDT, StrLen (EXTLINUX_GENERIC_FDT))) { ++ if (NULL != BootConfig->BootOptions[BootConfig->NumberOfBootOptions-1].DtbPath) { ++ FreePool(BootConfig->BootOptions[BootConfig->NumberOfBootOptions-1].DtbPath); ++ /* Check if a device-tree name is set in extra_uEnv.txt */ ++ CHAR16 *ExtrauEnvDtb = NULL; ++ Status = ProcessExtrauEnv(DeviceHandle, BootChain, BalenaOSRootFs, &ExtrauEnvDtb); ++ Print(L"After ProcessExtrauEnv\n"); ++ if (!EFI_ERROR(Status)) { ++ Print(L"Using default device-tree\n"); ++ } Print(L">> 11\n"); ++ BootConfig->BootOptions[BootConfig->NumberOfBootOptions-1].DtbPath = ExtrauEnvDtb; Print(L">> 12\n"); ++ Print(L"Kernel device-tree after parsing extra_uEnv.txt is %s\n", BootConfig->BootOptions[BootConfig->NumberOfBootOptions-1].DtbPath); ++ } ++ } else { Print(L">> 10\n"); ++ Print(L"Kernel device-tree is %s\n", BootConfig->BootOptions[BootConfig->NumberOfBootOptions-1].DtbPath); ++ } + continue; + } + +@@ -1249,6 +1410,19 @@ ProcessExtLinuxConfig ( + } + + Status = CheckCommandString (CleanLine, EXTLINUX_KEY_APPEND, &BootConfig->BootOptions[BootConfig->NumberOfBootOptions-1].BootArgs); ++ argsSize = StrSize (BootConfig->BootOptions[BootConfig->NumberOfBootOptions-1].BootArgs); ++ UpdatedCmdline = AllocateZeroPool (argsSize + StrSize(RootL) + StrSize(BalenaOSRootFs) + 2); ++ if (NULL == UpdatedCmdline) { ++ ErrorPrint (L"%a: Failed to allocate memory for updated cmdline %d\r\n", __FUNCTION__); ++ return EFI_OUT_OF_RESOURCES; ++ } ++ ++ /* Append root label to cmdline that has been read from the extlinux.conf read from the active rootfs */ ++ UnicodeSPrint (UpdatedCmdline, StrSize(RootL) + StrSize(BalenaOSRootFs) + argsSize, L"%s %s%s\0", BootConfig->BootOptions[BootConfig->NumberOfBootOptions-1].BootArgs, RootL, BalenaOSRootFs); ++ if (NULL != BootConfig->BootOptions[BootConfig->NumberOfBootOptions-1].BootArgs) { ++ FreePool(BootConfig->BootOptions[BootConfig->NumberOfBootOptions-1].BootArgs); ++ } ++ BootConfig->BootOptions[BootConfig->NumberOfBootOptions-1].BootArgs = UpdatedCmdline; + if (!EFI_ERROR (Status)) { + CbootArg = StrStr (BootConfig->BootOptions[BootConfig->NumberOfBootOptions-1].BootArgs, EXTLINUX_CBOOT_ARG); + if (CbootArg != NULL) { +@@ -1470,12 +1644,12 @@ ExtLinuxBoot ( + + // Reload fdt if needed + Status = EfiGetSystemConfigurationTable (&gEfiAcpiTableGuid, &AcpiBase); +- if (EFI_ERROR (Status) && (BootOption->DtbPath != NULL)) { ++ if (BootOption->DtbPath != NULL) { + Status = EfiGetSystemConfigurationTable (&gFdtTableGuid, &OldFdtBase); + if (EFI_ERROR (Status)) { + OldFdtBase = NULL; + } +- ++ ErrorPrint (L"%a: OpenedAndReadFileToBuffer %s (%r)\r\n", __FUNCTION__, BootOption->DtbPath, Status); + Status = OpenAndReadFileToBuffer ( + DeviceHandle, + BootOption->DtbPath, +@@ -1690,6 +1864,300 @@ Exit: + return Status; + } + ++STATIC ++EFI_STATUS ++EFIAPI ++WriteBootCountFile ( ++ IN EFI_HANDLE DeviceHandle, ++ IN UINT32 BootChain, ++ IN UINT32 BootCountValue ++) ++{ ++ EFI_STATUS Status; ++ EFI_DEVICE_PATH *FullDevicePath; ++ EFI_DEVICE_PATH *TmpFullDevicePath; ++ EFI_FILE_HANDLE FileHandle = NULL; ++ CHAR8 BootCountContent[11]; ++ UINTN BootCountFileSize; ++ EFI_HANDLE BootPartHandle; ++ ++ Status = FindPartitionInfo (DeviceHandle, BALENA_BOOT_PARTITION, BootChain, NULL, &BootPartHandle); ++ if (EFI_ERROR (Status)) { ++ ErrorPrint (L"%a: Unable to find partition resin-boot\r\n", __FUNCTION__); ++ return Status; ++ } ++ ++ FullDevicePath = FileDevicePath (BootPartHandle, BALENA_BOOTCOUNT_FILE_PATH); ++ if (NULL == FullDevicePath) { ++ ErrorPrint (L"%a: Failed to create file device path bootcount.env\r\n", __FUNCTION__); ++ return EFI_OUT_OF_RESOURCES; ++ } ++ ++ TmpFullDevicePath = FullDevicePath; ++ Status = EfiOpenFileByDevicePath (&TmpFullDevicePath, &FileHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_CREATE, 0); ++ if (EFI_ERROR (Status)) { ++ ErrorPrint (L"%a: Failed to open file bootcount.env: %r\r\n", __FUNCTION__, Status); ++ return Status; ++ } ++ ++ if (EFI_ERROR (Status)) { ++ ErrorPrint (L"%a: Failed to set file size to 0\r\n", __FUNCTION__); ++ return Status; ++ } ++ ++ BootCountFileSize = AsciiSPrint (BootCountContent, 12, "bootcount=%d\0", BootCountValue); ++ Status = FileHandleWrite (FileHandle, &BootCountFileSize, BootCountContent); ++ ++ if (EFI_ERROR (Status)) { ++ ErrorPrint (L"%a: Failed to write bootcount file contents\r\n", __FUNCTION__); ++ return Status; ++ } ++ ++ if (FileHandle != NULL) { ++ FileHandleClose (FileHandle); ++ } ++ ++ return EFI_SUCCESS; ++} ++ ++ ++STATIC ++EFI_STATUS ++EFIAPI ++ProcessBootCountValue ( ++ IN EFI_HANDLE DeviceHandle, ++ IN UINT32 BootChain, ++ OUT UINTN *BootCountValue ++) ++{ ++ EFI_STATUS Status; ++ EFI_DEVICE_PATH *FullDevicePath; ++ EFI_DEVICE_PATH *TmpFullDevicePath; ++ EFI_HANDLE BootPartHandle; ++ EFI_FILE_HANDLE FileHandle = NULL; ++ CHAR16 *FileLine = NULL; ++ CHAR16 *CleanLine; ++ BOOLEAN Ascii; ++ ++ Status = FindPartitionInfo (DeviceHandle, BALENA_BOOT_PARTITION, BootChain, NULL, &BootPartHandle); ++ if (EFI_ERROR (Status)) { ++ ErrorPrint (L"%a: Could not find partition resin-boot\r\n", __FUNCTION__); ++ return Status; ++ } ++ ++ FullDevicePath = FileDevicePath (BootPartHandle, BALENA_BOOTCOUNT_FILE_PATH); ++ if (NULL == FullDevicePath) { ++ ErrorPrint (L"%a: Failed to create file device path for bootcount.env\r\n", __FUNCTION__); ++ return EFI_OUT_OF_RESOURCES; ++ } ++ ++ TmpFullDevicePath = FullDevicePath; ++ Status = EfiOpenFileByDevicePath (&TmpFullDevicePath, &FileHandle, EFI_FILE_MODE_READ, 0); ++ if (EFI_ERROR (Status)) { ++ *BootCountValue = 1; ++ Status = WriteBootCountFile (DeviceHandle, BootChain, *BootCountValue); ++ ++ if (EFI_ERROR (Status)) { ++ ErrorPrint (L"%a: Failed to write bootcount file contents\r\n", __FUNCTION__); ++ return Status; ++ } else { ++ Print(L"Initialized boot count to 1\r\n"); ++ } ++ } else { ++ while (!FileHandleEof (FileHandle)) { ++ if (FileLine != NULL) { ++ FreePool (FileLine); ++ FileLine = NULL; ++ } ++ ++ FileLine = FileHandleReturnLine (FileHandle, &Ascii); ++ if (NULL == FileLine) { ++ break; ++ } ++ ++ CleanLine = CleanExtLinuxLine (FileLine); ++ if (*CleanLine != CHAR_NULL) { ++ if (StrStr(CleanLine, L"bootcount=")) { ++ *BootCountValue = StrDecimalToUintn(CleanLine + 10); ++ Print(L"%a: BootCount is %d\r\n", __FUNCTION__, *BootCountValue); ++ ++ if (FileHandle != NULL) { ++ FileHandleClose (FileHandle); ++ } ++ } ++ ++ if (FileLine != NULL) { ++ FreePool (FileLine); ++ FileLine = NULL; ++ } ++ ++ Status = WriteBootCountFile (DeviceHandle, BootChain, ++(*BootCountValue)); ++ if (EFI_ERROR (Status)) { ++ ErrorPrint (L"%a: Failed to write bootcount file value %d\r\n", __FUNCTION__, *BootCountValue); ++ } ++ ++ return Status; ++ } ++ } ++ } ++ ++ return EFI_SUCCESS; ++} ++ ++ ++STATIC ++EFI_STATUS ++EFIAPI ++ProcessResinOSuEnv ( ++ IN EFI_HANDLE DeviceHandle, ++ IN UINT32 BootChain, ++ OUT UINTN *RootPart, ++ OUT UINTN *UpgradeAvailable ++) ++{ ++ EFI_STATUS Status; ++ EFI_HANDLE BootPartHandle; ++ EFI_DEVICE_PATH *FullDevicePath; ++ EFI_DEVICE_PATH *TmpFullDevicePath; ++ EFI_FILE_HANDLE FileHandle = NULL; ++ CHAR16 *FileLine = NULL; ++ CHAR16 *CleanLine; ++ BOOLEAN Ascii; ++ ++ Status = FindPartitionInfo (DeviceHandle, BALENA_BOOT_PARTITION, BootChain, NULL, &BootPartHandle); ++ if (EFI_ERROR (Status)) { ++ ErrorPrint (L"%a: Could not find partition Balena boot partition\r\n", __FUNCTION__); ++ return Status; ++ } ++ ++ FullDevicePath = FileDevicePath (BootPartHandle, BALENA_BOOT_CONF_PATH); ++ if (NULL == FullDevicePath) { ++ ErrorPrint (L"%a: Failed to create path for resinOS_uEnvt.xt\r\n", __FUNCTION__); ++ return EFI_OUT_OF_RESOURCES; ++ } ++ ++ TmpFullDevicePath = FullDevicePath; ++ Status = EfiOpenFileByDevicePath (&TmpFullDevicePath, &FileHandle, EFI_FILE_MODE_READ, 0); ++ if (EFI_ERROR (Status)) { ++ ErrorPrint (L"%a: Failed to open resinOS_uEnv.txt: %r\r\n", __FUNCTION__, Status); ++ return Status; ++ } ++ ++ while (!FileHandleEof (FileHandle)) { ++ if (FileLine != NULL) { ++ FreePool (FileLine); ++ FileLine = NULL; ++ } ++ ++ FileLine = FileHandleReturnLine (FileHandle, &Ascii); ++ if (NULL == FileLine) { ++ break; ++ } ++ ++ CleanLine = CleanExtLinuxLine (FileLine); ++ if (*CleanLine != CHAR_NULL) { ++ if (StrStr(CleanLine, L"resin_root_part=")) { ++ *RootPart = StrDecimalToUintn(CleanLine + 16); ++ Print(L"RootPart is %d\r\n", *RootPart); ++ } else if (StrStr(CleanLine, L"upgrade_available=")) { ++ *UpgradeAvailable = StrDecimalToUintn(CleanLine + 18); ++ Print(L"UpgradeAvailable is %d\r\n", *UpgradeAvailable); ++ } ++ } ++ } ++ ++ if (FileHandle != NULL) { ++ FileHandleClose (FileHandle); ++ } ++ ++ if (FileLine != NULL) { ++ FreePool (FileLine); ++ FileLine = NULL; ++ } ++ ++ return EFI_SUCCESS; ++} ++ ++STATIC ++EFI_STATUS ++EFIAPI ++ProcessBootSlotFile ( ++ IN EFI_HANDLE DeviceHandle, ++ IN UINT32 BootChain, ++ OUT UINTN *BootSlotValue, ++ OUT BOOLEAN *IsRunningUpdatedSlot ++) ++{ ++ EFI_STATUS Status; ++ EFI_DEVICE_PATH *FullDevicePath; ++ EFI_DEVICE_PATH *TmpFullDevicePath; ++ EFI_HANDLE BootPartHandle; ++ EFI_FILE_HANDLE FileHandle = NULL; ++ CHAR16 *FileLine = NULL; ++ CHAR16 *CleanLine; ++ BOOLEAN Ascii; ++ ++ Status = FindPartitionInfo (DeviceHandle, BALENA_BOOT_PARTITION, BootChain, NULL, &BootPartHandle); ++ if (EFI_ERROR (Status)) { ++ ErrorPrint (L"%a: Could not find partition resin-boot\r\n", __FUNCTION__); ++ return Status; ++ } ++ ++ FullDevicePath = FileDevicePath (BootPartHandle, BALENA_BOOTSLOT_FILE_PATH); ++ if (NULL == FullDevicePath) { ++ ErrorPrint (L"%a: Failed to create file device path for bootcount.env\r\n", __FUNCTION__); ++ return EFI_OUT_OF_RESOURCES; ++ } ++ ++ TmpFullDevicePath = FullDevicePath; ++ Status = EfiOpenFileByDevicePath (&TmpFullDevicePath, &FileHandle, EFI_FILE_MODE_READ, 0); ++ if (EFI_ERROR (Status)) { ++ ErrorPrint (L"%a: Failed to open boot slot file\r\n", __FUNCTION__); ++ return Status; ++ } else { ++ while (!FileHandleEof (FileHandle)) { ++ if (FileLine != NULL) { ++ FreePool (FileLine); ++ FileLine = NULL; ++ } ++ ++ FileLine = FileHandleReturnLine (FileHandle, &Ascii); ++ if (NULL == FileLine) { ++ break; ++ } ++ ++ CleanLine = CleanExtLinuxLine (FileLine); ++ if (*CleanLine != CHAR_NULL) { ++ if (StrStr(CleanLine, L"bootslot=")) { ++ ErrorPrint(L"%a: BootSlotFile contents: %s\r\n", __FUNCTION__, CleanLine); ++ *BootSlotValue = StrDecimalToUintn(CleanLine + 9); ++ ErrorPrint(L"%a: BootSlot is %u \r\n", __FUNCTION__, *BootSlotValue); ++ if (*BootSlotValue == BootChain) { ++ ErrorPrint(L"%a: Running on updated slot %u\r\n", __FUNCTION__, BootChain); ++ *IsRunningUpdatedSlot = TRUE; ++ } else { ++ ErrorPrint(L"%a: Running on fallback slot %u\r\n", __FUNCTION__, BootChain); ++ *IsRunningUpdatedSlot = FALSE; ++ } ++ ++ if (FileHandle != NULL) { ++ FileHandleClose (FileHandle); ++ } ++ } ++ ++ if (FileLine != NULL) { ++ FreePool (FileLine); ++ FileLine = NULL; ++ } ++ return Status; ++ } ++ } ++ } ++ ++ return EFI_SUCCESS; ++} ++ ++ + /** + Process the boot mode selection from command line and variables + +@@ -1718,7 +2186,7 @@ ProcessBootParams ( + } + + BootParams->BootChain = 0; +- ++ ErrorPrint(L"%a: Bootchain before set %u\r\n", __FUNCTION__, BootParams->BootChain); + DataSize = sizeof (BootParams->BootMode); + Status = gRT->GetVariable (L4T_BOOTMODE_VARIABLE_NAME, &gNVIDIAPublicVariableGuid, NULL, &DataSize, &BootParams->BootMode); + if (EFI_ERROR (Status) || (BootParams->BootMode > NVIDIA_L4T_BOOTMODE_RECOVERY)) { +@@ -1729,17 +2197,22 @@ ProcessBootParams ( + Status = gRT->GetVariable (BOOT_FW_VARIABLE_NAME, &gNVIDIAPublicVariableGuid, NULL, &DataSize, &BootChain); + // If variable does not exist, is >4 bytes or has a value larger than 1, boot partition A + if (!EFI_ERROR (Status) && (BootChain <= 1)) { ++ ErrorPrint(L"%a: Setting bootchain after reading BOOT_FW_VARIABLE_NAME\r\n", __FUNCTION__); + BootParams->BootChain = BootChain; + } +- ++ ErrorPrint(L"%a: Bootchain after checking BOOT_FW_VARIABLE_NAME %u\r\n", __FUNCTION__, BootParams->BootChain); ++ /* Below section is commented out because we don't know at this point if the active balenaOS rootfs is B and boot chain is A ++ * and even if it was, they should run independently. + // Read current OS boot type to allow for chaining + DataSize = sizeof (BootChain); + Status = gRT->GetVariable (BOOT_OS_VARIABLE_NAME, &gNVIDIAPublicVariableGuid, NULL, &DataSize, &BootChain); + // If variable does not exist, is >4 bytes or has a value larger than 1, boot partition A + if (!EFI_ERROR (Status) && (BootChain <= 1)) { ++ ErrorPrint(L"%a: Set bootchain after reading BOOT_OS_VARIABLE_NAME, %u\r\n", __FUNCTION__); + BootParams->BootChain = BootChain; + } +- ++ ErrorPrint(L"%a: Bootchain after checking/setting BOOT_OS_VARIABLE_NAME %u\r\n", __FUNCTION__, BootParams->BootChain); ++ */ + if (LoadedImage->LoadOptionsSize) { + CurrentBootOption = StrStr (LoadedImage->LoadOptions, BOOTMODE_DIRECT_STRING); + if (CurrentBootOption != NULL) { +@@ -1769,7 +2242,9 @@ ProcessBootParams ( + if (EFI_ERROR (Status)) { + ErrorPrint (L"Failed to read boot chain override: %r\r\n", Status); + } else if (StringValue <= 1) { ++ ErrorPrint (L"Overriding bootchain with String Value!\r\n"); + BootParams->BootChain = (UINT32)StringValue; ++ ErrorPrint(L"%a: Bootchain after checking/setting BOOT_OS_VARIABLE_NAME %u\r\n", __FUNCTION__, BootParams->BootChain); + } else { + ErrorPrint (L"Boot chain override value out of range, ignoring\r\n"); + } +@@ -1777,15 +2252,17 @@ ProcessBootParams ( + } + + // Find valid Rootfs Chain. If not, select recovery kernel +- Status = ValidateRootfsStatus (BootParams); +- if (EFI_ERROR (Status)) { +- ErrorPrint (L"Failed to validate rootfs status: %r\r\n", Status); +- } ++ //Status = ValidateRootfsStatus (BootParams); ++ //if (EFI_ERROR (Status)) { ++ ErrorPrint (L"Skip rootfs validation, this is performed by balenaOS.\r\n"); ++ //} + + // Store the current boot chain in volatile variable to allow chain loading + Status = gRT->SetVariable (BOOT_OS_VARIABLE_NAME, &gNVIDIAPublicVariableGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS, sizeof (BootParams->BootChain), &BootParams->BootChain); + if (EFI_ERROR (Status)) { + ErrorPrint (L"Failed to set OS variable: %r\r\n", Status); ++ } else { ++ ErrorPrint(L"%a: BOOT_OS_VARIABLE_NAME was set to %u\r\n", __FUNCTION__, BootParams->BootChain); + } + + return EFI_SUCCESS; +@@ -2434,7 +2911,14 @@ L4TLauncher ( + EXTLINUX_BOOT_CONFIG ExtLinuxConfig; + UINTN ExtLinuxBootOption; + UINTN Index; +- ++ CHAR16 *BalenaOSRootFs = NULL; ++ UINTN UpgradeAvailable = 0; ++ UINTN BootCountValue = 0; ++ UINTN RootFsIndex = BALENA_ROOTFS_INDEX_A; ++ UINTN UpdatedBootSlot = 0; ++ BOOLEAN RunningUpdatedBootSlot = FALSE; ++ BOOLEAN BootLimitReached = FALSE; ++ BOOLEAN BootSlotProcessed = FALSE; + Status = gBS->HandleProtocol (ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **)&LoadedImage); + if (EFI_ERROR (Status)) { + ErrorPrint (L"%a: Unable to locate loaded image: %r\r\n", __FUNCTION__, Status); +@@ -2498,12 +2982,73 @@ L4TLauncher ( + } while (FALSE); + } + ++ ErrorPrint(L"BalenaOS: Set BootMode to NVIDIA_L4T_BOOTMODE_DIRECT\r\r\n"); ++ BootParams.BootMode = NVIDIA_L4T_BOOTMODE_DIRECT; ++ + if (BootParams.BootMode == NVIDIA_L4T_BOOTMODE_DIRECT) { +- ErrorPrint (L"%a: Attempting Direct Boot\r\n", __FUNCTION__); ++ Print (L"%a: Attempting Direct Boot\r\n", __FUNCTION__); + do { +- Status = ProcessExtLinuxConfig (DeviceHandle, BootParams.BootChain, &ExtLinuxConfig, &RootFsDeviceHandle); ++ Status = ProcessResinOSuEnv (DeviceHandle, BootParams.BootChain, &RootFsIndex, &UpgradeAvailable); ++ if (EFI_ERROR (Status)) { ++ ErrorPrint(L"resinOS_uEnv.txt does not exist\n"); ++ } ++ ++ Print(L"Current resin_root_part=%d - upgrade_available=%d\r\n", RootFsIndex, UpgradeAvailable); ++ if (1 == UpgradeAvailable) { ++ Status = ProcessBootCountValue (DeviceHandle, BootParams.BootChain, &BootCountValue); ++ if (EFI_ERROR (Status)) { ++ ErrorPrint(L"%a: Error while processing bootcount value\r\n", __FUNCTION__); ++ } ++ Print (L"%a: BootCountValue is %d\r\n", __FUNCTION__, BootCountValue); ++ } ++ ++ Status = ProcessBootSlotFile(DeviceHandle, BootParams.BootChain, &UpdatedBootSlot, &RunningUpdatedBootSlot); ++ if (EFI_ERROR (Status)) { ++ ErrorPrint(L"%a: Error while processing boot slot value\r\n", __FUNCTION__); ++ } else { ++ ErrorPrint(L"%a: Updated (target) boot slot: %u - Current running boot slot: %u\r\n", __FUNCTION__, UpdatedBootSlot, BootParams.BootChain); ++ BootSlotProcessed = TRUE; ++ } ++ ++ /* If boot limit is reached while upgrade_available=1, switch partitions */ ++ if (BALENA_OS_BC_LIM <= BootCountValue) { ++ if (BALENA_ROOTFS_INDEX_B == RootFsIndex) { ++ RootFsIndex = BALENA_ROOTFS_INDEX_A; ++ } else { ++ RootFsIndex = BALENA_ROOTFS_INDEX_B; ++ } ++ BootLimitReached = TRUE; ++ ErrorPrint(L"%a: Reached bootcount limit, will switch partitions... New index is %d\r\n", __FUNCTION__, RootFsIndex); ++ ++ /* Running the same boot slot as our target, which has been updated by the UEFI capsule */ ++ if (RunningUpdatedBootSlot) { ++ ErrorPrint(L"%a: Running the updated boot slot %u and boot limit was reached, rebooting into fallback (pre-update) slot %u\r\n", __FUNCTION__, BootParams.BootChain, !BootParams.BootChain); ++ Status = SetNextBootChain(!BootParams.BootChain); ++ ResetCold(); ++ } else { ++ ErrorPrint(L"%a: Running the fallback (pre-update) boot slot %u because boot limit was reached. Updated boot slot booted previously was %u\r\n", __FUNCTION__, BootParams.BootChain, UpdatedBootSlot); ++ ++ ValidateActiveBootChain(); ++ ErrorPrint(L"%a: Running the fallback (pre-update) boot slot %u because boot limit was reached, and marked current one as active. Updated boot slot booted previously was %u\r\n", __FUNCTION__, BootParams.BootChain, UpdatedBootSlot); ++ } ++ } else if (1 == UpgradeAvailable && BootSlotProcessed && !RunningUpdatedBootSlot) { ++ ErrorPrint(L"%a: Capsule update failed or was interrupted, because current boot slot is %u when it should be %u. Forcing altboot mode so the system can recover. \r\n", __FUNCTION__, BootParams.BootChain, UpdatedBootSlot); ++ if (BALENA_ROOTFS_INDEX_B == RootFsIndex) { ++ RootFsIndex = BALENA_ROOTFS_INDEX_A; ++ } else { ++ RootFsIndex = BALENA_ROOTFS_INDEX_B; ++ } ++ } ++ ++ if (BALENA_ROOTFS_INDEX_B == RootFsIndex) { ++ BalenaOSRootFs = BALENA_ROOTFS_BASE_NAME_B; ++ } else { ++ BalenaOSRootFs = BALENA_ROOTFS_BASE_NAME_A; ++ } ++ ++ Status = ProcessExtLinuxConfig (DeviceHandle, BootParams.BootChain, BalenaOSRootFs, &ExtLinuxConfig, &RootFsDeviceHandle, RunningUpdatedBootSlot); + if (EFI_ERROR (Status)) { +- ErrorPrint (L"%a: Unable to process extlinux config: %r\r\n", __FUNCTION__, Status); ++ ErrorPrint (L"%a: ProcessExtLinuxConfig failed on partition %s: %r\r\n", __FUNCTION__, BalenaOSRootFs, Status); + BootParams.BootMode = NVIDIA_L4T_BOOTMODE_BOOTIMG; + break; + } +diff --git a/Silicon/NVIDIA/Application/L4TLauncher/L4TLauncher.h b/Silicon/NVIDIA/Application/L4TLauncher/L4TLauncher.h +index fc46a70d..e46c5e07 100644 +--- a/Silicon/NVIDIA/Application/L4TLauncher/L4TLauncher.h ++++ b/Silicon/NVIDIA/Application/L4TLauncher/L4TLauncher.h +@@ -32,11 +32,22 @@ + #define BOOT_OS_VARIABLE_NAME L"BootChainOsCurrent" + + #define ROOTFS_BASE_NAME L"APP" ++#define BALENA_ROOTFS_BASE_NAME_A L"resin-rootA" ++#define BALENA_ROOTFS_BASE_NAME_B L"resin-rootB" ++#define BALENA_BOOT_PARTITION L"resin-boot" ++#define BALENA_BOOT_CONF_PATH L"resinOS_uEnv.txt" ++#define BALENA_BOOTCOUNT_FILE_PATH L"bootcount.env" ++#define BALENA_BOOTSLOT_FILE_PATH L"bootslot.env" ++#define MAX_RESINOS_UENV_SIZE 256 ++#define BALENA_ROOTFS_INDEX_A 7 ++#define BALENA_ROOTFS_INDEX_B 8 ++#define BALENA_OS_BC_LIM 3 ++#define BALENA_EXTRA_UENV_FILE L"extra_uEnv.txt2" + #define BOOTIMG_BASE_NAME L"kernel" + #define BOOTIMG_DTB_BASE_NAME L"kernel-dtb" + #define RECOVERY_BASE_NAME L"recovery" + #define RECOVERY_DTB_BASE_NAME L"recovery-dtb" +- ++#define DEFAULT_AGX_ORIN_DTB_NAME L"tegra234-p3737-0000+p3701-0000-nv.dtb" + #define EXTLINUX_KEY_TIMEOUT L"TIMEOUT" + #define EXTLINUX_KEY_DEFAULT L"DEFAULT" + #define EXTLINUX_KEY_MENU_TITLE L"MENU TITLE" +@@ -48,8 +59,10 @@ + #define EXTLINUX_KEY_APPEND L"APPEND" + #define EXTLINUX_KEY_OVERLAYS L"OVERLAYS" + ++#define EXTLINUX_GENERIC_FDT L"default" + #define EXTLINUX_CBOOT_ARG L"${cbootargs}" + ++#define MAX_DTB_PATH_LEN 512 * 2 + #define MAX_EXTLINUX_OPTIONS 10 + + typedef struct { +-- +2.34.1 + diff --git a/layers/meta-balena-jetson/recipes-bsp/uefi/files/0001-Orin-NX-16GB-Integrate-with-balenaOS-on-L4T-36.3_patch.txt b/layers/meta-balena-jetson/recipes-bsp/uefi/files/0001-Orin-NX-16GB-Integrate-with-balenaOS-on-L4T-36.3_patch.txt index 4c767bfa..5f3a9482 100644 --- a/layers/meta-balena-jetson/recipes-bsp/uefi/files/0001-Orin-NX-16GB-Integrate-with-balenaOS-on-L4T-36.3_patch.txt +++ b/layers/meta-balena-jetson/recipes-bsp/uefi/files/0001-Orin-NX-16GB-Integrate-with-balenaOS-on-L4T-36.3_patch.txt @@ -1,6 +1,6 @@ -From f34879e479acb1964405285a043ebbf9d4e34dba Mon Sep 17 00:00:00 2001 +From 3f2be20463b1873a0f6c3bbef69729d59486745d Mon Sep 17 00:00:00 2001 From: Alexandru Costache -Date: Mon, 1 Jul 2024 12:46:17 +0000 +Date: Tue, 16 Jul 2024 09:25:40 +0000 Subject: [PATCH] Orin NX 16GB: Integrate with balenaOS on L4T 36.3 With this patch, the Nvidia bootloader parses resinos_uEnv.txt, @@ -11,12 +11,12 @@ rootfs. Upstream-Status: Inappropriate [configuration] Signed-off-by: Alexandru Costache --- - .../Application/L4TLauncher/L4TLauncher.c | 583 +++++++++++++++++- + .../Application/L4TLauncher/L4TLauncher.c | 584 +++++++++++++++++- .../Application/L4TLauncher/L4TLauncher.h | 15 +- - 2 files changed, 578 insertions(+), 20 deletions(-) + 2 files changed, 579 insertions(+), 20 deletions(-) diff --git a/Silicon/NVIDIA/Application/L4TLauncher/L4TLauncher.c b/Silicon/NVIDIA/Application/L4TLauncher/L4TLauncher.c -index ab86f3e0..97bf1bd7 100644 +index ab86f3e0..2c2f5d5a 100644 --- a/Silicon/NVIDIA/Application/L4TLauncher/L4TLauncher.c +++ b/Silicon/NVIDIA/Application/L4TLauncher/L4TLauncher.c @@ -1125,6 +1125,147 @@ CheckCommandString ( @@ -140,7 +140,7 @@ index ab86f3e0..97bf1bd7 100644 + if (NULL != DtbName) { + DtbName += StrLen(L"custom_fdt_file="); + UnicodeSPrint(*CustomFdtName, MAX_DTB_PATH_LEN, L"boot\\%s\0", DtbName); -+ Print(L"Selected dtb name is %s:\n", CustomFdtName); ++ Print(L"Selected dtb name is %s:\n", *CustomFdtName); + Status = CheckDtbExists(DeviceHandle, BootChain, BalenaOSRootFs, *CustomFdtName); + + if (EFI_ERROR(Status)) { @@ -150,16 +150,16 @@ index ab86f3e0..97bf1bd7 100644 + } + } + -+ if (FileHandle != NULL) { -+ FileHandleClose (FileHandle); -+ } -+ + if (FileLine != NULL) { + FreePool (FileLine); + FileLine = NULL; + } + } + ++ if (FileHandle != NULL) { ++ FileHandleClose (FileHandle); ++ } ++ + return EFI_SUCCESS; +} + @@ -266,7 +266,7 @@ index ab86f3e0..97bf1bd7 100644 Status = OpenAndReadFileToBuffer ( DeviceHandle, BootOption->DtbPath, -@@ -1690,6 +1864,300 @@ Exit: +@@ -1690,6 +1864,301 @@ Exit: return Status; } @@ -386,10 +386,6 @@ index ab86f3e0..97bf1bd7 100644 + if (StrStr(CleanLine, L"bootcount=")) { + *BootCountValue = StrDecimalToUintn(CleanLine + 10); + Print(L"%a: BootCount is %d\r\n", __FUNCTION__, *BootCountValue); -+ -+ if (FileHandle != NULL) { -+ FileHandleClose (FileHandle); -+ } + } + + if (FileLine != NULL) { @@ -402,6 +398,10 @@ index ab86f3e0..97bf1bd7 100644 + ErrorPrint (L"%a: Failed to write bootcount file value %d\r\n", __FUNCTION__, *BootCountValue); + } + ++ if (FileHandle != NULL) { ++ FileHandleClose (FileHandle); ++ } ++ + return Status; + } + } @@ -545,16 +545,17 @@ index ab86f3e0..97bf1bd7 100644 + ErrorPrint(L"%a: Running on fallback slot %u\r\n", __FUNCTION__, BootChain); + *IsRunningUpdatedSlot = FALSE; + } -+ -+ if (FileHandle != NULL) { -+ FileHandleClose (FileHandle); -+ } + } + + if (FileLine != NULL) { + FreePool (FileLine); + FileLine = NULL; + } ++ ++ if (FileHandle != NULL) { ++ FileHandleClose (FileHandle); ++ } ++ + return Status; + } + } @@ -567,7 +568,7 @@ index ab86f3e0..97bf1bd7 100644 /** Process the boot mode selection from command line and variables -@@ -1718,7 +2186,7 @@ ProcessBootParams ( +@@ -1718,7 +2187,7 @@ ProcessBootParams ( } BootParams->BootChain = 0; @@ -576,7 +577,7 @@ index ab86f3e0..97bf1bd7 100644 DataSize = sizeof (BootParams->BootMode); Status = gRT->GetVariable (L4T_BOOTMODE_VARIABLE_NAME, &gNVIDIAPublicVariableGuid, NULL, &DataSize, &BootParams->BootMode); if (EFI_ERROR (Status) || (BootParams->BootMode > NVIDIA_L4T_BOOTMODE_RECOVERY)) { -@@ -1729,17 +2197,22 @@ ProcessBootParams ( +@@ -1729,17 +2198,22 @@ ProcessBootParams ( Status = gRT->GetVariable (BOOT_FW_VARIABLE_NAME, &gNVIDIAPublicVariableGuid, NULL, &DataSize, &BootChain); // If variable does not exist, is >4 bytes or has a value larger than 1, boot partition A if (!EFI_ERROR (Status) && (BootChain <= 1)) { @@ -601,7 +602,7 @@ index ab86f3e0..97bf1bd7 100644 if (LoadedImage->LoadOptionsSize) { CurrentBootOption = StrStr (LoadedImage->LoadOptions, BOOTMODE_DIRECT_STRING); if (CurrentBootOption != NULL) { -@@ -1769,7 +2242,9 @@ ProcessBootParams ( +@@ -1769,7 +2243,9 @@ ProcessBootParams ( if (EFI_ERROR (Status)) { ErrorPrint (L"Failed to read boot chain override: %r\r\n", Status); } else if (StringValue <= 1) { @@ -611,7 +612,7 @@ index ab86f3e0..97bf1bd7 100644 } else { ErrorPrint (L"Boot chain override value out of range, ignoring\r\n"); } -@@ -1777,15 +2252,17 @@ ProcessBootParams ( +@@ -1777,15 +2253,17 @@ ProcessBootParams ( } // Find valid Rootfs Chain. If not, select recovery kernel @@ -633,7 +634,7 @@ index ab86f3e0..97bf1bd7 100644 } return EFI_SUCCESS; -@@ -2434,7 +2911,14 @@ L4TLauncher ( +@@ -2434,7 +2912,14 @@ L4TLauncher ( EXTLINUX_BOOT_CONFIG ExtLinuxConfig; UINTN ExtLinuxBootOption; UINTN Index; @@ -649,7 +650,7 @@ index ab86f3e0..97bf1bd7 100644 Status = gBS->HandleProtocol (ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **)&LoadedImage); if (EFI_ERROR (Status)) { ErrorPrint (L"%a: Unable to locate loaded image: %r\r\n", __FUNCTION__, Status); -@@ -2498,12 +2982,73 @@ L4TLauncher ( +@@ -2498,12 +2983,73 @@ L4TLauncher ( } while (FALSE); } diff --git a/layers/meta-balena-jetson/recipes-bsp/uefi/files/0001-Orin-Nano-Integrate-with-balenaOS-on-L4T-36.3_patch.txt b/layers/meta-balena-jetson/recipes-bsp/uefi/files/0001-Orin-Nano-Integrate-with-balenaOS-on-L4T-36.3_patch.txt index b418a867..d2f4d80f 100644 --- a/layers/meta-balena-jetson/recipes-bsp/uefi/files/0001-Orin-Nano-Integrate-with-balenaOS-on-L4T-36.3_patch.txt +++ b/layers/meta-balena-jetson/recipes-bsp/uefi/files/0001-Orin-Nano-Integrate-with-balenaOS-on-L4T-36.3_patch.txt @@ -1,7 +1,7 @@ -From c79fe40dd2881a798214d975d1bf34a113e37ed8 Mon Sep 17 00:00:00 2001 +From 9e06dbf1557acaae9eae46010e0ebde182a31571 Mon Sep 17 00:00:00 2001 From: Alexandru Costache -Date: Mon, 1 Jul 2024 12:40:26 +0000 -Subject: [PATCH] 2 Orin Nano: Integrate with balenaOS on L4T 36.3 +Date: Tue, 16 Jul 2024 09:16:00 +0000 +Subject: [PATCH] Orin Nano: Integrate with balenaOS on L4T 36.3 With this patch, the Nvidia bootloader parses resinos_uEnv.txt, extra_uEnv.txt and bootcount.env in order to load the @@ -11,12 +11,12 @@ rootfs. Upstream-Status: Inappropriate [configuration] Signed-off-by: Alexandru Costache --- - .../Application/L4TLauncher/L4TLauncher.c | 584 +++++++++++++++++- + .../Application/L4TLauncher/L4TLauncher.c | 583 +++++++++++++++++- .../Application/L4TLauncher/L4TLauncher.h | 15 +- - 2 files changed, 579 insertions(+), 20 deletions(-) + 2 files changed, 578 insertions(+), 20 deletions(-) diff --git a/Silicon/NVIDIA/Application/L4TLauncher/L4TLauncher.c b/Silicon/NVIDIA/Application/L4TLauncher/L4TLauncher.c -index ab86f3e0..23338b7c 100644 +index ab86f3e0..87d32558 100644 --- a/Silicon/NVIDIA/Application/L4TLauncher/L4TLauncher.c +++ b/Silicon/NVIDIA/Application/L4TLauncher/L4TLauncher.c @@ -1125,6 +1125,147 @@ CheckCommandString ( @@ -140,7 +140,7 @@ index ab86f3e0..23338b7c 100644 + if (NULL != DtbName) { + DtbName += StrLen(L"custom_fdt_file="); + UnicodeSPrint(*CustomFdtName, MAX_DTB_PATH_LEN, L"boot\\%s\0", DtbName); -+ Print(L"Selected dtb name is %s:\n", CustomFdtName); ++ Print(L"Selected dtb name is %s:\n", *CustomFdtName); + Status = CheckDtbExists(DeviceHandle, BootChain, BalenaOSRootFs, *CustomFdtName); + + if (EFI_ERROR(Status)) { @@ -150,16 +150,16 @@ index ab86f3e0..23338b7c 100644 + } + } + -+ if (FileHandle != NULL) { -+ FileHandleClose (FileHandle); -+ } -+ + if (FileLine != NULL) { + FreePool (FileLine); + FileLine = NULL; + } + } + ++ if (FileHandle != NULL) { ++ FileHandleClose (FileHandle); ++ } ++ + return EFI_SUCCESS; +} + @@ -266,7 +266,7 @@ index ab86f3e0..23338b7c 100644 Status = OpenAndReadFileToBuffer ( DeviceHandle, BootOption->DtbPath, -@@ -1690,6 +1864,300 @@ Exit: +@@ -1690,6 +1864,299 @@ Exit: return Status; } @@ -386,10 +386,6 @@ index ab86f3e0..23338b7c 100644 + if (StrStr(CleanLine, L"bootcount=")) { + *BootCountValue = StrDecimalToUintn(CleanLine + 10); + Print(L"%a: BootCount is %d\r\n", __FUNCTION__, *BootCountValue); -+ -+ if (FileHandle != NULL) { -+ FileHandleClose (FileHandle); -+ } + } + + if (FileLine != NULL) { @@ -402,6 +398,10 @@ index ab86f3e0..23338b7c 100644 + ErrorPrint (L"%a: Failed to write bootcount file value %d\r\n", __FUNCTION__, *BootCountValue); + } + ++ if (FileHandle != NULL) { ++ FileHandleClose (FileHandle); ++ } ++ + return Status; + } + } @@ -545,16 +545,15 @@ index ab86f3e0..23338b7c 100644 + ErrorPrint(L"%a: Running on fallback slot %u\r\n", __FUNCTION__, BootChain); + *IsRunningUpdatedSlot = FALSE; + } -+ -+ if (FileHandle != NULL) { -+ FileHandleClose (FileHandle); -+ } + } + + if (FileLine != NULL) { + FreePool (FileLine); + FileLine = NULL; + } ++ if (FileHandle != NULL) { ++ FileHandleClose (FileHandle); ++ } + return Status; + } + } @@ -567,7 +566,7 @@ index ab86f3e0..23338b7c 100644 /** Process the boot mode selection from command line and variables -@@ -1718,7 +2186,7 @@ ProcessBootParams ( +@@ -1718,7 +2185,7 @@ ProcessBootParams ( } BootParams->BootChain = 0; @@ -576,7 +575,7 @@ index ab86f3e0..23338b7c 100644 DataSize = sizeof (BootParams->BootMode); Status = gRT->GetVariable (L4T_BOOTMODE_VARIABLE_NAME, &gNVIDIAPublicVariableGuid, NULL, &DataSize, &BootParams->BootMode); if (EFI_ERROR (Status) || (BootParams->BootMode > NVIDIA_L4T_BOOTMODE_RECOVERY)) { -@@ -1729,17 +2197,22 @@ ProcessBootParams ( +@@ -1729,17 +2196,22 @@ ProcessBootParams ( Status = gRT->GetVariable (BOOT_FW_VARIABLE_NAME, &gNVIDIAPublicVariableGuid, NULL, &DataSize, &BootChain); // If variable does not exist, is >4 bytes or has a value larger than 1, boot partition A if (!EFI_ERROR (Status) && (BootChain <= 1)) { @@ -601,7 +600,7 @@ index ab86f3e0..23338b7c 100644 if (LoadedImage->LoadOptionsSize) { CurrentBootOption = StrStr (LoadedImage->LoadOptions, BOOTMODE_DIRECT_STRING); if (CurrentBootOption != NULL) { -@@ -1769,7 +2242,9 @@ ProcessBootParams ( +@@ -1769,7 +2241,9 @@ ProcessBootParams ( if (EFI_ERROR (Status)) { ErrorPrint (L"Failed to read boot chain override: %r\r\n", Status); } else if (StringValue <= 1) { @@ -611,7 +610,7 @@ index ab86f3e0..23338b7c 100644 } else { ErrorPrint (L"Boot chain override value out of range, ignoring\r\n"); } -@@ -1777,15 +2252,17 @@ ProcessBootParams ( +@@ -1777,15 +2251,17 @@ ProcessBootParams ( } // Find valid Rootfs Chain. If not, select recovery kernel @@ -633,7 +632,7 @@ index ab86f3e0..23338b7c 100644 } return EFI_SUCCESS; -@@ -2434,7 +2911,14 @@ L4TLauncher ( +@@ -2434,7 +2910,14 @@ L4TLauncher ( EXTLINUX_BOOT_CONFIG ExtLinuxConfig; UINTN ExtLinuxBootOption; UINTN Index; @@ -649,7 +648,7 @@ index ab86f3e0..23338b7c 100644 Status = gBS->HandleProtocol (ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **)&LoadedImage); if (EFI_ERROR (Status)) { ErrorPrint (L"%a: Unable to locate loaded image: %r\r\n", __FUNCTION__, Status); -@@ -2498,12 +2982,74 @@ L4TLauncher ( +@@ -2498,12 +2981,74 @@ L4TLauncher ( } while (FALSE); } diff --git a/layers/meta-balena-jetson/recipes-bsp/uefi/files/0001-Seeed-J3010-Integrate-with-balenaOS-on-L4T-36.3_patch.txt b/layers/meta-balena-jetson/recipes-bsp/uefi/files/0001-Seeed-J3010-Integrate-with-balenaOS-on-L4T-36.3_patch.txt index 80f64735..de6d0862 100644 --- a/layers/meta-balena-jetson/recipes-bsp/uefi/files/0001-Seeed-J3010-Integrate-with-balenaOS-on-L4T-36.3_patch.txt +++ b/layers/meta-balena-jetson/recipes-bsp/uefi/files/0001-Seeed-J3010-Integrate-with-balenaOS-on-L4T-36.3_patch.txt @@ -1,6 +1,6 @@ -From 598d58363eddacfbec574f807b0e3eb366afa3a4 Mon Sep 17 00:00:00 2001 +From 4fa2c09eac1dd66044758a65f394427b158068b4 Mon Sep 17 00:00:00 2001 From: Alexandru Costache -Date: Mon, 1 Jul 2024 12:50:36 +0000 +Date: Tue, 16 Jul 2024 09:57:47 +0000 Subject: [PATCH] Seeed J3010: Integrate with balenaOS on L4T 36.3 With this patch, the Nvidia bootloader parses resinos_uEnv.txt, @@ -11,12 +11,12 @@ rootfs. Upstream-Status: Inappropriate [configuration] Signed-off-by: Alexandru Costache --- - .../Application/L4TLauncher/L4TLauncher.c | 583 +++++++++++++++++- + .../Application/L4TLauncher/L4TLauncher.c | 584 +++++++++++++++++- .../Application/L4TLauncher/L4TLauncher.h | 15 +- - 2 files changed, 578 insertions(+), 20 deletions(-) + 2 files changed, 579 insertions(+), 20 deletions(-) diff --git a/Silicon/NVIDIA/Application/L4TLauncher/L4TLauncher.c b/Silicon/NVIDIA/Application/L4TLauncher/L4TLauncher.c -index ab86f3e0..d1e592da 100644 +index ab86f3e0..570a1a20 100644 --- a/Silicon/NVIDIA/Application/L4TLauncher/L4TLauncher.c +++ b/Silicon/NVIDIA/Application/L4TLauncher/L4TLauncher.c @@ -1125,6 +1125,147 @@ CheckCommandString ( @@ -140,7 +140,7 @@ index ab86f3e0..d1e592da 100644 + if (NULL != DtbName) { + DtbName += StrLen(L"custom_fdt_file="); + UnicodeSPrint(*CustomFdtName, MAX_DTB_PATH_LEN, L"boot\\%s\0", DtbName); -+ Print(L"Selected dtb name is %s:\n", CustomFdtName); ++ Print(L"Selected dtb name is %s\n", *CustomFdtName); + Status = CheckDtbExists(DeviceHandle, BootChain, BalenaOSRootFs, *CustomFdtName); + + if (EFI_ERROR(Status)) { @@ -150,16 +150,16 @@ index ab86f3e0..d1e592da 100644 + } + } + -+ if (FileHandle != NULL) { -+ FileHandleClose (FileHandle); -+ } -+ + if (FileLine != NULL) { + FreePool (FileLine); + FileLine = NULL; + } + } + ++ if (FileHandle != NULL) { ++ FileHandleClose (FileHandle); ++ } ++ + return EFI_SUCCESS; +} + @@ -266,7 +266,7 @@ index ab86f3e0..d1e592da 100644 Status = OpenAndReadFileToBuffer ( DeviceHandle, BootOption->DtbPath, -@@ -1690,6 +1864,300 @@ Exit: +@@ -1690,6 +1864,301 @@ Exit: return Status; } @@ -386,10 +386,6 @@ index ab86f3e0..d1e592da 100644 + if (StrStr(CleanLine, L"bootcount=")) { + *BootCountValue = StrDecimalToUintn(CleanLine + 10); + Print(L"%a: BootCount is %d\r\n", __FUNCTION__, *BootCountValue); -+ -+ if (FileHandle != NULL) { -+ FileHandleClose (FileHandle); -+ } + } + + if (FileLine != NULL) { @@ -402,6 +398,10 @@ index ab86f3e0..d1e592da 100644 + ErrorPrint (L"%a: Failed to write bootcount file value %d\r\n", __FUNCTION__, *BootCountValue); + } + ++ if (FileHandle != NULL) { ++ FileHandleClose (FileHandle); ++ } ++ + return Status; + } + } @@ -545,16 +545,17 @@ index ab86f3e0..d1e592da 100644 + ErrorPrint(L"%a: Running on fallback slot %u\r\n", __FUNCTION__, BootChain); + *IsRunningUpdatedSlot = FALSE; + } -+ -+ if (FileHandle != NULL) { -+ FileHandleClose (FileHandle); -+ } + } + + if (FileLine != NULL) { + FreePool (FileLine); + FileLine = NULL; + } ++ ++ if (FileHandle != NULL) { ++ FileHandleClose (FileHandle); ++ } ++ + return Status; + } + } @@ -567,7 +568,7 @@ index ab86f3e0..d1e592da 100644 /** Process the boot mode selection from command line and variables -@@ -1718,7 +2186,7 @@ ProcessBootParams ( +@@ -1718,7 +2187,7 @@ ProcessBootParams ( } BootParams->BootChain = 0; @@ -576,7 +577,7 @@ index ab86f3e0..d1e592da 100644 DataSize = sizeof (BootParams->BootMode); Status = gRT->GetVariable (L4T_BOOTMODE_VARIABLE_NAME, &gNVIDIAPublicVariableGuid, NULL, &DataSize, &BootParams->BootMode); if (EFI_ERROR (Status) || (BootParams->BootMode > NVIDIA_L4T_BOOTMODE_RECOVERY)) { -@@ -1729,17 +2197,22 @@ ProcessBootParams ( +@@ -1729,17 +2198,22 @@ ProcessBootParams ( Status = gRT->GetVariable (BOOT_FW_VARIABLE_NAME, &gNVIDIAPublicVariableGuid, NULL, &DataSize, &BootChain); // If variable does not exist, is >4 bytes or has a value larger than 1, boot partition A if (!EFI_ERROR (Status) && (BootChain <= 1)) { @@ -601,7 +602,7 @@ index ab86f3e0..d1e592da 100644 if (LoadedImage->LoadOptionsSize) { CurrentBootOption = StrStr (LoadedImage->LoadOptions, BOOTMODE_DIRECT_STRING); if (CurrentBootOption != NULL) { -@@ -1769,7 +2242,9 @@ ProcessBootParams ( +@@ -1769,7 +2243,9 @@ ProcessBootParams ( if (EFI_ERROR (Status)) { ErrorPrint (L"Failed to read boot chain override: %r\r\n", Status); } else if (StringValue <= 1) { @@ -611,7 +612,7 @@ index ab86f3e0..d1e592da 100644 } else { ErrorPrint (L"Boot chain override value out of range, ignoring\r\n"); } -@@ -1777,15 +2252,17 @@ ProcessBootParams ( +@@ -1777,15 +2253,17 @@ ProcessBootParams ( } // Find valid Rootfs Chain. If not, select recovery kernel @@ -633,7 +634,7 @@ index ab86f3e0..d1e592da 100644 } return EFI_SUCCESS; -@@ -2434,7 +2911,14 @@ L4TLauncher ( +@@ -2434,7 +2912,14 @@ L4TLauncher ( EXTLINUX_BOOT_CONFIG ExtLinuxConfig; UINTN ExtLinuxBootOption; UINTN Index; @@ -649,7 +650,7 @@ index ab86f3e0..d1e592da 100644 Status = gBS->HandleProtocol (ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **)&LoadedImage); if (EFI_ERROR (Status)) { ErrorPrint (L"%a: Unable to locate loaded image: %r\r\n", __FUNCTION__, Status); -@@ -2498,12 +2982,73 @@ L4TLauncher ( +@@ -2498,12 +2983,73 @@ L4TLauncher ( } while (FALSE); } diff --git a/layers/meta-balena-jetson/recipes-bsp/uefi/files/0001-Seeed-J4012-Integrate-with-balenaOS-on-L4T-36.3_patch.txt b/layers/meta-balena-jetson/recipes-bsp/uefi/files/0001-Seeed-J4012-Integrate-with-balenaOS-on-L4T-36.3_patch.txt index 52db4848..100b8dd3 100644 --- a/layers/meta-balena-jetson/recipes-bsp/uefi/files/0001-Seeed-J4012-Integrate-with-balenaOS-on-L4T-36.3_patch.txt +++ b/layers/meta-balena-jetson/recipes-bsp/uefi/files/0001-Seeed-J4012-Integrate-with-balenaOS-on-L4T-36.3_patch.txt @@ -1,6 +1,6 @@ -From 2da60da2fdec13c87e5a1d2a3507df95d405274b Mon Sep 17 00:00:00 2001 +From 5127308a2b0be7c742fb80303e87e70e3a8abe75 Mon Sep 17 00:00:00 2001 From: Alexandru Costache -Date: Mon, 1 Jul 2024 12:54:19 +0000 +Date: Tue, 16 Jul 2024 09:48:42 +0000 Subject: [PATCH] Seeed J4012: Integrate with balenaOS on L4T 36.3 With this patch, the Nvidia bootloader parses resinos_uEnv.txt, @@ -11,12 +11,12 @@ rootfs. Upstream-Status: Inappropriate [configuration] Signed-off-by: Alexandru Costache --- - .../Application/L4TLauncher/L4TLauncher.c | 582 +++++++++++++++++- + .../Application/L4TLauncher/L4TLauncher.c | 583 +++++++++++++++++- .../Application/L4TLauncher/L4TLauncher.h | 15 +- - 2 files changed, 577 insertions(+), 20 deletions(-) + 2 files changed, 578 insertions(+), 20 deletions(-) diff --git a/Silicon/NVIDIA/Application/L4TLauncher/L4TLauncher.c b/Silicon/NVIDIA/Application/L4TLauncher/L4TLauncher.c -index ab86f3e0..aaf6c383 100644 +index ab86f3e0..a5a18895 100644 --- a/Silicon/NVIDIA/Application/L4TLauncher/L4TLauncher.c +++ b/Silicon/NVIDIA/Application/L4TLauncher/L4TLauncher.c @@ -1125,6 +1125,147 @@ CheckCommandString ( @@ -140,7 +140,7 @@ index ab86f3e0..aaf6c383 100644 + if (NULL != DtbName) { + DtbName += StrLen(L"custom_fdt_file="); + UnicodeSPrint(*CustomFdtName, MAX_DTB_PATH_LEN, L"boot\\%s\0", DtbName); -+ Print(L"Selected dtb name is %s:\n", CustomFdtName); ++ Print(L"Selected dtb name is %s:\n", *CustomFdtName); + Status = CheckDtbExists(DeviceHandle, BootChain, BalenaOSRootFs, *CustomFdtName); + + if (EFI_ERROR(Status)) { @@ -150,16 +150,16 @@ index ab86f3e0..aaf6c383 100644 + } + } + -+ if (FileHandle != NULL) { -+ FileHandleClose (FileHandle); -+ } -+ + if (FileLine != NULL) { + FreePool (FileLine); + FileLine = NULL; + } + } + ++ if (FileHandle != NULL) { ++ FileHandleClose (FileHandle); ++ } ++ + return EFI_SUCCESS; +} + @@ -266,7 +266,7 @@ index ab86f3e0..aaf6c383 100644 Status = OpenAndReadFileToBuffer ( DeviceHandle, BootOption->DtbPath, -@@ -1690,6 +1864,300 @@ Exit: +@@ -1690,6 +1864,301 @@ Exit: return Status; } @@ -386,10 +386,6 @@ index ab86f3e0..aaf6c383 100644 + if (StrStr(CleanLine, L"bootcount=")) { + *BootCountValue = StrDecimalToUintn(CleanLine + 10); + Print(L"%a: BootCount is %d\r\n", __FUNCTION__, *BootCountValue); -+ -+ if (FileHandle != NULL) { -+ FileHandleClose (FileHandle); -+ } + } + + if (FileLine != NULL) { @@ -402,6 +398,10 @@ index ab86f3e0..aaf6c383 100644 + ErrorPrint (L"%a: Failed to write bootcount file value %d\r\n", __FUNCTION__, *BootCountValue); + } + ++ if (FileHandle != NULL) { ++ FileHandleClose (FileHandle); ++ } ++ + return Status; + } + } @@ -545,16 +545,17 @@ index ab86f3e0..aaf6c383 100644 + ErrorPrint(L"%a: Running on fallback slot %u\r\n", __FUNCTION__, BootChain); + *IsRunningUpdatedSlot = FALSE; + } -+ -+ if (FileHandle != NULL) { -+ FileHandleClose (FileHandle); -+ } + } + + if (FileLine != NULL) { + FreePool (FileLine); + FileLine = NULL; + } ++ ++ if (FileHandle != NULL) { ++ FileHandleClose (FileHandle); ++ } ++ + return Status; + } + } @@ -567,7 +568,7 @@ index ab86f3e0..aaf6c383 100644 /** Process the boot mode selection from command line and variables -@@ -1718,7 +2186,7 @@ ProcessBootParams ( +@@ -1718,7 +2187,7 @@ ProcessBootParams ( } BootParams->BootChain = 0; @@ -576,7 +577,7 @@ index ab86f3e0..aaf6c383 100644 DataSize = sizeof (BootParams->BootMode); Status = gRT->GetVariable (L4T_BOOTMODE_VARIABLE_NAME, &gNVIDIAPublicVariableGuid, NULL, &DataSize, &BootParams->BootMode); if (EFI_ERROR (Status) || (BootParams->BootMode > NVIDIA_L4T_BOOTMODE_RECOVERY)) { -@@ -1729,17 +2197,22 @@ ProcessBootParams ( +@@ -1729,17 +2198,22 @@ ProcessBootParams ( Status = gRT->GetVariable (BOOT_FW_VARIABLE_NAME, &gNVIDIAPublicVariableGuid, NULL, &DataSize, &BootChain); // If variable does not exist, is >4 bytes or has a value larger than 1, boot partition A if (!EFI_ERROR (Status) && (BootChain <= 1)) { @@ -601,7 +602,7 @@ index ab86f3e0..aaf6c383 100644 if (LoadedImage->LoadOptionsSize) { CurrentBootOption = StrStr (LoadedImage->LoadOptions, BOOTMODE_DIRECT_STRING); if (CurrentBootOption != NULL) { -@@ -1769,7 +2242,9 @@ ProcessBootParams ( +@@ -1769,7 +2243,9 @@ ProcessBootParams ( if (EFI_ERROR (Status)) { ErrorPrint (L"Failed to read boot chain override: %r\r\n", Status); } else if (StringValue <= 1) { @@ -611,7 +612,7 @@ index ab86f3e0..aaf6c383 100644 } else { ErrorPrint (L"Boot chain override value out of range, ignoring\r\n"); } -@@ -1777,15 +2252,17 @@ ProcessBootParams ( +@@ -1777,15 +2253,17 @@ ProcessBootParams ( } // Find valid Rootfs Chain. If not, select recovery kernel @@ -633,7 +634,7 @@ index ab86f3e0..aaf6c383 100644 } return EFI_SUCCESS; -@@ -2434,7 +2911,14 @@ L4TLauncher ( +@@ -2434,7 +2912,14 @@ L4TLauncher ( EXTLINUX_BOOT_CONFIG ExtLinuxConfig; UINTN ExtLinuxBootOption; UINTN Index; @@ -649,7 +650,7 @@ index ab86f3e0..aaf6c383 100644 Status = gBS->HandleProtocol (ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **)&LoadedImage); if (EFI_ERROR (Status)) { ErrorPrint (L"%a: Unable to locate loaded image: %r\r\n", __FUNCTION__, Status); -@@ -2498,12 +2982,72 @@ L4TLauncher ( +@@ -2498,12 +2983,72 @@ L4TLauncher ( } while (FALSE); } diff --git a/layers/meta-balena-jetson/recipes-bsp/uefi/files/0001-feat-add-a-null-version-of-the-FwVariableLib_patch.txt b/layers/meta-balena-jetson/recipes-bsp/uefi/files/0001-feat-add-a-null-version-of-the-FwVariableLib_patch.txt deleted file mode 100644 index a1f373cb..00000000 --- a/layers/meta-balena-jetson/recipes-bsp/uefi/files/0001-feat-add-a-null-version-of-the-FwVariableLib_patch.txt +++ /dev/null @@ -1,103 +0,0 @@ -From 8f99f1efdd6782f9b4ec35b1c6927a196797a0b5 Mon Sep 17 00:00:00 2001 -From: Alexandru Costache -Date: Mon, 24 Jun 2024 17:10:40 +0300 -Subject: [PATCH 1/3] feat: add a null version of the FwVariableLib - -Add a null version of the FwVariableLib that targets using emulated -variable store can include. - -Backported-from: -https://github.com/NVIDIA/edk2-nvidia/commit/92bc1c3468ec44f5c04eefe2f91844d92bdc6219 - -Signed-off-by: Girish Mahadevan -Reviewed-by: Ashish Singhal ---- - Platform/NVIDIA/TegraVirt/TegraVirt.dsc | 2 +- - .../FwVariableLibNull/FwVariableLib.inf | 27 +++++++++++++++++++ - .../FwVariableLibNull/FwVariableLibNull.c | 27 +++++++++++++++++++ - 3 files changed, 55 insertions(+), 1 deletion(-) - create mode 100644 Silicon/NVIDIA/Library/FwVariableLibNull/FwVariableLib.inf - create mode 100644 Silicon/NVIDIA/Library/FwVariableLibNull/FwVariableLibNull.c - -diff --git a/Platform/NVIDIA/TegraVirt/TegraVirt.dsc b/Platform/NVIDIA/TegraVirt/TegraVirt.dsc -index f457392c..d52d6e69 100644 ---- a/Platform/NVIDIA/TegraVirt/TegraVirt.dsc -+++ b/Platform/NVIDIA/TegraVirt/TegraVirt.dsc -@@ -91,7 +91,7 @@ - TpmPlatformHierarchyLib|SecurityPkg/Library/PeiDxeTpmPlatformHierarchyLibNull/PeiDxeTpmPlatformHierarchyLib.inf - Tcg2PhysicalPresenceLib|Silicon/NVIDIA/Library/DxeTcg2PhysicalPresenceLibNull/DxeTcg2PhysicalPresenceLibNull.inf - IpmiBaseLib|IpmiFeaturePkg/Library/IpmiBaseLib/IpmiBaseLib.inf -- FwVariableLib|Silicon/NVIDIA/Library/FwVariableLib/FwVariableLib.inf -+ FwVariableLib|Silicon/NVIDIA/Library/FwVariableLibNull/FwVariableLib.inf - - # AndroidBootDxe Libraries - NvgLib|Silicon/NVIDIA/Library/NvgLib/NvgLib.inf -diff --git a/Silicon/NVIDIA/Library/FwVariableLibNull/FwVariableLib.inf b/Silicon/NVIDIA/Library/FwVariableLibNull/FwVariableLib.inf -new file mode 100644 -index 00000000..23412d20 ---- /dev/null -+++ b/Silicon/NVIDIA/Library/FwVariableLibNull/FwVariableLib.inf -@@ -0,0 +1,27 @@ -+## @file -+# -+# FwVariableLib - Firmware variable support library -+# -+# SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -+# SPDX-License-Identifier: BSD-2-Clause-Patent -+# -+## -+ -+[Defines] -+ INF_VERSION = 0x00010005 -+ BASE_NAME = FwVariableLibNull -+ FILE_GUID = 1a2fdba4-93fa-4b64-bb92-2c5792a76caa -+ MODULE_TYPE = BASE -+ VERSION_STRING = 1.0 -+ LIBRARY_CLASS = FwVariableLib -+ -+[Sources.common] -+ FwVariableLibNull.c -+ -+[Packages] -+ MdePkg/MdePkg.dec -+ Silicon/NVIDIA/NVIDIA.dec -+ -+[LibraryClasses] -+ BaseLib -+ -diff --git a/Silicon/NVIDIA/Library/FwVariableLibNull/FwVariableLibNull.c b/Silicon/NVIDIA/Library/FwVariableLibNull/FwVariableLibNull.c -new file mode 100644 -index 00000000..729882d9 ---- /dev/null -+++ b/Silicon/NVIDIA/Library/FwVariableLibNull/FwVariableLibNull.c -@@ -0,0 +1,27 @@ -+/** @file -+ -+ FwVariableLibNull - Null Version of the Firmware variable support library -+ -+ SPDX-FileCopyrightText: Copyright (c) 2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved. -+ SPDX-License-Identifier: BSD-2-Clause-Patent -+ -+**/ -+ -+#include -+#include -+#include -+ -+/** -+ Delete all Firmware Variables -+ Stub version that returns success only. -+ -+ @retval EFI_SUCCESS All variables deleted -+ -+**/ -+EFI_STATUS -+EFIAPI -+FwVariableDeleteAll ( -+ ) -+{ -+ return EFI_SUCCESS; -+} --- -2.34.1 - diff --git a/layers/meta-balena-jetson/recipes-bsp/uefi/files/0002-fix-don-t-try-to-erase-early-vars-partition-in-Jetso_patch.txt b/layers/meta-balena-jetson/recipes-bsp/uefi/files/0002-fix-don-t-try-to-erase-early-vars-partition-in-Jetso_patch.txt deleted file mode 100644 index d5fcf24a..00000000 --- a/layers/meta-balena-jetson/recipes-bsp/uefi/files/0002-fix-don-t-try-to-erase-early-vars-partition-in-Jetso_patch.txt +++ /dev/null @@ -1,103 +0,0 @@ -From ca9deb161bb3e6570f24906cbed9477c930abc8a Mon Sep 17 00:00:00 2001 -From: Alexandru Costache -Date: Mon, 24 Jun 2024 17:11:27 +0300 -Subject: [PATCH 2/3] fix: don't try to erase early vars partition in Jetson - -Part of resetting the settings from the UEFI menu entails erasing the -Early Variables partition, but this partition isn't present on Jetson -targets and sending this request to StMM would result in an ASSERT from -the secure code. - -Backported-from: https://github.com/NVIDIA/edk2-nvidia/commit/1b61c7443e37c8673934135ecdf5ef4d86aca2d6 - -Signed-off-by: Girish Mahadevan -Reviewed-by: Ashish Singhal ---- - .../Library/FwVariableLib/FwVariableLib.c | 27 +++++++++++-------- - .../Library/FwVariableLib/FwVariableLib.inf | 4 +-- - 2 files changed, 18 insertions(+), 13 deletions(-) - -diff --git a/Silicon/NVIDIA/Library/FwVariableLib/FwVariableLib.c b/Silicon/NVIDIA/Library/FwVariableLib/FwVariableLib.c -index 3d14f655..21e4d81b 100644 ---- a/Silicon/NVIDIA/Library/FwVariableLib/FwVariableLib.c -+++ b/Silicon/NVIDIA/Library/FwVariableLib/FwVariableLib.c -@@ -2,8 +2,7 @@ - - FwVariableLib - Firmware variable support library - -- Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -- -+ SPDX-FileCopyrightText: Copyright (c) 2023 - 2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved. - SPDX-License-Identifier: BSD-2-Clause-Patent - - **/ -@@ -17,6 +16,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -167,6 +167,7 @@ FwVariableDeleteAll ( - EFI_GUID CurrentGuid; - EFI_GUID NextGuid; - UINTN NameSize; -+ UINTN ChipId; - - CurrentName = NULL; - NextName = NULL; -@@ -227,15 +228,19 @@ FwVariableDeleteAll ( - goto CleanupAndReturn; - } - -- Status = EraseMb1VariablePartition (); -- if (EFI_ERROR (Status)) { -- DEBUG (( -- DEBUG_ERROR, -- "%a: Failed to Erase Mb1 Var Partition %r\n", -- __FUNCTION__, -- Status -- )); -- goto CleanupAndReturn; -+ ChipId = TegraGetChipID (); -+ -+ if (ChipId == TH500_CHIP_ID) { -+ Status = EraseMb1VariablePartition (); -+ if (EFI_ERROR (Status)) { -+ DEBUG (( -+ DEBUG_ERROR, -+ "%a: Failed to Erase Mb1 Var Partition %r\n", -+ __FUNCTION__, -+ Status -+ )); -+ goto CleanupAndReturn; -+ } - } - - Status = EFI_SUCCESS; -diff --git a/Silicon/NVIDIA/Library/FwVariableLib/FwVariableLib.inf b/Silicon/NVIDIA/Library/FwVariableLib/FwVariableLib.inf -index 5ba138c3..856e1973 100644 ---- a/Silicon/NVIDIA/Library/FwVariableLib/FwVariableLib.inf -+++ b/Silicon/NVIDIA/Library/FwVariableLib/FwVariableLib.inf -@@ -2,8 +2,7 @@ - # - # FwVariableLib - Firmware variable support library - # --# Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. --# -+# SPDX-FileCopyrightText: Copyright (c) 2023 - 2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved. - # SPDX-License-Identifier: BSD-2-Clause-Patent - # - ## -@@ -26,6 +25,7 @@ - [LibraryClasses] - BaseLib - ReportStatusCodeLib -+ TegraPlatformInfoLib - - [Guids] - gNVIDIAMmMb1RecordGuid --- -2.34.1 - diff --git a/layers/meta-balena-jetson/recipes-bsp/uefi/files/0003-fix-reset-the-meas-buffer-after-computing-the-first-_patch.txt b/layers/meta-balena-jetson/recipes-bsp/uefi/files/0003-fix-reset-the-meas-buffer-after-computing-the-first-_patch.txt deleted file mode 100644 index 438657ad..00000000 --- a/layers/meta-balena-jetson/recipes-bsp/uefi/files/0003-fix-reset-the-meas-buffer-after-computing-the-first-_patch.txt +++ /dev/null @@ -1,95 +0,0 @@ -From 627a6814eedae481243fa30cdf96c894929bf0c5 Mon Sep 17 00:00:00 2001 -From: Alexandru Costache -Date: Mon, 24 Jun 2024 17:11:55 +0300 -Subject: [PATCH 3/3] fix: reset the meas buffer after computing the first - measurement - -After using the measurement buffer to verify the variable -store, reset it back to 0. -Without this change, if a var write comes in the FVB driver -treats the contents of the measurement buffer as valid to be -committed and it throws the state machine off. -Also return an error when checking if the Measurement partition -is zero or erased to force a re-init of the VarStore. - -Backported-from: https://github.com/NVIDIA/edk2-nvidia/commit/615288ae7635103213e81e7356b3e47e283306f5 - -Signed-off-by: Girish Mahadevan -Reviewed-by: Ashish Singhal ---- - .../FvbNorFlashDxe/FvbNorFlashStandaloneMm.c | 13 +++++++++++-- - Silicon/NVIDIA/Drivers/FvbNorFlashDxe/VarIntCheck.c | 5 +++-- - 2 files changed, 14 insertions(+), 4 deletions(-) - -diff --git a/Silicon/NVIDIA/Drivers/FvbNorFlashDxe/FvbNorFlashStandaloneMm.c b/Silicon/NVIDIA/Drivers/FvbNorFlashDxe/FvbNorFlashStandaloneMm.c -index 9575cb47..b8bc03d4 100644 ---- a/Silicon/NVIDIA/Drivers/FvbNorFlashDxe/FvbNorFlashStandaloneMm.c -+++ b/Silicon/NVIDIA/Drivers/FvbNorFlashDxe/FvbNorFlashStandaloneMm.c -@@ -1004,6 +1004,8 @@ MmFvbSmmVarReady ( - @param CheckVariableStore - TRUE if the variable data should be checked - @param NorFlashProtocol - Pointer to nor flash protocol - @param FlashAttributes - Pointer to flash attributes for the nor flash partition is on -+ @param MeasurementOffset - Offset of the Measuremet partition -+ @param MeasurementSize - Size of the Measurement partition - - **/ - EFI_STATUS -@@ -1075,7 +1077,12 @@ ValidateFvHeader ( - // then check if the partition is erased. If it is erased, then re-initialize the varstore, as it - // could be a possible tamper. - if (CheckVarStoreIntegrity == TRUE) { -- if (IsMeasurementPartitionErasedOrZero (NorFlashProtocol, MeasurementOffset, MeasurementPartitionSize) == TRUE) { -+ if (IsMeasurementPartitionErasedOrZero ( -+ NorFlashProtocol, -+ MeasurementOffset, -+ MeasurementPartitionSize -+ ) == TRUE) -+ { - DEBUG ((DEBUG_ERROR, "%a: No Valid Measurements found. Re-initializing the Variable Store\n", __FUNCTION__)); - Status = EraseMeasurementPartition (NorFlashProtocol, MeasurementOffset, MeasurementPartitionSize); - if (EFI_ERROR (Status)) { -@@ -1085,8 +1092,10 @@ ValidateFvHeader ( - __FUNCTION__, - Status - )); -- return Status; - } -+ -+ // return EFI_NOT_FOUND to force a re-init. -+ return EFI_NOT_FOUND; - } - } - } -diff --git a/Silicon/NVIDIA/Drivers/FvbNorFlashDxe/VarIntCheck.c b/Silicon/NVIDIA/Drivers/FvbNorFlashDxe/VarIntCheck.c -index 5a73607f..53d5fc2a 100644 ---- a/Silicon/NVIDIA/Drivers/FvbNorFlashDxe/VarIntCheck.c -+++ b/Silicon/NVIDIA/Drivers/FvbNorFlashDxe/VarIntCheck.c -@@ -323,7 +323,7 @@ GetWriteOffset ( - } - - if ((*Offset % This->BlockSize) == 0) { -- DEBUG ((DEBUG_ERROR, "Erasing BLock %lu\n", *Offset)); -+ DEBUG ((DEBUG_INFO, "Erasing BLock %lu\n", *Offset)); - Status = NorFlashProtocol->Erase ( - NorFlashProtocol, - (*Offset / This->BlockSize), -@@ -1019,6 +1019,7 @@ ExitVarIntValidate: - } - } - -+ ZeroMem (This->CurMeasurement, This->MeasurementSize); - return Status; - } - -@@ -1069,7 +1070,7 @@ VarIntInit ( - } - - DEBUG (( -- DEBUG_ERROR, -+ DEBUG_INFO, - "%a: Partition Start 0x%lx %lu Size %u\n", - __FUNCTION__, - PartitionStartOffset, --- -2.34.1 - diff --git a/layers/meta-balena-jetson/recipes-bsp/uefi/files/Dockerfile b/layers/meta-balena-jetson/recipes-bsp/uefi/files/Dockerfile index 79157c80..9dd2707d 100644 --- a/layers/meta-balena-jetson/recipes-bsp/uefi/files/Dockerfile +++ b/layers/meta-balena-jetson/recipes-bsp/uefi/files/Dockerfile @@ -22,9 +22,6 @@ COPY ./0001-Orin-NX-16GB-Integrate-with-balenaOS-on-L4T-36.3_patch.txt /build/nv COPY ./0001-Seeed-J4012-Integrate-with-balenaOS-on-L4T-36.3_patch.txt /build/nvidia-uefi/edk2-nvidia/0001-Seeed-J4012-Integrate-with-balenaOS-on-L4T-36.3.patch COPY ./0001-Seeed-J3010-Integrate-with-balenaOS-on-L4T-36.3_patch.txt /build/nvidia-uefi/edk2-nvidia/0001-Seeed-J3010-Integrate-with-balenaOS-on-L4T-36.3.patch COPY ./0001-edk2-nvidia-Remove-pva-fw-from-required-list_patch.txt /build/nvidia-uefi/edk2-nvidia/0001-edk2-nvidia-Remove-pva-fw-from-required-list.patch -COPY ./0001-feat-add-a-null-version-of-the-FwVariableLib_patch.txt /build/nvidia-uefi/edk2-nvidia/0001-feat-add-a-null-version-of-the-FwVariableLib.patch -COPY ./0002-fix-don-t-try-to-erase-early-vars-partition-in-Jetso_patch.txt /build/nvidia-uefi/edk2-nvidia/0002-fix-don-t-try-to-erase-early-vars-partition-in-Jetso.patch -COPY ./0003-fix-reset-the-meas-buffer-after-computing-the-first-_patch.txt /build/nvidia-uefi/edk2-nvidia/0003-fix-reset-the-meas-buffer-after-computing-the-first-.patch # We keep the reference to the patch below, but don't use it right now because the tos-optee built using the public atf & optee sources # using the standalone_optee binary generated here crashes. See https://forums.developer.nvidia.com/t/jetson-orin-nano-ota-35-5-0-36-3-failed-to-boot-after-ota-upgrade-from-35-5-0-to-36-3/296205/16 diff --git a/layers/meta-balena-jetson/recipes-bsp/uefi/files/build.sh b/layers/meta-balena-jetson/recipes-bsp/uefi/files/build.sh index 9ec436af..20a564c2 100644 --- a/layers/meta-balena-jetson/recipes-bsp/uefi/files/build.sh +++ b/layers/meta-balena-jetson/recipes-bsp/uefi/files/build.sh @@ -13,12 +13,8 @@ device_specific_patches["jetson-orin-nx-seeed-j4012"]="0001-Seeed-J4012-Integrat device_specific_patches["jetson-orin-nano-seeed-j3010"]="0001-Seeed-J3010-Integrate-with-balenaOS-on-L4T-36.3.patch" edk2_patch="0001-edk2-Disable-network-boot-and-allow-UEFI-capsule-dow.patch" - edk2_nvidia_patches=( "0001-edk2-nvidia-Add-changes-for-balenaOS-integration.patch " \ - "0001-edk2-nvidia-Remove-pva-fw-from-required-list.patch" \ - "0001-feat-add-a-null-version-of-the-FwVariableLib.patch" \ - "0002-fix-don-t-try-to-erase-early-vars-partition-in-Jetso.patch" \ - "0003-fix-reset-the-meas-buffer-after-computing-the-first-.patch" ) + "0001-edk2-nvidia-Remove-pva-fw-from-required-list.patch" ) cd /build/nvidia-uefi/edk2 && \ git reset --hard HEAD && \