2 EBL commands for EFI and PI Devices
4 Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
5 Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
6 (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
8 This program and the accompanying materials
9 are licensed and made available under the terms and conditions of the BSD License
10 which accompanies this distribution. The full text of the license may be found at
11 http://opensource.org/licenses/bsd-license.php
13 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
14 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
21 EFI_DXE_SERVICES
*gDS
= NULL
;
25 Print information about the File System device.
27 @param File Open File for the device
32 IN EFI_OPEN_FILE
*File
41 AsciiPrint (" %a: ", File
->DeviceName
);
42 if (File
->FsInfo
!= NULL
) {
43 for (Str
= File
->FsInfo
->VolumeLabel
; *Str
!= '\0'; Str
++) {
45 // UI makes you enter _ for space, so make the printout match that
48 AsciiPrint ("%c", *Str
);
51 if (File
->FsInfo
->ReadOnly
) {
52 AsciiPrint ("ReadOnly");
62 Print information about the FV devices.
64 @param File Open File for the device
69 IN EFI_OPEN_FILE
*File
76 AsciiPrint (" %a: 0x%08lx - 0x%08lx : 0x%08x\n", File
->DeviceName
, File
->FvStart
, File
->FvStart
+ File
->FvSize
- 1, File
->FvSize
);
82 Print information about the Blk IO devices.
83 If the device supports PXE dump out extra information
85 @param File Open File for the device
90 IN EFI_OPEN_FILE
*File
96 EFI_OPEN_FILE
*FsFile
;
102 AsciiPrint (" %a: ", File
->DeviceName
);
104 // print out name of file system, if any, on this block device
105 Max
= EfiGetDeviceCounts (EfiOpenFileSystem
);
107 for (Index
= 0; Index
< Max
; Index
++) {
108 FsFile
= EfiDeviceOpenByType (EfiOpenFileSystem
, Index
);
109 if (FsFile
!= NULL
) {
110 if (FsFile
->EfiHandle
== File
->EfiHandle
) {
111 AsciiPrint ("fs%d: ", Index
);
120 // Print out useful Block IO media properties
121 if (File
->FsBlockIoMedia
->RemovableMedia
) {
122 AsciiPrint ("Removable ");
124 if (!File
->FsBlockIoMedia
->MediaPresent
) {
125 AsciiPrint ("No Media\n");
127 if (File
->FsBlockIoMedia
->LogicalPartition
) {
128 AsciiPrint ("Partition ");
130 DeviceSize
= MultU64x32 (File
->FsBlockIoMedia
->LastBlock
+ 1, File
->FsBlockIoMedia
->BlockSize
);
131 AsciiPrint ("Size = 0x%lX\n", DeviceSize
);
137 Print information about the Load File devices.
138 If the device supports PXE dump out extra information
140 @param File Open File for the device
144 EblPrintLoadFileInfo (
145 IN EFI_OPEN_FILE
*File
148 EFI_DEVICE_PATH_PROTOCOL
*DevicePathNode
;
149 MAC_ADDR_DEVICE_PATH
*MacAddr
;
157 AsciiPrint (" %a: %a ", File
->DeviceName
, EblLoadFileBootTypeString (File
->EfiHandle
));
159 if (File
->DevicePath
!= NULL
) {
160 // Try to print out the MAC address
161 for (DevicePathNode
= File
->DevicePath
;
162 !IsDevicePathEnd (DevicePathNode
);
163 DevicePathNode
= NextDevicePathNode (DevicePathNode
)) {
165 if ((DevicePathType (DevicePathNode
) == MESSAGING_DEVICE_PATH
) && (DevicePathSubType (DevicePathNode
) == MSG_MAC_ADDR_DP
)) {
166 MacAddr
= (MAC_ADDR_DEVICE_PATH
*)DevicePathNode
;
168 HwAddressSize
= sizeof (EFI_MAC_ADDRESS
);
169 if (MacAddr
->IfType
== 0x01 || MacAddr
->IfType
== 0x00) {
174 for (Index
= 0; Index
< HwAddressSize
; Index
++) {
175 AsciiPrint ("%02x", MacAddr
->MacAddress
.Addr
[Index
] & 0xff);
189 Dump information about devices in the system.
191 fv: PI Firmware Volume
192 fs: EFI Simple File System
194 LoadFile: EFI Load File Protocol (commonly PXE network boot)
198 @param Argc Number of command arguments in Argv
199 @param Argv Array of strings that represent the parsed command line.
200 Argv[0] is the command name
218 // Need to call here to make sure Device Counts are valid
219 EblUpdateDeviceLists ();
221 // Now we can print out the info...
222 Max
= EfiGetDeviceCounts (EfiOpenFirmwareVolume
);
224 AsciiPrint ("Firmware Volume Devices:\n");
225 for (Index
= 0; Index
< Max
; Index
++) {
226 EblPrintFvbInfo (EfiDeviceOpenByType (EfiOpenFirmwareVolume
, Index
));
227 if (EblAnyKeyToContinueQtoQuit (&CurrentRow
, TRUE
)) {
233 Max
= EfiGetDeviceCounts (EfiOpenFileSystem
);
235 AsciiPrint ("File System Devices:\n");
236 for (Index
= 0; Index
< Max
; Index
++) {
237 EblPrintFsInfo (EfiDeviceOpenByType (EfiOpenFileSystem
, Index
));
238 if (EblAnyKeyToContinueQtoQuit (&CurrentRow
, TRUE
)) {
244 Max
= EfiGetDeviceCounts (EfiOpenBlockIo
);
246 AsciiPrint ("Block IO Devices:\n");
247 for (Index
= 0; Index
< Max
; Index
++) {
248 EblPrintBlkIoInfo (EfiDeviceOpenByType (EfiOpenBlockIo
, Index
));
249 if (EblAnyKeyToContinueQtoQuit (&CurrentRow
, TRUE
)) {
255 Max
= EfiGetDeviceCounts (EfiOpenLoadFile
);
257 AsciiPrint ("LoadFile Devices: (usually network)\n");
258 for (Index
= 0; Index
< Max
; Index
++) {
259 EblPrintLoadFileInfo (EfiDeviceOpenByType (EfiOpenLoadFile
, Index
));
260 if (EblAnyKeyToContinueQtoQuit (&CurrentRow
, TRUE
)) {
271 Start an EFI image (PE32+ with EFI defined entry point).
274 Argv[1] - device name and path
275 Argv[2] - "" string to pass into image being started
277 start fs1:\Temp\Fv.Fv "arg to pass" ; load an FV from the disk and pass the
278 ; ascii string arg to pass to the image
279 start fv0:\FV ; load an FV from an FV (not common)
280 start LoadFile0: ; load an FV via a PXE boot
282 @param Argc Number of command arguments in Argv
283 @param Argv Array of strings that represent the parsed command line.
284 Argv[0] is the command name
298 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
299 EFI_HANDLE ImageHandle
;
304 EFI_LOADED_IMAGE_PROTOCOL
*ImageInfo
;
309 return EFI_INVALID_PARAMETER
;
312 File
= EfiOpen (Argv
[1], EFI_FILE_MODE_READ
, 0);
314 return EFI_INVALID_PARAMETER
;
317 DevicePath
= File
->DevicePath
;
318 if (DevicePath
!= NULL
) {
319 // check for device path form: blk, fv, fs, and loadfile
320 Status
= gBS
->LoadImage (FALSE
, gImageHandle
, DevicePath
, NULL
, 0, &ImageHandle
);
322 // Check for buffer form: A0x12345678:0x1234 syntax.
323 // Means load using buffer starting at 0x12345678 of size 0x1234.
325 Status
= EfiReadAllocatePool (File
, &Buffer
, &BufferSize
);
326 if (EFI_ERROR (Status
)) {
330 Status
= gBS
->LoadImage (FALSE
, gImageHandle
, DevicePath
, Buffer
, BufferSize
, &ImageHandle
);
337 if (!EFI_ERROR (Status
)) {
339 // Argv[2] is a "" string that we pass directly to the EFI application without the ""
340 // We don't pass Argv[0] to the EFI Application (it's name) just the args
341 Status
= gBS
->HandleProtocol (ImageHandle
, &gEfiLoadedImageProtocolGuid
, (VOID
**)&ImageInfo
);
342 ASSERT_EFI_ERROR (Status
);
344 ImageInfo
->LoadOptionsSize
= (UINT32
)AsciiStrSize (Argv
[2]);
345 ImageInfo
->LoadOptions
= AllocatePool (ImageInfo
->LoadOptionsSize
);
346 AsciiStrCpyS (ImageInfo
->LoadOptions
, ImageInfo
->LoadOptionsSize
, Argv
[2]);
349 // Transfer control to the EFI image we loaded with LoadImage()
350 Status
= gBS
->StartImage (ImageHandle
, &ExitDataSize
, &ExitData
);
358 Load a Firmware Volume (FV) into memory from a device. This causes drivers in
359 the FV to be dispatched if the dependencies of the drivers are met.
362 Argv[1] - device name and path
364 loadfv fs1:\Temp\Fv.Fv ; load an FV from the disk
365 loadfv fv0:\FV ; load an FV from an FV (not common)
366 loadfv LoadFile0: ; load an FV via a PXE boot
368 @param Argc Number of command arguments in Argv
369 @param Argv Array of strings that represent the parsed command line.
370 Argv[0] is the command name
390 return EFI_INVALID_PARAMETER
;
393 File
= EfiOpen (Argv
[1], EFI_FILE_MODE_READ
, 0);
395 return EFI_INVALID_PARAMETER
;
398 if (File
->Type
== EfiOpenMemoryBuffer
) {
399 // If it is a address just use it.
400 Status
= gDS
->ProcessFirmwareVolume (File
->Buffer
, File
->Size
, &FvHandle
);
402 // If it is a file read it into memory and use it
403 Status
= EfiReadAllocatePool (File
, &FvStart
, &FvSize
);
405 if (EFI_ERROR (Status
)) {
409 Status
= gDS
->ProcessFirmwareVolume (FvStart
, FvSize
, &FvHandle
);
410 if (EFI_ERROR (Status
)) {
419 Perform an EFI connect to connect devices that follow the EFI driver model.
420 If it is a PI system also call the dispatcher in case a new FV was made
421 available by one of the connect EFI drivers (this is not a common case).
425 @param Argc Number of command arguments in Argv
426 @param Argv Array of strings that represent the parsed command line.
427 Argv[0] is the command name
441 EFI_HANDLE
*HandleBuffer
;
448 if ((*Argv
[1] == 'd') || (*Argv
[1] == 'D')) {
449 Status
= gBS
->LocateHandleBuffer (
456 if (EFI_ERROR (Status
)) {
460 for (Index
= 0; Index
< HandleCount
; Index
++) {
461 gBS
->DisconnectController (HandleBuffer
[Index
], NULL
, NULL
);
465 // Given we disconnect our console we should go and do a connect now
468 File
= EfiOpen (Argv
[1], EFI_FILE_MODE_READ
, 0);
470 AsciiPrint ("Connecting %a\n", Argv
[1]);
471 gBS
->ConnectController (File
->EfiHandle
, NULL
, NULL
, TRUE
);
480 Status
= gBS
->LocateHandleBuffer (
487 if (EFI_ERROR (Status
)) {
491 for (Index
= 0; Index
< HandleCount
; Index
++) {
492 gBS
->ConnectController (HandleBuffer
[Index
], NULL
, NULL
, TRUE
);
495 FreePool (HandleBuffer
);
498 // Check to see if it's possible to dispatch an more DXE drivers.
499 // The BdsLibConnectAllEfi () may have made new DXE drivers show up.
500 // If anything is Dispatched Status == EFI_SUCCESS and we will try
501 // the connect again.
504 Status
= EFI_NOT_FOUND
;
506 Status
= gDS
->Dispatch ();
507 if (!EFI_ERROR (Status
)) {
512 } while (!EFI_ERROR (Status
));
515 AsciiPrint ("Connected and dispatched\n");
517 AsciiPrint ("Connect\n");
525 CHAR8
*gMemMapType
[] = {
544 Dump out the EFI memory map
548 @param Argc Number of command arguments in Argv
549 @param Argv Array of strings that represent the parsed command line.
550 Argv[0] is the command name
563 EFI_MEMORY_DESCRIPTOR
*MemMap
;
564 EFI_MEMORY_DESCRIPTOR
*OrigMemMap
;
567 UINTN DescriptorSize
;
568 UINT32 DescriptorVersion
;
569 UINT64 PageCount
[EfiMaxMemoryType
];
575 ZeroMem (PageCount
, sizeof (PageCount
));
577 AsciiPrint ("EFI Memory Map\n");
579 // First call is to figure out how big the buffer needs to be
582 Status
= gBS
->GetMemoryMap (&MemMapSize
, MemMap
, &MapKey
, &DescriptorSize
, &DescriptorVersion
);
583 if (Status
== EFI_BUFFER_TOO_SMALL
) {
584 // In case the AllocatPool changes the memory map we added in some extra descriptors
585 MemMapSize
+= (DescriptorSize
* 0x100);
586 OrigMemMap
= MemMap
= AllocatePool (MemMapSize
);
587 if (OrigMemMap
!= NULL
) {
588 // 2nd time we get the data
589 Status
= gBS
->GetMemoryMap (&MemMapSize
, MemMap
, &MapKey
, &DescriptorSize
, &DescriptorVersion
);
590 if (!EFI_ERROR (Status
)) {
591 for (Index
= 0, CurrentRow
= 0; Index
< MemMapSize
/DescriptorSize
; Index
++) {
592 EntrySize
= LShiftU64 (MemMap
->NumberOfPages
, 12);
593 AsciiPrint ("\n%a %016lx - %016lx: # %08lx %016lx", gMemMapType
[MemMap
->Type
% EfiMaxMemoryType
], MemMap
->PhysicalStart
, MemMap
->PhysicalStart
+ EntrySize
-1, MemMap
->NumberOfPages
, MemMap
->Attribute
);
594 if (EblAnyKeyToContinueQtoQuit (&CurrentRow
, TRUE
)) {
598 PageCount
[MemMap
->Type
% EfiMaxMemoryType
] += MemMap
->NumberOfPages
;
599 MemMap
= NEXT_MEMORY_DESCRIPTOR (MemMap
, DescriptorSize
);
603 for (Index
= 0, TotalMemory
= 0; Index
< EfiMaxMemoryType
; Index
++) {
604 if (PageCount
[Index
] != 0) {
605 AsciiPrint ("\n %a %,7ld Pages (%,14ld)", gMemMapType
[Index
], PageCount
[Index
], LShiftU64 (PageCount
[Index
], 12));
606 if (Index
== EfiLoaderCode
||
607 Index
== EfiLoaderData
||
608 Index
== EfiBootServicesCode
||
609 Index
== EfiBootServicesData
||
610 Index
== EfiRuntimeServicesCode
||
611 Index
== EfiRuntimeServicesData
||
612 Index
== EfiConventionalMemory
||
613 Index
== EfiACPIReclaimMemory
||
614 Index
== EfiACPIMemoryNVS
||
617 // Count total memory
618 TotalMemory
+= PageCount
[Index
];
623 AsciiPrint ("\nTotal Memory: %,ld MB (%,ld bytes)\n", RShiftU64 (TotalMemory
, 8), LShiftU64 (TotalMemory
, 12));
625 FreePool (OrigMemMap
);
637 Load a file into memory and optionally jump to it. A load address can be
638 specified or automatically allocated. A quoted command line can optionally
639 be passed into the image.
642 Argv[1] - Device Name:path for the file to load
643 Argv[2] - Address to load to or '*' if the load address will be allocated
644 Argv[3] - Optional Entry point to the image. Image will be called if present
645 Argv[4] - "" string that will be passed as Argc & Argv to EntryPoint. Needs
646 to include the command name
648 go fv1:\EblCmdX 0x10000 0x10010 "EblCmdX Arg2 Arg3 Arg4"; - load EblCmdX
649 from FV1 to location 0x10000 and call the entry point at 0x10010 passing
650 in "EblCmdX Arg2 Arg3 Arg4" as the arguments.
652 go fv0:\EblCmdX * 0x10 "EblCmdX Arg2 Arg3 Arg4"; - load EblCmdX from FS0
653 to location allocated by this command and call the entry point at offset 0x10
654 passing in "EblCmdX Arg2 Arg3 Arg4" as the arguments.
656 go fv1:\EblCmdX 0x10000; Load EblCmdX to address 0x10000 and return
658 @param Argc Number of command arguments in Argv
659 @param Argv Array of strings that represent the parsed command line.
660 Argv[0] is the command name
676 EBL_COMMMAND EntryPoint
;
677 UINTN EntryPointArgc
;
678 CHAR8
*EntryPointArgv
[MAX_ARGS
];
682 // device name and laod address are required
686 File
= EfiOpen (Argv
[1], EFI_FILE_MODE_READ
, 0);
688 AsciiPrint (" %a is not a valid path\n", Argv
[1]);
692 EntryPoint
= (EBL_COMMMAND
)((Argc
> 3) ? (UINTN
)AsciiStrHexToUintn (Argv
[3]) : (UINTN
)NULL
);
693 if (Argv
[2][0] == '*') {
694 // * Means allocate the buffer
695 Status
= EfiReadAllocatePool (File
, &Address
, &Size
);
697 // EntryPoint is relative to the start of the image
698 EntryPoint
= (EBL_COMMMAND
)((UINTN
)EntryPoint
+ (UINTN
)Address
);
701 Address
= (VOID
*)AsciiStrHexToUintn (Argv
[2]);
704 // File->Size for LoadFile is lazy so we need to use the tell to figure it out
705 EfiTell (File
, NULL
);
706 Status
= EfiRead (File
, Address
, &Size
);
709 if (!EFI_ERROR (Status
)) {
710 AsciiPrint ("Loaded %,d bytes to 0x%08x\n", Size
, Address
);
714 ParseArguments (Argv
[4], &EntryPointArgc
, EntryPointArgv
);
717 EntryPointArgv
[0] = File
->FileName
;
720 Status
= EntryPoint (EntryPointArgc
, EntryPointArgv
);
728 #define FILE_COPY_CHUNK 0x20000
737 EFI_OPEN_FILE
*Source
= NULL
;
738 EFI_OPEN_FILE
*Destination
= NULL
;
739 EFI_STATUS Status
= EFI_SUCCESS
;
743 UINTN Chunk
= FILE_COPY_CHUNK
;
744 UINTN FileNameLen
, DestFileNameLen
;
750 return EFI_INVALID_PARAMETER
;
753 DestFileName
= Argv
[2];
754 FileNameLen
= AsciiStrLen (DestFileName
);
756 // Check if the destination file name looks like a directory
757 if ((DestFileName
[FileNameLen
-1] == '\\') || (DestFileName
[FileNameLen
-1] == ':')) {
758 // Set the pointer after the source drive (eg: after fs1:)
759 SrcPtr
= AsciiStrStr (Argv
[1], ":");
760 if (SrcPtr
== NULL
) {
764 if (*SrcPtr
== '\\') {
769 if (*SrcPtr
== '\0') {
770 AsciiPrint("Source file incorrect.\n");
773 // Skip the Source Directories
775 SrcFileName
= SrcPtr
;
776 SrcPtr
= AsciiStrStr (SrcPtr
,"\\");
777 if (SrcPtr
!= NULL
) {
784 if (*SrcFileName
== '\0') {
785 AsciiPrint("Source file incorrect (Error 2).\n");
788 // Construct the destination filepath
789 DestFileNameLen
= FileNameLen
+ AsciiStrLen (SrcFileName
) + 1;
790 DestFileName
= (CHAR8
*)AllocatePool (DestFileNameLen
);
791 AsciiStrCpyS (DestFileName
, DestFileNameLen
, Argv
[2]);
792 AsciiStrCatS (DestFileName
, DestFileNameLen
, SrcFileName
);
795 Source
= EfiOpen(Argv
[1], EFI_FILE_MODE_READ
, 0);
796 if (Source
== NULL
) {
797 AsciiPrint("Source file open error.\n");
798 return EFI_NOT_FOUND
;
801 Destination
= EfiOpen(DestFileName
, EFI_FILE_MODE_READ
| EFI_FILE_MODE_WRITE
| EFI_FILE_MODE_CREATE
, 0);
802 if (Destination
== NULL
) {
803 AsciiPrint("Destination file open error.\n");
804 return EFI_NOT_FOUND
;
807 Buffer
= AllocatePool(FILE_COPY_CHUNK
);
808 if (Buffer
== NULL
) {
812 Size
= EfiTell(Source
, NULL
);
814 for (Offset
= 0; Offset
+ FILE_COPY_CHUNK
<= Size
; Offset
+= Chunk
) {
815 Chunk
= FILE_COPY_CHUNK
;
817 Status
= EfiRead(Source
, Buffer
, &Chunk
);
818 if (EFI_ERROR(Status
)) {
819 AsciiPrint("Read file error %r\n", Status
);
823 Status
= EfiWrite(Destination
, Buffer
, &Chunk
);
824 if (EFI_ERROR(Status
)) {
825 AsciiPrint("Write file error %r\n", Status
);
832 Chunk
= Size
- Offset
;
834 Status
= EfiRead(Source
, Buffer
, &Chunk
);
835 if (EFI_ERROR(Status
)) {
836 AsciiPrint("Read file error %r\n", Status
);
840 Status
= EfiWrite(Destination
, Buffer
, &Chunk
);
841 if (EFI_ERROR(Status
)) {
842 AsciiPrint("Write file error %r\n", Status
);
849 if (Source
!= NULL
) {
850 Status
= EfiClose(Source
);
851 if (EFI_ERROR(Status
)) {
852 AsciiPrint("Source close error %r\n", Status
);
855 if (Destination
!= NULL
) {
856 Status
= EfiClose(Destination
);
857 if (EFI_ERROR(Status
)) {
858 AsciiPrint("Destination close error %r\n", Status
);
861 // Case when we have concated the filename to the destination directory
862 if (DestFileName
!= Argv
[2]) {
863 FreePool (DestFileName
);
867 if (Buffer
!= NULL
) {
881 EFI_OPEN_FILE
*File1
= NULL
;
882 EFI_OPEN_FILE
*File2
= NULL
;
883 EFI_STATUS Status
= EFI_SUCCESS
;
884 VOID
*Buffer1
= NULL
;
885 VOID
*Buffer2
= NULL
;
889 UINTN Chunk
= FILE_COPY_CHUNK
;
892 return EFI_INVALID_PARAMETER
;
895 File1
= EfiOpen(Argv
[1], EFI_FILE_MODE_READ
, 0);
897 AsciiPrint("File 1 open error.\n");
898 return EFI_NOT_FOUND
;
901 File2
= EfiOpen(Argv
[2], EFI_FILE_MODE_READ
, 0);
903 AsciiPrint("File 2 open error.\n");
904 return EFI_NOT_FOUND
;
907 Size1
= EfiTell(File1
, NULL
);
908 Size2
= EfiTell(File2
, NULL
);
910 if (Size1
!= Size2
) {
911 AsciiPrint("Files differ.\n");
915 Buffer1
= AllocatePool(FILE_COPY_CHUNK
);
916 if (Buffer1
== NULL
) {
920 Buffer2
= AllocatePool(FILE_COPY_CHUNK
);
921 if (Buffer2
== NULL
) {
925 for (Offset
= 0; Offset
+ FILE_COPY_CHUNK
<= Size1
; Offset
+= Chunk
) {
926 Chunk
= FILE_COPY_CHUNK
;
928 Status
= EfiRead(File1
, Buffer1
, &Chunk
);
929 if (EFI_ERROR(Status
)) {
930 AsciiPrint("File 1 read error\n");
934 Status
= EfiRead(File2
, Buffer2
, &Chunk
);
935 if (EFI_ERROR(Status
)) {
936 AsciiPrint("File 2 read error\n");
940 if (CompareMem(Buffer1
, Buffer2
, Chunk
) != 0) {
941 AsciiPrint("Files differ.\n");
947 if (Offset
< Size1
) {
948 Chunk
= Size1
- Offset
;
950 Status
= EfiRead(File1
, Buffer1
, &Chunk
);
951 if (EFI_ERROR(Status
)) {
952 AsciiPrint("File 1 read error\n");
956 Status
= EfiRead(File2
, Buffer2
, &Chunk
);
957 if (EFI_ERROR(Status
)) {
958 AsciiPrint("File 2 read error\n");
963 if (CompareMem(Buffer1
, Buffer2
, Chunk
) != 0) {
964 AsciiPrint("Files differ.\n");
966 AsciiPrint("Files are identical.\n");
971 Status
= EfiClose(File1
);
972 if (EFI_ERROR(Status
)) {
973 AsciiPrint("File 1 close error %r\n", Status
);
978 Status
= EfiClose(File2
);
979 if (EFI_ERROR(Status
)) {
980 AsciiPrint("File 2 close error %r\n", Status
);
984 if (Buffer1
!= NULL
) {
988 if (Buffer2
!= NULL
) {
995 GLOBAL_REMOVE_IF_UNREFERENCED
const EBL_COMMAND_TABLE mCmdDeviceTemplate
[] =
999 "[d]; Connect all EFI devices. d means disconnect",
1005 "; Show information about boot devices",
1011 " dev:path loadaddress entrypoint args; load to given address and jump in",
1017 " devname; Load PI FV from device",
1023 " path; EFI Boot Device:filepath. fs1:\\EFI\\BOOT.EFI",
1029 "; dump EFI memory map",
1035 " file1 file2; copy file only.",
1041 " file1 file2; compare files",
1049 Initialize the commands in this in this file
1053 EblInitializeDeviceCmd (
1057 EfiGetSystemConfigurationTable (&gEfiDxeServicesTableGuid
, (VOID
**) &gDS
);
1058 EblAddCommands (mCmdDeviceTemplate
, sizeof (mCmdDeviceTemplate
)/sizeof (EBL_COMMAND_TABLE
));