X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=EmbeddedPkg%2FEbl%2FEfiDevice.c;h=ec9c331b70047bad00a60105eab2926eaf3a03ec;hp=2f9a6067267cc4e950000d17ac53bd1f2444f589;hb=50c6a4d2d4d7ede07143c0cde9505938e5d43a5b;hpb=884366cf56a53f3e54c19790e60c9eb788706e1c diff --git a/EmbeddedPkg/Ebl/EfiDevice.c b/EmbeddedPkg/Ebl/EfiDevice.c index 2f9a606726..ec9c331b70 100644 --- a/EmbeddedPkg/Ebl/EfiDevice.c +++ b/EmbeddedPkg/Ebl/EfiDevice.c @@ -3,6 +3,7 @@ Copyright (c) 2007, Intel Corporation. All rights reserved.
Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
+ (C) Copyright 2015 Hewlett Packard Enterprise Development LP
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License @@ -157,23 +158,23 @@ EblPrintLoadFileInfo ( if (File->DevicePath != NULL) { // Try to print out the MAC address - for (DevicePathNode = File->DevicePath; - !IsDevicePathEnd (DevicePathNode); + for (DevicePathNode = File->DevicePath; + !IsDevicePathEnd (DevicePathNode); DevicePathNode = NextDevicePathNode (DevicePathNode)) { - + if ((DevicePathType (DevicePathNode) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (DevicePathNode) == MSG_MAC_ADDR_DP)) { MacAddr = (MAC_ADDR_DEVICE_PATH *)DevicePathNode; - + HwAddressSize = sizeof (EFI_MAC_ADDRESS); if (MacAddr->IfType == 0x01 || MacAddr->IfType == 0x00) { HwAddressSize = 6; } - + AsciiPrint ("MAC "); for (Index = 0; Index < HwAddressSize; Index++) { AsciiPrint ("%02x", MacAddr->MacAddress.Addr[Index] & 0xff); } - } + } } } @@ -185,7 +186,7 @@ EblPrintLoadFileInfo ( /** - Dump information about devices in the system. + Dump information about devices in the system. fv: PI Firmware Volume fs: EFI Simple File System @@ -195,13 +196,14 @@ EblPrintLoadFileInfo ( Argv[0] - "device" @param Argc Number of command arguments in Argv - @param Argv Array of strings that represent the parsed command line. - Argv[0] is the comamnd name + @param Argv Array of strings that represent the parsed command line. + Argv[0] is the command name @return EFI_SUCCESS **/ EFI_STATUS +EFIAPI EblDeviceCmd ( IN UINTN Argc, IN CHAR8 **Argv @@ -249,7 +251,7 @@ EblDeviceCmd ( } } } - + Max = EfiGetDeviceCounts (EfiOpenLoadFile); if (Max != 0) { AsciiPrint ("LoadFile Devices: (usually network)\n"); @@ -266,7 +268,7 @@ EblDeviceCmd ( /** - Start an EFI image (PE32+ with EFI defined entry point). + Start an EFI image (PE32+ with EFI defined entry point). Argv[0] - "start" Argv[1] - device name and path @@ -278,13 +280,14 @@ EblDeviceCmd ( start LoadFile0: ; load an FV via a PXE boot @param Argc Number of command arguments in Argv - @param Argv Array of strings that represent the parsed command line. - Argv[0] is the comamnd name + @param Argv Array of strings that represent the parsed command line. + Argv[0] is the command name @return EFI_SUCCESS **/ EFI_STATUS +EFIAPI EblStartCmd ( IN UINTN Argc, IN CHAR8 **Argv @@ -308,7 +311,7 @@ EblStartCmd ( File = EfiOpen (Argv[1], EFI_FILE_MODE_READ, 0); if (File == NULL) { - return EFI_INVALID_PARAMETER; + return EFI_INVALID_PARAMETER; } DevicePath = File->DevicePath; @@ -328,7 +331,7 @@ EblStartCmd ( FreePool (Buffer); } - + EfiClose (File); if (!EFI_ERROR (Status)) { @@ -337,7 +340,7 @@ EblStartCmd ( // We don't pass Argv[0] to the EFI Application (it's name) just the args Status = gBS->HandleProtocol (ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **)&ImageInfo); ASSERT_EFI_ERROR (Status); - + ImageInfo->LoadOptionsSize = (UINT32)AsciiStrSize (Argv[2]); ImageInfo->LoadOptions = AllocatePool (ImageInfo->LoadOptionsSize); AsciiStrCpy (ImageInfo->LoadOptions, Argv[2]); @@ -353,8 +356,8 @@ EblStartCmd ( /** Load a Firmware Volume (FV) into memory from a device. This causes drivers in - the FV to be dispatched if the dependancies of the drivers are met. - + the FV to be dispatched if the dependencies of the drivers are met. + Argv[0] - "loadfv" Argv[1] - device name and path @@ -363,13 +366,14 @@ EblStartCmd ( loadfv LoadFile0: ; load an FV via a PXE boot @param Argc Number of command arguments in Argv - @param Argv Array of strings that represent the parsed command line. - Argv[0] is the comamnd name + @param Argv Array of strings that represent the parsed command line. + Argv[0] is the command name @return EFI_SUCCESS **/ EFI_STATUS +EFIAPI EblLoadFvCmd ( IN UINTN Argc, IN CHAR8 **Argv @@ -388,7 +392,7 @@ EblLoadFvCmd ( File = EfiOpen (Argv[1], EFI_FILE_MODE_READ, 0); if (File == NULL) { - return EFI_INVALID_PARAMETER; + return EFI_INVALID_PARAMETER; } if (File->Type == EfiOpenMemoryBuffer) { @@ -401,29 +405,32 @@ EblLoadFvCmd ( if (EFI_ERROR (Status)) { return Status; } - + Status = gDS->ProcessFirmwareVolume (FvStart, FvSize, &FvHandle); - FreePool (FvStart); + if (EFI_ERROR (Status)) { + FreePool (FvStart); + } } return Status; } /** - Perform an EFI connect to connect devices that follow the EFI driver model. + Perform an EFI connect to connect devices that follow the EFI driver model. If it is a PI system also call the dispatcher in case a new FV was made - availible by one of the connect EFI drivers (this is not a common case). - + available by one of the connect EFI drivers (this is not a common case). + Argv[0] - "connect" @param Argc Number of command arguments in Argv - @param Argv Array of strings that represent the parsed command line. - Argv[0] is the comamnd name + @param Argv Array of strings that represent the parsed command line. + Argv[0] is the command name @return EFI_SUCCESS **/ EFI_STATUS +EFIAPI EblConnectCmd ( IN UINTN Argc, IN CHAR8 **Argv @@ -449,11 +456,11 @@ EblConnectCmd ( if (EFI_ERROR (Status)) { return Status; } - + for (Index = 0; Index < HandleCount; Index++) { gBS->DisconnectController (HandleBuffer[Index], NULL, NULL); } - + // // Given we disconnect our console we should go and do a connect now // @@ -535,17 +542,18 @@ CHAR8 *gMemMapType[] = { /** Dump out the EFI memory map - + Argv[0] - "memmap" @param Argc Number of command arguments in Argv - @param Argv Array of strings that represent the parsed command line. - Argv[0] is the comamnd name + @param Argv Array of strings that represent the parsed command line. + Argv[0] is the command name @return EFI_SUCCESS **/ EFI_STATUS +EFIAPI EblMemMapCmd ( IN UINTN Argc, IN CHAR8 **Argv @@ -567,7 +575,7 @@ EblMemMapCmd ( ZeroMem (PageCount, sizeof (PageCount)); AsciiPrint ("EFI Memory Map\n"); - + // First call is to figure out how big the buffer needs to be MemMapSize = 0; MemMap = NULL; @@ -591,7 +599,7 @@ EblMemMapCmd ( MemMap = NEXT_MEMORY_DESCRIPTOR (MemMap, DescriptorSize); } } - + for (Index = 0, TotalMemory = 0; Index < EfiMaxMemoryType; Index++) { if (PageCount[Index] != 0) { AsciiPrint ("\n %a %,7ld Pages (%,14ld)", gMemMapType[Index], PageCount[Index], LShiftU64 (PageCount[Index], 12)); @@ -626,35 +634,36 @@ EblMemMapCmd ( /** - Load a file into memory and optionally jump to it. A load addres can be + Load a file into memory and optionally jump to it. A load address can be specified or automatically allocated. A quoted command line can optionally - be passed into the image. + be passed into the image. Argv[0] - "go" Argv[1] - Device Name:path for the file to load Argv[2] - Address to load to or '*' if the load address will be allocated Argv[3] - Optional Entry point to the image. Image will be called if present - Argv[4] - "" string that will be passed as Argc & Argv to EntryPoint. Needs + Argv[4] - "" string that will be passed as Argc & Argv to EntryPoint. Needs to include the command name - go fv1:\EblCmdX 0x10000 0x10010 "EblCmdX Arg2 Arg3 Arg4"; - load EblCmdX - from FV1 to location 0x10000 and call the entry point at 0x10010 passing + go fv1:\EblCmdX 0x10000 0x10010 "EblCmdX Arg2 Arg3 Arg4"; - load EblCmdX + from FV1 to location 0x10000 and call the entry point at 0x10010 passing in "EblCmdX Arg2 Arg3 Arg4" as the arguments. - go fv0:\EblCmdX * 0x10 "EblCmdX Arg2 Arg3 Arg4"; - load EblCmdX from FS0 - to location allocated by this comamnd and call the entry point at offset 0x10 + go fv0:\EblCmdX * 0x10 "EblCmdX Arg2 Arg3 Arg4"; - load EblCmdX from FS0 + to location allocated by this command and call the entry point at offset 0x10 passing in "EblCmdX Arg2 Arg3 Arg4" as the arguments. go fv1:\EblCmdX 0x10000; Load EblCmdX to address 0x10000 and return @param Argc Number of command arguments in Argv - @param Argv Array of strings that represent the parsed command line. - Argv[0] is the comamnd name + @param Argv Array of strings that represent the parsed command line. + Argv[0] is the command name @return EFI_SUCCESS **/ EFI_STATUS +EFIAPI EblGoCmd ( IN UINTN Argc, IN CHAR8 **Argv @@ -667,7 +676,7 @@ EblGoCmd ( EBL_COMMMAND EntryPoint; UINTN EntryPointArgc; CHAR8 *EntryPointArgv[MAX_ARGS]; - + if (Argc <= 2) { // device name and laod address are required @@ -684,8 +693,8 @@ EblGoCmd ( if (Argv[2][0] == '*') { // * Means allocate the buffer Status = EfiReadAllocatePool (File, &Address, &Size); - - // EntryPoint is relatvie to the start of the image + + // EntryPoint is relative to the start of the image EntryPoint = (EBL_COMMMAND)((UINTN)EntryPoint + (UINTN)Address); } else { @@ -707,7 +716,7 @@ EblGoCmd ( EntryPointArgc = 1; EntryPointArgv[0] = File->FileName; } - + Status = EntryPoint (EntryPointArgc, EntryPointArgv); } } @@ -719,6 +728,7 @@ EblGoCmd ( #define FILE_COPY_CHUNK 0x20000 EFI_STATUS +EFIAPI EblFileCopyCmd ( IN UINTN Argc, IN CHAR8 **Argv @@ -730,19 +740,64 @@ EblFileCopyCmd ( VOID *Buffer = NULL; UINTN Size; UINTN Offset; - UINTN Chunk = FILE_COPY_CHUNK; + UINTN Chunk = FILE_COPY_CHUNK; + UINTN FileNameLen; + CHAR8* DestFileName; + CHAR8* SrcFileName; + CHAR8* SrcPtr; if (Argc < 3) { return EFI_INVALID_PARAMETER; } - + + DestFileName = Argv[2]; + FileNameLen = AsciiStrLen (DestFileName); + + // Check if the destination file name looks like a directory + if ((DestFileName[FileNameLen-1] == '\\') || (DestFileName[FileNameLen-1] == ':')) { + // Set the pointer after the source drive (eg: after fs1:) + SrcPtr = AsciiStrStr (Argv[1], ":"); + if (SrcPtr == NULL) { + SrcPtr = Argv[1]; + } else { + SrcPtr++; + if (*SrcPtr == '\\') { + SrcPtr++; + } + } + + if (*SrcPtr == '\0') { + AsciiPrint("Source file incorrect.\n"); + } + + // Skip the Source Directories + while (1) { + SrcFileName = SrcPtr; + SrcPtr = AsciiStrStr (SrcPtr,"\\"); + if (SrcPtr != NULL) { + SrcPtr++; + } else { + break; + } + } + + if (*SrcFileName == '\0') { + AsciiPrint("Source file incorrect (Error 2).\n"); + } + + // Construct the destination filepath + DestFileName = (CHAR8*)AllocatePool (FileNameLen + AsciiStrLen (SrcFileName) + 1); + AsciiStrCpy (DestFileName, Argv[2]); + AsciiStrCat (DestFileName, SrcFileName); + } + Source = EfiOpen(Argv[1], EFI_FILE_MODE_READ, 0); if (Source == NULL) { AsciiPrint("Source file open error.\n"); return EFI_NOT_FOUND; } - - Destination = EfiOpen(Argv[2], EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE, 0); + + Destination = EfiOpen(DestFileName, EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE, 0); if (Destination == NULL) { AsciiPrint("Destination file open error.\n"); return EFI_NOT_FOUND; @@ -752,12 +807,12 @@ EblFileCopyCmd ( if (Buffer == NULL) { goto Exit; } - + Size = EfiTell(Source, NULL); for (Offset = 0; Offset + FILE_COPY_CHUNK <= Size; Offset += Chunk) { Chunk = FILE_COPY_CHUNK; - + Status = EfiRead(Source, Buffer, &Chunk); if (EFI_ERROR(Status)) { AsciiPrint("Read file error %r\n", Status); @@ -768,13 +823,13 @@ EblFileCopyCmd ( if (EFI_ERROR(Status)) { AsciiPrint("Write file error %r\n", Status); goto Exit; - } + } } - + // Any left over? if (Offset < Size) { Chunk = Size - Offset; - + Status = EfiRead(Source, Buffer, &Chunk); if (EFI_ERROR(Status)) { AsciiPrint("Read file error %r\n", Status); @@ -785,7 +840,7 @@ EblFileCopyCmd ( if (EFI_ERROR(Status)) { AsciiPrint("Write file error %r\n", Status); goto Exit; - } + } } @@ -801,16 +856,22 @@ Exit: if (EFI_ERROR(Status)) { AsciiPrint("Destination close error %r\n", Status); } + + // Case when we have concated the filename to the destination directory + if (DestFileName != Argv[2]) { + FreePool (DestFileName); + } } - + if (Buffer != NULL) { FreePool(Buffer); } - + return Status; } EFI_STATUS +EFIAPI EblFileDiffCmd ( IN UINTN Argc, IN CHAR8 **Argv @@ -825,17 +886,17 @@ EblFileDiffCmd ( UINTN Size2; UINTN Offset; UINTN Chunk = FILE_COPY_CHUNK; - + if (Argc != 3) { return EFI_INVALID_PARAMETER; } - + File1 = EfiOpen(Argv[1], EFI_FILE_MODE_READ, 0); if (File1 == NULL) { AsciiPrint("File 1 open error.\n"); return EFI_NOT_FOUND; } - + File2 = EfiOpen(Argv[2], EFI_FILE_MODE_READ, 0); if (File2 == NULL) { AsciiPrint("File 2 open error.\n"); @@ -854,15 +915,15 @@ EblFileDiffCmd ( if (Buffer1 == NULL) { goto Exit; } - + Buffer2 = AllocatePool(FILE_COPY_CHUNK); if (Buffer2 == NULL) { goto Exit; - } + } for (Offset = 0; Offset + FILE_COPY_CHUNK <= Size1; Offset += Chunk) { Chunk = FILE_COPY_CHUNK; - + Status = EfiRead(File1, Buffer1, &Chunk); if (EFI_ERROR(Status)) { AsciiPrint("File 1 read error\n"); @@ -874,17 +935,17 @@ EblFileDiffCmd ( AsciiPrint("File 2 read error\n"); goto Exit; } - + if (CompareMem(Buffer1, Buffer2, Chunk) != 0) { AsciiPrint("Files differ.\n"); goto Exit; }; } - + // Any left over? if (Offset < Size1) { Chunk = Size1 - Offset; - + Status = EfiRead(File1, Buffer1, &Chunk); if (EFI_ERROR(Status)) { AsciiPrint("File 1 read error\n"); @@ -895,9 +956,9 @@ EblFileDiffCmd ( if (EFI_ERROR(Status)) { AsciiPrint("File 2 read error\n"); goto Exit; - } + } } - + if (CompareMem(Buffer1, Buffer2, Chunk) != 0) { AsciiPrint("Files differ.\n"); } else { @@ -911,22 +972,22 @@ Exit: AsciiPrint("File 1 close error %r\n", Status); } } - + if (File2 != NULL) { Status = EfiClose(File2); if (EFI_ERROR(Status)) { AsciiPrint("File 2 close error %r\n", Status); } } - + if (Buffer1 != NULL) { FreePool(Buffer1); } - + if (Buffer2 != NULL) { FreePool(Buffer2); } - + return Status; } @@ -946,31 +1007,31 @@ GLOBAL_REMOVE_IF_UNREFERENCED const EBL_COMMAND_TABLE mCmdDeviceTemplate[] = }, { "go", - " dev:path loadaddress entrypoint args; load to given address and jump in", + " dev:path loadaddress entrypoint args; load to given address and jump in", NULL, EblGoCmd }, { "loadfv", - " devname; Load PI FV from device", + " devname; Load PI FV from device", NULL, EblLoadFvCmd }, { "start", - " path; EFI Boot Device:filepath. fs1:\\EFI\\BOOT.EFI", + " path; EFI Boot Device:filepath. fs1:\\EFI\\BOOT.EFI", NULL, EblStartCmd }, { "memmap", - "; dump EFI memory map", + "; dump EFI memory map", NULL, EblMemMapCmd }, { "cp", - " file1 file2; copy file", + " file1 file2; copy file only.", NULL, EblFileCopyCmd },