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>
7 This program and the accompanying materials
8 are licensed and made available under the terms and conditions of the BSD License
9 which accompanies this distribution. The full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
20 EFI_DXE_SERVICES
*gDS
= NULL
;
24 Print information about the File System device.
26 @param File Open File for the device
31 IN EFI_OPEN_FILE
*File
40 AsciiPrint (" %a: ", File
->DeviceName
);
41 if (File
->FsInfo
!= NULL
) {
42 for (Str
= File
->FsInfo
->VolumeLabel
; *Str
!= '\0'; Str
++) {
44 // UI makes you enter _ for space, so make the printout match that
47 AsciiPrint ("%c", *Str
);
50 if (File
->FsInfo
->ReadOnly
) {
51 AsciiPrint ("ReadOnly");
61 Print information about the FV devices.
63 @param File Open File for the device
68 IN EFI_OPEN_FILE
*File
75 AsciiPrint (" %a: 0x%08lx - 0x%08lx : 0x%08x\n", File
->DeviceName
, File
->FvStart
, File
->FvStart
+ File
->FvSize
- 1, File
->FvSize
);
81 Print information about the Blk IO devices.
82 If the device supports PXE dump out extra information
84 @param File Open File for the device
89 IN EFI_OPEN_FILE
*File
95 EFI_OPEN_FILE
*FsFile
;
101 AsciiPrint (" %a: ", File
->DeviceName
);
103 // print out name of file system, if any, on this block device
104 Max
= EfiGetDeviceCounts (EfiOpenFileSystem
);
106 for (Index
= 0; Index
< Max
; Index
++) {
107 FsFile
= EfiDeviceOpenByType (EfiOpenFileSystem
, Index
);
108 if (FsFile
!= NULL
) {
109 if (FsFile
->EfiHandle
== File
->EfiHandle
) {
110 AsciiPrint ("fs%d: ", Index
);
119 // Print out useful Block IO media properties
120 if (File
->FsBlockIoMedia
->RemovableMedia
) {
121 AsciiPrint ("Removable ");
123 if (!File
->FsBlockIoMedia
->MediaPresent
) {
124 AsciiPrint ("No Media\n");
126 if (File
->FsBlockIoMedia
->LogicalPartition
) {
127 AsciiPrint ("Partition ");
129 DeviceSize
= MultU64x32 (File
->FsBlockIoMedia
->LastBlock
+ 1, File
->FsBlockIoMedia
->BlockSize
);
130 AsciiPrint ("Size = 0x%lX\n", DeviceSize
);
136 Print information about the Load File devices.
137 If the device supports PXE dump out extra information
139 @param File Open File for the device
143 EblPrintLoadFileInfo (
144 IN EFI_OPEN_FILE
*File
147 EFI_DEVICE_PATH_PROTOCOL
*DevicePathNode
;
148 MAC_ADDR_DEVICE_PATH
*MacAddr
;
156 AsciiPrint (" %a: %a ", File
->DeviceName
, EblLoadFileBootTypeString (File
->EfiHandle
));
158 if (File
->DevicePath
!= NULL
) {
159 // Try to print out the MAC address
160 for (DevicePathNode
= File
->DevicePath
;
161 !IsDevicePathEnd (DevicePathNode
);
162 DevicePathNode
= NextDevicePathNode (DevicePathNode
)) {
164 if ((DevicePathType (DevicePathNode
) == MESSAGING_DEVICE_PATH
) && (DevicePathSubType (DevicePathNode
) == MSG_MAC_ADDR_DP
)) {
165 MacAddr
= (MAC_ADDR_DEVICE_PATH
*)DevicePathNode
;
167 HwAddressSize
= sizeof (EFI_MAC_ADDRESS
);
168 if (MacAddr
->IfType
== 0x01 || MacAddr
->IfType
== 0x00) {
173 for (Index
= 0; Index
< HwAddressSize
; Index
++) {
174 AsciiPrint ("%02x", MacAddr
->MacAddress
.Addr
[Index
] & 0xff);
188 Dump information about devices in the system.
190 fv: PI Firmware Volume
191 fs: EFI Simple File System
193 LoadFile: EFI Load File Protocol (commonly PXE network boot)
197 @param Argc Number of command arguments in Argv
198 @param Argv Array of strings that represent the parsed command line.
199 Argv[0] is the command name
216 // Need to call here to make sure Device Counts are valid
217 EblUpdateDeviceLists ();
219 // Now we can print out the info...
220 Max
= EfiGetDeviceCounts (EfiOpenFirmwareVolume
);
222 AsciiPrint ("Firmware Volume Devices:\n");
223 for (Index
= 0; Index
< Max
; Index
++) {
224 EblPrintFvbInfo (EfiDeviceOpenByType (EfiOpenFirmwareVolume
, Index
));
225 if (EblAnyKeyToContinueQtoQuit (&CurrentRow
, TRUE
)) {
231 Max
= EfiGetDeviceCounts (EfiOpenFileSystem
);
233 AsciiPrint ("File System Devices:\n");
234 for (Index
= 0; Index
< Max
; Index
++) {
235 EblPrintFsInfo (EfiDeviceOpenByType (EfiOpenFileSystem
, Index
));
236 if (EblAnyKeyToContinueQtoQuit (&CurrentRow
, TRUE
)) {
242 Max
= EfiGetDeviceCounts (EfiOpenBlockIo
);
244 AsciiPrint ("Block IO Devices:\n");
245 for (Index
= 0; Index
< Max
; Index
++) {
246 EblPrintBlkIoInfo (EfiDeviceOpenByType (EfiOpenBlockIo
, Index
));
247 if (EblAnyKeyToContinueQtoQuit (&CurrentRow
, TRUE
)) {
253 Max
= EfiGetDeviceCounts (EfiOpenLoadFile
);
255 AsciiPrint ("LoadFile Devices: (usually network)\n");
256 for (Index
= 0; Index
< Max
; Index
++) {
257 EblPrintLoadFileInfo (EfiDeviceOpenByType (EfiOpenLoadFile
, Index
));
258 if (EblAnyKeyToContinueQtoQuit (&CurrentRow
, TRUE
)) {
269 Start an EFI image (PE32+ with EFI defined entry point).
272 Argv[1] - device name and path
273 Argv[2] - "" string to pass into image being started
275 start fs1:\Temp\Fv.Fv "arg to pass" ; load an FV from the disk and pass the
276 ; ascii string arg to pass to the image
277 start fv0:\FV ; load an FV from an FV (not common)
278 start LoadFile0: ; load an FV via a PXE boot
280 @param Argc Number of command arguments in Argv
281 @param Argv Array of strings that represent the parsed command line.
282 Argv[0] is the command name
295 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
296 EFI_HANDLE ImageHandle
;
301 EFI_LOADED_IMAGE_PROTOCOL
*ImageInfo
;
306 return EFI_INVALID_PARAMETER
;
309 File
= EfiOpen (Argv
[1], EFI_FILE_MODE_READ
, 0);
311 return EFI_INVALID_PARAMETER
;
314 DevicePath
= File
->DevicePath
;
315 if (DevicePath
!= NULL
) {
316 // check for device path form: blk, fv, fs, and loadfile
317 Status
= gBS
->LoadImage (FALSE
, gImageHandle
, DevicePath
, NULL
, 0, &ImageHandle
);
319 // Check for buffer form: A0x12345678:0x1234 syntax.
320 // Means load using buffer starting at 0x12345678 of size 0x1234.
322 Status
= EfiReadAllocatePool (File
, &Buffer
, &BufferSize
);
323 if (EFI_ERROR (Status
)) {
327 Status
= gBS
->LoadImage (FALSE
, gImageHandle
, DevicePath
, Buffer
, BufferSize
, &ImageHandle
);
334 if (!EFI_ERROR (Status
)) {
336 // Argv[2] is a "" string that we pass directly to the EFI application without the ""
337 // We don't pass Argv[0] to the EFI Application (it's name) just the args
338 Status
= gBS
->HandleProtocol (ImageHandle
, &gEfiLoadedImageProtocolGuid
, (VOID
**)&ImageInfo
);
339 ASSERT_EFI_ERROR (Status
);
341 ImageInfo
->LoadOptionsSize
= (UINT32
)AsciiStrSize (Argv
[2]);
342 ImageInfo
->LoadOptions
= AllocatePool (ImageInfo
->LoadOptionsSize
);
343 AsciiStrCpy (ImageInfo
->LoadOptions
, Argv
[2]);
346 // Transfer control to the EFI image we loaded with LoadImage()
347 Status
= gBS
->StartImage (ImageHandle
, &ExitDataSize
, &ExitData
);
355 Load a Firmware Volume (FV) into memory from a device. This causes drivers in
356 the FV to be dispatched if the dependencies of the drivers are met.
359 Argv[1] - device name and path
361 loadfv fs1:\Temp\Fv.Fv ; load an FV from the disk
362 loadfv fv0:\FV ; load an FV from an FV (not common)
363 loadfv LoadFile0: ; load an FV via a PXE boot
365 @param Argc Number of command arguments in Argv
366 @param Argv Array of strings that represent the parsed command line.
367 Argv[0] is the command name
386 return EFI_INVALID_PARAMETER
;
389 File
= EfiOpen (Argv
[1], EFI_FILE_MODE_READ
, 0);
391 return EFI_INVALID_PARAMETER
;
394 if (File
->Type
== EfiOpenMemoryBuffer
) {
395 // If it is a address just use it.
396 Status
= gDS
->ProcessFirmwareVolume (File
->Buffer
, File
->Size
, &FvHandle
);
398 // If it is a file read it into memory and use it
399 Status
= EfiReadAllocatePool (File
, &FvStart
, &FvSize
);
401 if (EFI_ERROR (Status
)) {
405 Status
= gDS
->ProcessFirmwareVolume (FvStart
, FvSize
, &FvHandle
);
406 if (EFI_ERROR (Status
)) {
415 Perform an EFI connect to connect devices that follow the EFI driver model.
416 If it is a PI system also call the dispatcher in case a new FV was made
417 available by one of the connect EFI drivers (this is not a common case).
421 @param Argc Number of command arguments in Argv
422 @param Argv Array of strings that represent the parsed command line.
423 Argv[0] is the command name
436 EFI_HANDLE
*HandleBuffer
;
443 if ((*Argv
[1] == 'd') || (*Argv
[1] == 'D')) {
444 Status
= gBS
->LocateHandleBuffer (
451 if (EFI_ERROR (Status
)) {
455 for (Index
= 0; Index
< HandleCount
; Index
++) {
456 gBS
->DisconnectController (HandleBuffer
[Index
], NULL
, NULL
);
460 // Given we disconnect our console we should go and do a connect now
463 File
= EfiOpen (Argv
[1], EFI_FILE_MODE_READ
, 0);
465 AsciiPrint ("Connecting %a\n", Argv
[1]);
466 gBS
->ConnectController (File
->EfiHandle
, NULL
, NULL
, TRUE
);
475 Status
= gBS
->LocateHandleBuffer (
482 if (EFI_ERROR (Status
)) {
486 for (Index
= 0; Index
< HandleCount
; Index
++) {
487 gBS
->ConnectController (HandleBuffer
[Index
], NULL
, NULL
, TRUE
);
490 FreePool (HandleBuffer
);
493 // Check to see if it's possible to dispatch an more DXE drivers.
494 // The BdsLibConnectAllEfi () may have made new DXE drivers show up.
495 // If anything is Dispatched Status == EFI_SUCCESS and we will try
496 // the connect again.
499 Status
= EFI_NOT_FOUND
;
501 Status
= gDS
->Dispatch ();
502 if (!EFI_ERROR (Status
)) {
507 } while (!EFI_ERROR (Status
));
510 AsciiPrint ("Connected and dispatched\n");
512 AsciiPrint ("Connect\n");
520 CHAR8
*gMemMapType
[] = {
539 Dump out the EFI memory map
543 @param Argc Number of command arguments in Argv
544 @param Argv Array of strings that represent the parsed command line.
545 Argv[0] is the command name
557 EFI_MEMORY_DESCRIPTOR
*MemMap
;
558 EFI_MEMORY_DESCRIPTOR
*OrigMemMap
;
561 UINTN DescriptorSize
;
562 UINT32 DescriptorVersion
;
563 UINT64 PageCount
[EfiMaxMemoryType
];
569 ZeroMem (PageCount
, sizeof (PageCount
));
571 AsciiPrint ("EFI Memory Map\n");
573 // First call is to figure out how big the buffer needs to be
576 Status
= gBS
->GetMemoryMap (&MemMapSize
, MemMap
, &MapKey
, &DescriptorSize
, &DescriptorVersion
);
577 if (Status
== EFI_BUFFER_TOO_SMALL
) {
578 // In case the AllocatPool changes the memory map we added in some extra descriptors
579 MemMapSize
+= (DescriptorSize
* 0x100);
580 OrigMemMap
= MemMap
= AllocatePool (MemMapSize
);
581 if (OrigMemMap
!= NULL
) {
582 // 2nd time we get the data
583 Status
= gBS
->GetMemoryMap (&MemMapSize
, MemMap
, &MapKey
, &DescriptorSize
, &DescriptorVersion
);
584 if (!EFI_ERROR (Status
)) {
585 for (Index
= 0, CurrentRow
= 0; Index
< MemMapSize
/DescriptorSize
; Index
++) {
586 EntrySize
= LShiftU64 (MemMap
->NumberOfPages
, 12);
587 AsciiPrint ("\n%a %016lx - %016lx: # %08lx %016lx", gMemMapType
[MemMap
->Type
% EfiMaxMemoryType
], MemMap
->PhysicalStart
, MemMap
->PhysicalStart
+ EntrySize
-1, MemMap
->NumberOfPages
, MemMap
->Attribute
);
588 if (EblAnyKeyToContinueQtoQuit (&CurrentRow
, TRUE
)) {
592 PageCount
[MemMap
->Type
% EfiMaxMemoryType
] += MemMap
->NumberOfPages
;
593 MemMap
= NEXT_MEMORY_DESCRIPTOR (MemMap
, DescriptorSize
);
597 for (Index
= 0, TotalMemory
= 0; Index
< EfiMaxMemoryType
; Index
++) {
598 if (PageCount
[Index
] != 0) {
599 AsciiPrint ("\n %a %,7ld Pages (%,14ld)", gMemMapType
[Index
], PageCount
[Index
], LShiftU64 (PageCount
[Index
], 12));
600 if (Index
== EfiLoaderCode
||
601 Index
== EfiLoaderData
||
602 Index
== EfiBootServicesCode
||
603 Index
== EfiBootServicesData
||
604 Index
== EfiRuntimeServicesCode
||
605 Index
== EfiRuntimeServicesData
||
606 Index
== EfiConventionalMemory
||
607 Index
== EfiACPIReclaimMemory
||
608 Index
== EfiACPIMemoryNVS
||
611 // Count total memory
612 TotalMemory
+= PageCount
[Index
];
617 AsciiPrint ("\nTotal Memory: %,ld MB (%,ld bytes)\n", RShiftU64 (TotalMemory
, 8), LShiftU64 (TotalMemory
, 12));
619 FreePool (OrigMemMap
);
631 Load a file into memory and optionally jump to it. A load address can be
632 specified or automatically allocated. A quoted command line can optionally
633 be passed into the image.
636 Argv[1] - Device Name:path for the file to load
637 Argv[2] - Address to load to or '*' if the load address will be allocated
638 Argv[3] - Optional Entry point to the image. Image will be called if present
639 Argv[4] - "" string that will be passed as Argc & Argv to EntryPoint. Needs
640 to include the command name
642 go fv1:\EblCmdX 0x10000 0x10010 "EblCmdX Arg2 Arg3 Arg4"; - load EblCmdX
643 from FV1 to location 0x10000 and call the entry point at 0x10010 passing
644 in "EblCmdX Arg2 Arg3 Arg4" as the arguments.
646 go fv0:\EblCmdX * 0x10 "EblCmdX Arg2 Arg3 Arg4"; - load EblCmdX from FS0
647 to location allocated by this command and call the entry point at offset 0x10
648 passing in "EblCmdX Arg2 Arg3 Arg4" as the arguments.
650 go fv1:\EblCmdX 0x10000; Load EblCmdX to address 0x10000 and return
652 @param Argc Number of command arguments in Argv
653 @param Argv Array of strings that represent the parsed command line.
654 Argv[0] is the command name
669 EBL_COMMMAND EntryPoint
;
670 UINTN EntryPointArgc
;
671 CHAR8
*EntryPointArgv
[MAX_ARGS
];
675 // device name and laod address are required
679 File
= EfiOpen (Argv
[1], EFI_FILE_MODE_READ
, 0);
681 AsciiPrint (" %a is not a valid path\n", Argv
[1]);
685 EntryPoint
= (EBL_COMMMAND
)((Argc
> 3) ? (UINTN
)AsciiStrHexToUintn (Argv
[3]) : (UINTN
)NULL
);
686 if (Argv
[2][0] == '*') {
687 // * Means allocate the buffer
688 Status
= EfiReadAllocatePool (File
, &Address
, &Size
);
690 // EntryPoint is relative to the start of the image
691 EntryPoint
= (EBL_COMMMAND
)((UINTN
)EntryPoint
+ (UINTN
)Address
);
694 Address
= (VOID
*)AsciiStrHexToUintn (Argv
[2]);
697 // File->Size for LoadFile is lazy so we need to use the tell to figure it out
698 EfiTell (File
, NULL
);
699 Status
= EfiRead (File
, Address
, &Size
);
702 if (!EFI_ERROR (Status
)) {
703 AsciiPrint ("Loaded %,d bytes to 0x%08x\n", Size
, Address
);
707 ParseArguments (Argv
[4], &EntryPointArgc
, EntryPointArgv
);
710 EntryPointArgv
[0] = File
->FileName
;
713 Status
= EntryPoint (EntryPointArgc
, EntryPointArgv
);
721 #define FILE_COPY_CHUNK 0x20000
729 EFI_OPEN_FILE
*Source
= NULL
;
730 EFI_OPEN_FILE
*Destination
= NULL
;
731 EFI_STATUS Status
= EFI_SUCCESS
;
735 UINTN Chunk
= FILE_COPY_CHUNK
;
742 return EFI_INVALID_PARAMETER
;
745 DestFileName
= Argv
[2];
746 FileNameLen
= AsciiStrLen (DestFileName
);
748 // Check if the destination file name looks like a directory
749 if ((DestFileName
[FileNameLen
-1] == '\\') || (DestFileName
[FileNameLen
-1] == ':')) {
750 // Set the pointer after the source drive (eg: after fs1:)
751 SrcPtr
= AsciiStrStr (Argv
[1], ":");
752 if (SrcPtr
== NULL
) {
756 if (*SrcPtr
== '\\') {
761 if (*SrcPtr
== '\0') {
762 AsciiPrint("Source file incorrect.\n");
765 // Skip the Source Directories
767 SrcFileName
= SrcPtr
;
768 SrcPtr
= AsciiStrStr (SrcPtr
,"\\");
769 if (SrcPtr
!= NULL
) {
776 if (*SrcFileName
== '\0') {
777 AsciiPrint("Source file incorrect (Error 2).\n");
780 // Construct the destination filepath
781 DestFileName
= (CHAR8
*)AllocatePool (FileNameLen
+ AsciiStrLen (SrcFileName
) + 1);
782 AsciiStrCpy (DestFileName
, Argv
[2]);
783 AsciiStrCat (DestFileName
, SrcFileName
);
786 Source
= EfiOpen(Argv
[1], EFI_FILE_MODE_READ
, 0);
787 if (Source
== NULL
) {
788 AsciiPrint("Source file open error.\n");
789 return EFI_NOT_FOUND
;
792 Destination
= EfiOpen(DestFileName
, EFI_FILE_MODE_READ
| EFI_FILE_MODE_WRITE
| EFI_FILE_MODE_CREATE
, 0);
793 if (Destination
== NULL
) {
794 AsciiPrint("Destination file open error.\n");
795 return EFI_NOT_FOUND
;
798 Buffer
= AllocatePool(FILE_COPY_CHUNK
);
799 if (Buffer
== NULL
) {
803 Size
= EfiTell(Source
, NULL
);
805 for (Offset
= 0; Offset
+ FILE_COPY_CHUNK
<= Size
; Offset
+= Chunk
) {
806 Chunk
= FILE_COPY_CHUNK
;
808 Status
= EfiRead(Source
, Buffer
, &Chunk
);
809 if (EFI_ERROR(Status
)) {
810 AsciiPrint("Read file error %r\n", Status
);
814 Status
= EfiWrite(Destination
, Buffer
, &Chunk
);
815 if (EFI_ERROR(Status
)) {
816 AsciiPrint("Write file error %r\n", Status
);
823 Chunk
= Size
- Offset
;
825 Status
= EfiRead(Source
, Buffer
, &Chunk
);
826 if (EFI_ERROR(Status
)) {
827 AsciiPrint("Read file error %r\n", Status
);
831 Status
= EfiWrite(Destination
, Buffer
, &Chunk
);
832 if (EFI_ERROR(Status
)) {
833 AsciiPrint("Write file error %r\n", Status
);
840 if (Source
!= NULL
) {
841 Status
= EfiClose(Source
);
842 if (EFI_ERROR(Status
)) {
843 AsciiPrint("Source close error %r\n", Status
);
846 if (Destination
!= NULL
) {
847 Status
= EfiClose(Destination
);
848 if (EFI_ERROR(Status
)) {
849 AsciiPrint("Destination close error %r\n", Status
);
852 // Case when we have concated the filename to the destination directory
853 if (DestFileName
!= Argv
[2]) {
854 FreePool (DestFileName
);
858 if (Buffer
!= NULL
) {
871 EFI_OPEN_FILE
*File1
= NULL
;
872 EFI_OPEN_FILE
*File2
= NULL
;
873 EFI_STATUS Status
= EFI_SUCCESS
;
874 VOID
*Buffer1
= NULL
;
875 VOID
*Buffer2
= NULL
;
879 UINTN Chunk
= FILE_COPY_CHUNK
;
882 return EFI_INVALID_PARAMETER
;
885 File1
= EfiOpen(Argv
[1], EFI_FILE_MODE_READ
, 0);
887 AsciiPrint("File 1 open error.\n");
888 return EFI_NOT_FOUND
;
891 File2
= EfiOpen(Argv
[2], EFI_FILE_MODE_READ
, 0);
893 AsciiPrint("File 2 open error.\n");
894 return EFI_NOT_FOUND
;
897 Size1
= EfiTell(File1
, NULL
);
898 Size2
= EfiTell(File2
, NULL
);
900 if (Size1
!= Size2
) {
901 AsciiPrint("Files differ.\n");
905 Buffer1
= AllocatePool(FILE_COPY_CHUNK
);
906 if (Buffer1
== NULL
) {
910 Buffer2
= AllocatePool(FILE_COPY_CHUNK
);
911 if (Buffer2
== NULL
) {
915 for (Offset
= 0; Offset
+ FILE_COPY_CHUNK
<= Size1
; Offset
+= Chunk
) {
916 Chunk
= FILE_COPY_CHUNK
;
918 Status
= EfiRead(File1
, Buffer1
, &Chunk
);
919 if (EFI_ERROR(Status
)) {
920 AsciiPrint("File 1 read error\n");
924 Status
= EfiRead(File2
, Buffer2
, &Chunk
);
925 if (EFI_ERROR(Status
)) {
926 AsciiPrint("File 2 read error\n");
930 if (CompareMem(Buffer1
, Buffer2
, Chunk
) != 0) {
931 AsciiPrint("Files differ.\n");
937 if (Offset
< Size1
) {
938 Chunk
= Size1
- Offset
;
940 Status
= EfiRead(File1
, Buffer1
, &Chunk
);
941 if (EFI_ERROR(Status
)) {
942 AsciiPrint("File 1 read error\n");
946 Status
= EfiRead(File2
, Buffer2
, &Chunk
);
947 if (EFI_ERROR(Status
)) {
948 AsciiPrint("File 2 read error\n");
953 if (CompareMem(Buffer1
, Buffer2
, Chunk
) != 0) {
954 AsciiPrint("Files differ.\n");
956 AsciiPrint("Files are identical.\n");
961 Status
= EfiClose(File1
);
962 if (EFI_ERROR(Status
)) {
963 AsciiPrint("File 1 close error %r\n", Status
);
968 Status
= EfiClose(File2
);
969 if (EFI_ERROR(Status
)) {
970 AsciiPrint("File 2 close error %r\n", Status
);
974 if (Buffer1
!= NULL
) {
978 if (Buffer2
!= NULL
) {
985 GLOBAL_REMOVE_IF_UNREFERENCED
const EBL_COMMAND_TABLE mCmdDeviceTemplate
[] =
989 "[d]; Connect all EFI devices. d means disconnect",
995 "; Show information about boot devices",
1001 " dev:path loadaddress entrypoint args; load to given address and jump in",
1007 " devname; Load PI FV from device",
1013 " path; EFI Boot Device:filepath. fs1:\\EFI\\BOOT.EFI",
1019 "; dump EFI memory map",
1025 " file1 file2; copy file only.",
1031 " file1 file2; compare files",
1039 Initialize the commands in this in this file
1043 EblInitializeDeviceCmd (
1047 EfiGetSystemConfigurationTable (&gEfiDxeServicesTableGuid
, (VOID
**) &gDS
);
1048 EblAddCommands (mCmdDeviceTemplate
, sizeof (mCmdDeviceTemplate
)/sizeof (EBL_COMMAND_TABLE
));