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 <olivier.martin@arm.com>



git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15539 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
Olivier Martin 2014-05-19 16:41:25 +00:00 committed by oliviermartin
parent 6b5f577faf
commit d8f36fb568
3 changed files with 75 additions and 29 deletions

View File

@ -133,6 +133,8 @@
gArmTokenSpaceGuid.PcdArmMachineType|0|UINT32|0x0000001E gArmTokenSpaceGuid.PcdArmMachineType|0|UINT32|0x0000001E
# The compressed Linux kernel is expected to be under 128MB from the beginning of the System Memory # The compressed Linux kernel is expected to be under 128MB from the beginning of the System Memory
gArmTokenSpaceGuid.PcdArmLinuxKernelMaxOffset|0x08000000|UINT32|0x0000001F 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 # ARM Architectural Timer

View File

@ -1,6 +1,6 @@
/** @file /** @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 * This program and the accompanying materials
* are licensed and made available under the terms and conditions of the BSD License * are licensed and made available under the terms and conditions of the BSD License
@ -817,6 +817,7 @@ BdsTftpLoadImage (
} }
UnicodeStrToAsciiStr (FilePathDevicePath->PathName, AsciiPathName); UnicodeStrToAsciiStr (FilePathDevicePath->PathName, AsciiPathName);
// Try to get the size (required the TFTP server to have "tsize" extension)
Status = Pxe->Mtftp ( Status = Pxe->Mtftp (
Pxe, Pxe,
EFI_PXE_BASE_CODE_TFTP_GET_FILE_SIZE, EFI_PXE_BASE_CODE_TFTP_GET_FILE_SIZE,
@ -829,41 +830,82 @@ BdsTftpLoadImage (
NULL, NULL,
FALSE 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) { if (Status == EFI_TFTP_ERROR) {
DEBUG((EFI_D_ERROR, "TFTP Error: Fail to get the size of the file\n")); DEBUG((EFI_D_ERROR, "TFTP Error: Fail to get the size of the file\n"));
} }
goto EXIT; goto EXIT;
} }
// Allocate a buffer to hold the whole file. //
Status = gBS->AllocatePages ( // Two cases:
Type, // 1) the file size is unknown (tsize extension not supported)
EfiBootServicesCode, // 2) tsize returned the file size
EFI_SIZE_TO_PAGES (TftpBufferSize), //
Image if (Status == EFI_PROTOCOL_ERROR) {
); for (TftpBufferSize = SIZE_8MB; TftpBufferSize <= FixedPcdGet32 (PcdMaxTftpFileSize); TftpBufferSize += SIZE_8MB) {
if (EFI_ERROR (Status)) { // Allocate a buffer to hold the whole file.
DEBUG ((EFI_D_ERROR, "Failed to allocate space for kernel image: %r\n", Status)); Status = gBS->AllocatePages (
goto EXIT; 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 ( Status = Pxe->Mtftp (
Pxe, Pxe,
EFI_PXE_BASE_CODE_TFTP_READ_FILE, EFI_PXE_BASE_CODE_TFTP_READ_FILE,
(VOID *)(UINTN)*Image, (VOID *)(UINTN)*Image,
FALSE, FALSE,
&TftpBufferSize, &TftpBufferSize,
NULL, NULL,
&ServerIp, &ServerIp,
(UINT8*)AsciiPathName, (UINT8*)AsciiPathName,
NULL, NULL,
FALSE FALSE
); );
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
gBS->FreePages (*Image, EFI_SIZE_TO_PAGES (TftpBufferSize)); gBS->FreePages (*Image, EFI_SIZE_TO_PAGES (TftpBufferSize));
} else {
*ImageSize = (UINTN)TftpBufferSize;
break;
}
}
} else { } 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: EXIT:

View File

@ -1,6 +1,6 @@
#/* @file #/* @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 # This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License # are licensed and made available under the terms and conditions of the BSD License
@ -86,6 +86,8 @@
gArmTokenSpaceGuid.PcdArmLinuxFdtAlignment gArmTokenSpaceGuid.PcdArmLinuxFdtAlignment
gArmTokenSpaceGuid.PcdArmLinuxKernelMaxOffset gArmTokenSpaceGuid.PcdArmLinuxKernelMaxOffset
gArmTokenSpaceGuid.PcdMaxTftpFileSize
[FixedPcd.ARM] [FixedPcd.ARM]
gArmTokenSpaceGuid.PcdArmLinuxAtagMaxOffset gArmTokenSpaceGuid.PcdArmLinuxAtagMaxOffset