ArmPkg/BdsLib: Rework TFTP boot
Rework the downloading of an image from a TFTP server to do not depend on any "PXE specific" setting of the DHCP server. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ronald Cron <Ronald.Cron@arm.com> Reviewed-by: Olivier Martin <olivier.martin@arm.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16516 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
committed by
oliviermartin
parent
b4c222655c
commit
061568e2d5
@@ -22,6 +22,8 @@
|
||||
#include <Protocol/PxeBaseCode.h>
|
||||
#include <Protocol/SimpleFileSystem.h>
|
||||
#include <Protocol/SimpleNetwork.h>
|
||||
#include <Protocol/Dhcp4.h>
|
||||
#include <Protocol/Mtftp4.h>
|
||||
|
||||
#include <Guid/FileSystemInfo.h>
|
||||
|
||||
@@ -866,49 +868,96 @@ BdsLoadOptionPxeIsSupported (
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Add to the list of boot devices the devices allowing a TFTP boot
|
||||
|
||||
@param[in] BdsLoadOptionList List of devices to boot from
|
||||
|
||||
@retval EFI_SUCCESS Update completed
|
||||
@retval EFI_OUT_OF_RESOURCES Fail to perform the update due to lack of resource
|
||||
**/
|
||||
EFI_STATUS
|
||||
BdsLoadOptionTftpList (
|
||||
IN OUT LIST_ENTRY* BdsLoadOptionList
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINTN HandleCount;
|
||||
EFI_HANDLE *HandleBuffer;
|
||||
UINTN Index;
|
||||
BDS_SUPPORTED_DEVICE *SupportedDevice;
|
||||
EFI_DEVICE_PATH_PROTOCOL* DevicePathProtocol;
|
||||
EFI_SIMPLE_NETWORK_PROTOCOL* SimpleNet;
|
||||
CHAR16 DeviceDescription[BOOT_DEVICE_DESCRIPTION_MAX];
|
||||
EFI_MAC_ADDRESS *Mac;
|
||||
EFI_STATUS Status;
|
||||
UINTN HandleCount;
|
||||
EFI_HANDLE *HandleBuffer;
|
||||
EFI_HANDLE Handle;
|
||||
UINTN Index;
|
||||
EFI_DEVICE_PATH_PROTOCOL *DevicePathProtocol;
|
||||
VOID *Interface;
|
||||
EFI_SIMPLE_NETWORK_PROTOCOL *SimpleNetworkProtocol;
|
||||
BDS_SUPPORTED_DEVICE *SupportedDevice;
|
||||
EFI_MAC_ADDRESS *Mac;
|
||||
|
||||
// List all the PXE Protocols
|
||||
Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiPxeBaseCodeProtocolGuid, NULL, &HandleCount, &HandleBuffer);
|
||||
//
|
||||
// List all the handles on which the Simple Network Protocol is installed.
|
||||
//
|
||||
Status = gBS->LocateHandleBuffer (
|
||||
ByProtocol,
|
||||
&gEfiSimpleNetworkProtocolGuid,
|
||||
NULL,
|
||||
&HandleCount,
|
||||
&HandleBuffer
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
for (Index = 0; Index < HandleCount; Index++) {
|
||||
// We only select the handle WITH a Device Path AND the PXE Protocol AND the TFTP Protocol (the TFTP protocol is required to start PXE)
|
||||
Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID **)&DevicePathProtocol);
|
||||
if (!EFI_ERROR(Status)) {
|
||||
// Allocate BDS Supported Device structure
|
||||
SupportedDevice = (BDS_SUPPORTED_DEVICE*)AllocatePool(sizeof(BDS_SUPPORTED_DEVICE));
|
||||
|
||||
Status = gBS->LocateProtocol (&gEfiSimpleNetworkProtocolGuid, NULL, (VOID **)&SimpleNet);
|
||||
if (!EFI_ERROR(Status)) {
|
||||
Mac = &SimpleNet->Mode->CurrentAddress;
|
||||
UnicodeSPrint (DeviceDescription,BOOT_DEVICE_DESCRIPTION_MAX,L"MAC Address: %02x:%02x:%02x:%02x:%02x:%02x", Mac->Addr[0], Mac->Addr[1], Mac->Addr[2], Mac->Addr[3], Mac->Addr[4], Mac->Addr[5]);
|
||||
} else {
|
||||
Status = GenerateDeviceDescriptionName (HandleBuffer[Index], DeviceDescription);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
}
|
||||
UnicodeSPrint (SupportedDevice->Description,BOOT_DEVICE_DESCRIPTION_MAX,L"TFTP on %s",DeviceDescription);
|
||||
|
||||
SupportedDevice->DevicePathProtocol = DevicePathProtocol;
|
||||
SupportedDevice->Support = &BdsLoadOptionSupportList[BDS_DEVICE_TFTP];
|
||||
|
||||
InsertTailList (BdsLoadOptionList,&SupportedDevice->Link);
|
||||
Handle = HandleBuffer[Index];
|
||||
//
|
||||
// We select the handles that support :
|
||||
// . the Device Path Protocol
|
||||
// . the MTFTP4 Protocol
|
||||
//
|
||||
Status = gBS->HandleProtocol (
|
||||
Handle,
|
||||
&gEfiDevicePathProtocolGuid,
|
||||
(VOID **)&DevicePathProtocol
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Status = gBS->HandleProtocol (
|
||||
Handle,
|
||||
&gEfiMtftp4ServiceBindingProtocolGuid,
|
||||
&Interface
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Status = gBS->HandleProtocol (
|
||||
Handle,
|
||||
&gEfiSimpleNetworkProtocolGuid,
|
||||
(VOID **)&SimpleNetworkProtocol
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Allocate BDS Supported Device structure
|
||||
SupportedDevice = (BDS_SUPPORTED_DEVICE*)AllocatePool (sizeof (BDS_SUPPORTED_DEVICE));
|
||||
if (SupportedDevice == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Mac = &SimpleNetworkProtocol->Mode->CurrentAddress;
|
||||
UnicodeSPrint (
|
||||
SupportedDevice->Description,
|
||||
BOOT_DEVICE_DESCRIPTION_MAX,
|
||||
L"TFTP on MAC Address: %02x:%02x:%02x:%02x:%02x:%02x",
|
||||
Mac->Addr[0], Mac->Addr[1], Mac->Addr[2], Mac->Addr[3], Mac->Addr[4], Mac->Addr[5]
|
||||
);
|
||||
|
||||
SupportedDevice->DevicePathProtocol = DevicePathProtocol;
|
||||
SupportedDevice->Support = &BdsLoadOptionSupportList[BDS_DEVICE_TFTP];
|
||||
|
||||
InsertTailList (BdsLoadOptionList, &SupportedDevice->Link);
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
@@ -920,38 +969,50 @@ BdsLoadOptionTftpCreateDevicePath (
|
||||
OUT EFI_DEVICE_PATH_PROTOCOL **DevicePathNodes
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
BOOLEAN IsDHCP;
|
||||
EFI_IP_ADDRESS LocalIp;
|
||||
EFI_IP_ADDRESS RemoteIp;
|
||||
IPv4_DEVICE_PATH* IPv4DevicePathNode;
|
||||
FILEPATH_DEVICE_PATH* FilePathDevicePath;
|
||||
CHAR16 BootFilePath[BOOT_DEVICE_FILEPATH_MAX];
|
||||
UINTN BootFilePathSize;
|
||||
EFI_STATUS Status;
|
||||
BOOLEAN IsDHCP;
|
||||
EFI_IP_ADDRESS LocalIp;
|
||||
EFI_IP_ADDRESS SubnetMask;
|
||||
EFI_IP_ADDRESS GatewayIp;
|
||||
EFI_IP_ADDRESS RemoteIp;
|
||||
IPv4_DEVICE_PATH *IPv4DevicePathNode;
|
||||
FILEPATH_DEVICE_PATH *FilePathDevicePath;
|
||||
CHAR16 BootFilePath[BOOT_DEVICE_FILEPATH_MAX];
|
||||
UINTN BootFilePathSize;
|
||||
|
||||
Print(L"Get the IP address from DHCP: ");
|
||||
Print (L"Get the IP address from DHCP: ");
|
||||
Status = GetHIInputBoolean (&IsDHCP);
|
||||
if (EFI_ERROR(Status)) {
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_ABORTED;
|
||||
}
|
||||
|
||||
if (!IsDHCP) {
|
||||
Print(L"Get the static IP address: ");
|
||||
Print (L"Local static IP address: ");
|
||||
Status = GetHIInputIP (&LocalIp);
|
||||
if (EFI_ERROR(Status)) {
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_ABORTED;
|
||||
}
|
||||
Print (L"Get the network mask: ");
|
||||
Status = GetHIInputIP (&SubnetMask);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_ABORTED;
|
||||
}
|
||||
Print (L"Get the gateway IP address: ");
|
||||
Status = GetHIInputIP (&GatewayIp);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_ABORTED;
|
||||
}
|
||||
}
|
||||
|
||||
Print(L"Get the TFTP server IP address: ");
|
||||
Print (L"Get the TFTP server IP address: ");
|
||||
Status = GetHIInputIP (&RemoteIp);
|
||||
if (EFI_ERROR(Status)) {
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_ABORTED;
|
||||
}
|
||||
|
||||
Print(L"File path of the %s : ", FileName);
|
||||
Print (L"File path of the %s : ", FileName);
|
||||
Status = GetHIInputStr (BootFilePath, BOOT_DEVICE_FILEPATH_MAX);
|
||||
if (EFI_ERROR(Status)) {
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_ABORTED;
|
||||
}
|
||||
|
||||
@@ -967,7 +1028,13 @@ BdsLoadOptionTftpCreateDevicePath (
|
||||
IPv4DevicePathNode->Header.Type = MESSAGING_DEVICE_PATH;
|
||||
IPv4DevicePathNode->Header.SubType = MSG_IPv4_DP;
|
||||
SetDevicePathNodeLength (&IPv4DevicePathNode->Header, sizeof(IPv4_DEVICE_PATH));
|
||||
CopyMem (&IPv4DevicePathNode->LocalIpAddress, &LocalIp.v4, sizeof (EFI_IPv4_ADDRESS));
|
||||
|
||||
if (!IsDHCP) {
|
||||
CopyMem (&IPv4DevicePathNode->LocalIpAddress, &LocalIp.v4, sizeof (EFI_IPv4_ADDRESS));
|
||||
CopyMem (&IPv4DevicePathNode->SubnetMask, &SubnetMask.v4, sizeof (EFI_IPv4_ADDRESS));
|
||||
CopyMem (&IPv4DevicePathNode->GatewayIpAddress, &GatewayIp.v4, sizeof (EFI_IPv4_ADDRESS));
|
||||
}
|
||||
|
||||
CopyMem (&IPv4DevicePathNode->RemoteIpAddress, &RemoteIp.v4, sizeof (EFI_IPv4_ADDRESS));
|
||||
IPv4DevicePathNode->LocalPort = 0;
|
||||
IPv4DevicePathNode->RemotePort = 0;
|
||||
@@ -1021,7 +1088,11 @@ BdsLoadOptionTftpUpdateDevicePath (
|
||||
IPv4_DEVICE_PATH Ipv4Node;
|
||||
BOOLEAN IsDHCP;
|
||||
EFI_IP_ADDRESS OldIp;
|
||||
EFI_IP_ADDRESS OldSubnetMask;
|
||||
EFI_IP_ADDRESS OldGatewayIp;
|
||||
EFI_IP_ADDRESS LocalIp;
|
||||
EFI_IP_ADDRESS SubnetMask;
|
||||
EFI_IP_ADDRESS GatewayIp;
|
||||
EFI_IP_ADDRESS RemoteIp;
|
||||
UINT8 *FileNodePtr;
|
||||
CHAR16 BootFilePath[BOOT_DEVICE_FILEPATH_MAX];
|
||||
@@ -1074,9 +1145,7 @@ BdsLoadOptionTftpUpdateDevicePath (
|
||||
if (!IsDHCP) {
|
||||
Print (L"Local static IP address: ");
|
||||
if (Ipv4Node.StaticIpAddress) {
|
||||
// Copy local IPv4 address into IPv4 or IPv6 union
|
||||
CopyMem (&OldIp.v4, &Ipv4Node.LocalIpAddress, sizeof (EFI_IPv4_ADDRESS));
|
||||
|
||||
Status = EditHIInputIP (&OldIp, &LocalIp);
|
||||
} else {
|
||||
Status = GetHIInputIP (&LocalIp);
|
||||
@@ -1084,6 +1153,28 @@ BdsLoadOptionTftpUpdateDevicePath (
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ErrorExit;
|
||||
}
|
||||
|
||||
Print (L"Get the network mask: ");
|
||||
if (Ipv4Node.StaticIpAddress) {
|
||||
CopyMem (&OldSubnetMask.v4, &Ipv4Node.SubnetMask, sizeof (EFI_IPv4_ADDRESS));
|
||||
Status = EditHIInputIP (&OldSubnetMask, &SubnetMask);
|
||||
} else {
|
||||
Status = GetHIInputIP (&SubnetMask);
|
||||
}
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ErrorExit;
|
||||
}
|
||||
|
||||
Print (L"Get the gateway IP address: ");
|
||||
if (Ipv4Node.StaticIpAddress) {
|
||||
CopyMem (&OldGatewayIp.v4, &Ipv4Node.GatewayIpAddress, sizeof (EFI_IPv4_ADDRESS));
|
||||
Status = EditHIInputIP (&OldGatewayIp, &GatewayIp);
|
||||
} else {
|
||||
Status = GetHIInputIP (&GatewayIp);
|
||||
}
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ErrorExit;
|
||||
}
|
||||
}
|
||||
|
||||
Print (L"TFTP server IP address: ");
|
||||
@@ -1126,12 +1217,18 @@ BdsLoadOptionTftpUpdateDevicePath (
|
||||
//
|
||||
// Update the IPv4 node. IPv6 case not handled yet.
|
||||
//
|
||||
if (IsDHCP == TRUE) {
|
||||
if (IsDHCP) {
|
||||
Ipv4Node.StaticIpAddress = FALSE;
|
||||
ZeroMem (&Ipv4Node.LocalIpAddress, sizeof (EFI_IPv4_ADDRESS));
|
||||
ZeroMem (&Ipv4Node.SubnetMask, sizeof (EFI_IPv4_ADDRESS));
|
||||
ZeroMem (&Ipv4Node.GatewayIpAddress, sizeof (EFI_IPv4_ADDRESS));
|
||||
} else {
|
||||
Ipv4Node.StaticIpAddress = TRUE;
|
||||
CopyMem (&Ipv4Node.LocalIpAddress, &LocalIp.v4, sizeof (EFI_IPv4_ADDRESS));
|
||||
CopyMem (&Ipv4Node.SubnetMask, &SubnetMask.v4, sizeof (EFI_IPv4_ADDRESS));
|
||||
CopyMem (&Ipv4Node.GatewayIpAddress, &GatewayIp.v4, sizeof (EFI_IPv4_ADDRESS));
|
||||
}
|
||||
CopyMem (&Ipv4Node.LocalIpAddress, &LocalIp.v4, sizeof (EFI_IPv4_ADDRESS));
|
||||
|
||||
CopyMem (&Ipv4Node.RemoteIpAddress, &RemoteIp.v4, sizeof (EFI_IPv4_ADDRESS));
|
||||
CopyMem (Ipv4NodePtr, &Ipv4Node, sizeof (IPv4_DEVICE_PATH));
|
||||
|
||||
|
Reference in New Issue
Block a user