Shell App - Get Args unsupported?


Mitchell, Nathaniel P
 

Hi all,

I'm trying to create a basic shell app that consumes command line arguments. I'm able to build and run the .efi file. I looked around and found examples of the function "GetArg()" using gBS->HandleProtocol. I tried updating it to use gBS->OpenProtocol, but in both cases the return of the Handle/Open Protocol calls return 0x3 which from what I gather means "EFI_UNSUPPORTED". After googling a little, it looks like when that error comes up for other people it means something is corrupted, so I'm not sure if I'm not compiling it correctly, or I'm missing a step, or if something else is wrong. If anyone has any ideas, that would be appreciated!

Build environment: Windows-10-10.0.19042-SP0
WORKSPACE = c:\edk\edk2
EDK_TOOLS_PATH = c:\edk\edk2\basetools
EDK_TOOLS_BIN = c:\edk\edk2\basetools\bin\win32
CONF_PATH = c:\edk\edk2\conf
PYTHON_COMMAND = py -3

Processing meta-data .
Architecture(s) = X64
Build target = DEBUG
Toolchain = VS2019
Active Platform = c:\edk\edk2\MdeModulePkg\MdeModulePkg.dsc

py -3 --version
Python 3.10.0

Thanks,
Nathaniel


Andrew Fish
 

Nathaniel,

Are you trying to write an EFI App or a Shell App?

Conceptually a Shell App is an EFI App that also has access to gEfiShellProtocolGuid, gEfiShellParametersProtocolGuid, etc. But to have access to those features the UEFI Shell has to be running. The Shell APIs help you do useful things and abstract some Shell concepts like Volume names (fs0:), as volume names don’t exist in UEFI.

So 1st off did you launch your App from the Shell?

2nd did you build your App from the edk2? Did you link in UefiApplicationEntryPoint? Means it is in the INF under [LibraryClasses]

I assume your example code looks like…

EFI_STATUS Status;
EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters;

Status = gBS->HandleProtocol (
gImageHandle,
&gEfiShellParametersProtocolGuid,
(VOID**)&ShellParameters
);
if (EFI_ERROR(Status)) {
return Status;
}

The gImageHandle is the image handle for your app. It was set by the UefiBootServicesTableLib that would be pulled in by the UefiApplicationEntryPoint lib. An image handle is created when ever a PE/COFF image is loaded in EFI. The UEFI Shell adds the extra gEfiShellParametersProtocolGuid on this handle.

You should be getting a return code of 0x800000000000003[1] you can use %r to get it decoded for you, or %lx to see the real value. FYI 0x3 is actually RETURN_WARN_WRITE_FAILURE.

The way EFI works is you have a set of handle, and each handle has a set of unique protocols on the handle. If gEfiShellParametersProtocolGuid is not present that means you passed in the wrong handle, or you did not load from the UEFI Shell so gEfiShellParametersProtocolGuid did not get added to the handle.

[1] https://github.com/tianocore/edk2/blob/master/MdePkg/Include/Base.h#L1002

Thanks,

Andrew Fish

On Dec 6, 2021, at 12:33 PM, nathaniel.p.mitchell@intel.com wrote:

Hi all,

I'm trying to create a basic shell app that consumes command line arguments. I'm able to build and run the .efi file. I looked around and found examples of the function "GetArg()" using gBS->HandleProtocol. I tried updating it to use gBS->OpenProtocol, but in both cases the return of the Handle/Open Protocol calls return 0x3 which from what I gather means "EFI_UNSUPPORTED". After googling a little, it looks like when that error comes up for other people it means something is corrupted, so I'm not sure if I'm not compiling it correctly, or I'm missing a step, or if something else is wrong. If anyone has any ideas, that would be appreciated!

Build environment: Windows-10-10.0.19042-SP0
WORKSPACE = c:\edk\edk2
EDK_TOOLS_PATH = c:\edk\edk2\basetools
EDK_TOOLS_BIN = c:\edk\edk2\basetools\bin\win32
CONF_PATH = c:\edk\edk2\conf
PYTHON_COMMAND = py -3

