Search code examples
shellcommandbootloaderuefi

Run a UEFI shell command from inside UEFI application


I'm new to UEFI application development.

My requirement is that,

I need to run an UEFI shell command from my UEFI application (app.efi) source code. Need guidance on how I can do this.

Example,

cp command in UEFI shell is used to copy a file from one path to another. I want to do this programmatically inside my application (app.efi) source code.

EDIT: I'm looking for something similar to system("command"); function in Linux.

How to achieve this?


Solution

  • Calling a UEFI shell command from a UEFI application can be done using the EFI_SHELL_EXECUTE function of EFI_SHELL_PROTOCOL, defined under MdePkg/Include/Protocol/Shell.h.

    You need to include the protocol GUID in the inf file of your UEFI application:

    [Protocols]
      gEfiShellProtocolGuid                  ## CONSUMES
    

    Then you can call a shell command like in the following example:

    EFI_STATUS
    EFIAPI
    UefiMain (
      IN EFI_HANDLE                            ImageHandle,
      IN EFI_SYSTEM_TABLE                      *SystemTable
      )
    {
      EFI_SHELL_PROTOCOL    *EfiShellProtocol;
      EFI_STATUS            Status;
    
      Status = gBS->LocateProtocol (&gEfiShellProtocolGuid,
                                    NULL,
                                    (VOID **) &EfiShellProtocol);
    
      if (EFI_ERROR (Status)) {
        return Status; 
      }
    
      EfiShellProtocol->Execute (&ImageHandle,
                                 L"echo Hello World!",
                                 NULL,
                                 &Status);
    
      return Status;
    }
    

    EDIT: There's an easier (and probably a more correct) way of doing it using ShellLib Library Class:

    #include <Library/ShellLib.h>
    
    EFI_STATUS
    EFIAPI
    UefiMain (
      IN EFI_HANDLE                            ImageHandle,
      IN EFI_SYSTEM_TABLE                      *SystemTable
      )
    {
      EFI_STATUS            Status;
    
      ShellExecute (&ImageHandle,
                    L"echo Hello World!",
                    FALSE,
                    NULL,
                    &Status);
    
      return Status;
    }