From d8f36fb56834e26a03e8993ca76d2f3870dd0b39 Mon Sep 17 00:00:00 2001 From: Olivier Martin Date: Mon, 19 May 2014 16:41:25 +0000 Subject: ArmPkg/BdsLib: Added support for TFTP servers without 'tsize' extension Some TFTP servers do not have 'tsize' extension. This change allows to download files from TFTP servers that do not have this extension by trying to download the file into a pre-allocated buffer. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Olivier Martin git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15539 6f19259b-4bc3-4df7-8a09-765794883524 --- ArmPkg/ArmPkg.dec | 2 + ArmPkg/Library/BdsLib/BdsFilePath.c | 98 ++++++++++++++++++++++++++----------- ArmPkg/Library/BdsLib/BdsLib.inf | 4 +- 3 files changed, 75 insertions(+), 29 deletions(-) (limited to 'ArmPkg') diff --git a/ArmPkg/ArmPkg.dec b/ArmPkg/ArmPkg.dec index 5efef7c9d..14f16b851 100644 --- a/ArmPkg/ArmPkg.dec +++ b/ArmPkg/ArmPkg.dec @@ -133,6 +133,8 @@ gArmTokenSpaceGuid.PcdArmMachineType|0|UINT32|0x0000001E # The compressed Linux kernel is expected to be under 128MB from the beginning of the System Memory gArmTokenSpaceGuid.PcdArmLinuxKernelMaxOffset|0x08000000|UINT32|0x0000001F + # Maximum file size for TFTP servers that do not support 'tsize' extension + gArmTokenSpaceGuid.PcdMaxTftpFileSize|0x01000000|UINT32|0x00000000 # # ARM Architectural Timer diff --git a/ArmPkg/Library/BdsLib/BdsFilePath.c b/ArmPkg/Library/BdsLib/BdsFilePath.c index 90be9c1e1..f3fa44565 100644 --- a/ArmPkg/Library/BdsLib/BdsFilePath.c +++ b/ArmPkg/Library/BdsLib/BdsFilePath.c @@ -1,6 +1,6 @@ /** @file * -* Copyright (c) 2011-2013, ARM Limited. All rights reserved. +* Copyright (c) 2011-2014, ARM Limited. All rights reserved. * * This program and the accompanying materials * are licensed and made available under the terms and conditions of the BSD License @@ -817,6 +817,7 @@ BdsTftpLoadImage ( } UnicodeStrToAsciiStr (FilePathDevicePath->PathName, AsciiPathName); + // Try to get the size (required the TFTP server to have "tsize" extension) Status = Pxe->Mtftp ( Pxe, EFI_PXE_BASE_CODE_TFTP_GET_FILE_SIZE, @@ -829,41 +830,82 @@ BdsTftpLoadImage ( NULL, FALSE ); - if (EFI_ERROR(Status)) { + // Pxe.Mtftp replies EFI_PROTOCOL_ERROR if tsize is not supported by the TFTP server + if (EFI_ERROR (Status) && (Status != EFI_PROTOCOL_ERROR)) { if (Status == EFI_TFTP_ERROR) { DEBUG((EFI_D_ERROR, "TFTP Error: Fail to get the size of the file\n")); } goto EXIT; } - // Allocate a buffer to hold the whole file. - Status = gBS->AllocatePages ( - Type, - EfiBootServicesCode, - EFI_SIZE_TO_PAGES (TftpBufferSize), - Image - ); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "Failed to allocate space for kernel image: %r\n", Status)); - goto EXIT; - } + // + // Two cases: + // 1) the file size is unknown (tsize extension not supported) + // 2) tsize returned the file size + // + if (Status == EFI_PROTOCOL_ERROR) { + for (TftpBufferSize = SIZE_8MB; TftpBufferSize <= FixedPcdGet32 (PcdMaxTftpFileSize); TftpBufferSize += SIZE_8MB) { + // Allocate a buffer to hold the whole file. + Status = gBS->AllocatePages ( + Type, + EfiBootServicesCode, + EFI_SIZE_TO_PAGES (TftpBufferSize), + Image + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "Failed to allocate space for image: %r\n", Status)); + goto EXIT; + } - Status = Pxe->Mtftp ( - Pxe, - EFI_PXE_BASE_CODE_TFTP_READ_FILE, - (VOID *)(UINTN)*Image, - FALSE, - &TftpBufferSize, - NULL, - &ServerIp, - (UINT8*)AsciiPathName, - NULL, - FALSE - ); - if (EFI_ERROR (Status)) { - gBS->FreePages (*Image, EFI_SIZE_TO_PAGES (TftpBufferSize)); + Status = Pxe->Mtftp ( + Pxe, + EFI_PXE_BASE_CODE_TFTP_READ_FILE, + (VOID *)(UINTN)*Image, + FALSE, + &TftpBufferSize, + NULL, + &ServerIp, + (UINT8*)AsciiPathName, + NULL, + FALSE + ); + if (EFI_ERROR (Status)) { + gBS->FreePages (*Image, EFI_SIZE_TO_PAGES (TftpBufferSize)); + } else { + *ImageSize = (UINTN)TftpBufferSize; + break; + } + } } else { - *ImageSize = (UINTN)TftpBufferSize; + // Allocate a buffer to hold the whole file. + Status = gBS->AllocatePages ( + Type, + EfiBootServicesCode, + EFI_SIZE_TO_PAGES (TftpBufferSize), + Image + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "Failed to allocate space for kernel image: %r\n", Status)); + goto EXIT; + } + + Status = Pxe->Mtftp ( + Pxe, + EFI_PXE_BASE_CODE_TFTP_READ_FILE, + (VOID *)(UINTN)*Image, + FALSE, + &TftpBufferSize, + NULL, + &ServerIp, + (UINT8*)AsciiPathName, + NULL, + FALSE + ); + if (EFI_ERROR (Status)) { + gBS->FreePages (*Image, EFI_SIZE_TO_PAGES (TftpBufferSize)); + } else { + *ImageSize = (UINTN)TftpBufferSize; + } } EXIT: diff --git a/ArmPkg/Library/BdsLib/BdsLib.inf b/ArmPkg/Library/BdsLib/BdsLib.inf index 30746f69a..6158fba59 100644 --- a/ArmPkg/Library/BdsLib/BdsLib.inf +++ b/ArmPkg/Library/BdsLib/BdsLib.inf @@ -1,6 +1,6 @@ #/* @file # -# Copyright (c) 2011-2013, ARM Limited. All rights reserved. +# Copyright (c) 2011-2014, ARM Limited. All rights reserved. # # This program and the accompanying materials # are licensed and made available under the terms and conditions of the BSD License @@ -86,6 +86,8 @@ gArmTokenSpaceGuid.PcdArmLinuxFdtAlignment gArmTokenSpaceGuid.PcdArmLinuxKernelMaxOffset + gArmTokenSpaceGuid.PcdMaxTftpFileSize + [FixedPcd.ARM] gArmTokenSpaceGuid.PcdArmLinuxAtagMaxOffset -- cgit v1.2.3