Processing meta-data .
Architecture(s) = X64
Build target = DEBUG
Toolchain = VS2019
Active Platform = c:\edk\edk2\MdeModulePkg\MdeModulePkg.dsc

py -3 --version
Python 3.10.0

Thanks,
Nathaniel





Mitchell, Nathaniel P
 

That was very helpful Andrew, Thank you!

I was able to get it working on my own, but you helped me understand what I did.

Nathaniel

From: Andrew Fish <afish@apple.com>
Sent: Tuesday, December 7, 2021 10:05 AM
To: discuss <discuss@edk2.groups.io>; Mitchell, Nathaniel P <nathaniel.p.mitchell@intel.com>
Subject: Re: [edk2-discuss] Shell App - Get Args unsupported?

Nathaniel,

Are you trying to write an EFI App or a Shell App?

Conceptually a Shell App is an EFI App that also has access to gEfiShellProtocolGuid, gEfiShellParametersProtocolGuid, etc. But to have access to those features the UEFI Shell has to be running. The Shell APIs help you do useful things and abstract some Shell concepts like Volume names (fs0:), as volume names don’t exist in UEFI.

So 1st off did you launch your App from the Shell?

2nd did you build your App from the edk2? Did you link in UefiApplicationEntryPoint? Means it is in the INF under [LibraryClasses]

I assume your example code looks like…

EFI_STATUS Status;
EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters;

Status = gBS->HandleProtocol (
gImageHandle,
&gEfiShellParametersProtocolGuid,
(VOID**)&ShellParameters
);
if (EFI_ERROR(Status)) {
return Status;
}

The gImageHandle is the image handle for your app. It was set by the UefiBootServicesTableLib that would be pulled in by the UefiApplicationEntryPoint lib. An image handle is created when ever a PE/COFF image is loaded in EFI. The UEFI Shell adds the extra gEfiShellParametersProtocolGuid on this handle.

You should be getting a return code of 0x800000000000003[1] you can use %r to get it decoded for you, or %lx to see the real value. FYI 0x3 is actually RETURN_WARN_WRITE_FAILURE.

The way EFI works is you have a set of handle, and each handle has a set of unique protocols on the handle. If gEfiShellParametersProtocolGuid is not present that means you passed in the wrong handle, or you did not load from the UEFI Shell so gEfiShellParametersProtocolGuid did not get added to the handle.

[1] https://github.com/tianocore/edk2/blob/master/MdePkg/Include/Base.h#L1002

Thanks,

Andrew Fish


On Dec 6, 2021, at 12:33 PM, nathaniel.p.mitchell@intel.com<mailto:nathaniel.p.mitchell@intel.com> wrote:

Hi all,

I'm trying to create a basic shell app that consumes command line arguments. I'm able to build and run the .efi file. I looked around and found examples of the function "GetArg()" using gBS->HandleProtocol. I tried updating it to use gBS->OpenProtocol, but in both cases the return of the Handle/Open Protocol calls return 0x3 which from what I gather means "EFI_UNSUPPORTED". After googling a little, it looks like when that error comes up for other people it means something is corrupted, so I'm not sure if I'm not compiling it correctly, or I'm missing a step, or if something else is wrong. If anyone has any ideas, that would be appreciated!

Build environment: Windows-10-10.0.19042-SP0
WORKSPACE = c:\edk\edk2
EDK_TOOLS_PATH = c:\edk\edk2\basetools
EDK_TOOLS_BIN = c:\edk\edk2\basetools\bin\win32
CONF_PATH = c:\edk\edk2\conf
PYTHON_COMMAND = py -3

Processing meta-data .
Architecture(s) = X64
Build target = DEBUG
Toolchain = VS2019
Active Platform = c:\edk\edk2\MdeModulePkg\MdeModulePkg.dsc


py -3 --version
Python 3.10.0

Thanks,
Nathaniel