这个UEFI shell app跟我们平时用的C语言的main函数有点像,支持传参数…
写个例子测试下:
PATH:
edk2/ShellPkg/Application/TestShellApp/TestShellApp.inf
## @file
# This is the shell application
#
# Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
#
##
[Defines]
INF_VERSION = 0x00010006
BASE_NAME = TestShellApp
FILE_GUID = 7a6ca325-ee33-489c-b300-24544a7bd418
MODULE_TYPE = UEFI_APPLICATION
VERSION_STRING = 1.0
ENTRY_POINT = ShellCEntryLib
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 EBC
#
[Sources]
TestShellApp.c
[Packages]
MdePkg/MdePkg.dec
ShellPkg/ShellPkg.dec
[LibraryClasses]
ShellCEntryLib
UefiLib
PATH:
/** @file
This is a test application that demonstrates how to use the C-style entry point
for a shell application.
Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <Uefi.h>
#include <Library/UefiLib.h>
#include <Library/DebugLib.h>
#include <Library/ShellCEntryLib.h>
/**
UEFI application entry point which has an interface similar to a
standard C main function.
The ShellCEntryLib library instance wrappers the actual UEFI application
entry point and calls this ShellAppMain function.
@param[in] Argc The number of items in Argv.
@param[in] Argv Array of pointers to strings.
@retval 0 The application exited normally.
@retval Other An error occurred.
**/
INTN
EFIAPI
ShellAppMain (
IN UINTN Argc,
IN CHAR16 **Argv
)
{
UINTN Index;
Print (L"Argc: %d\n",Argc);
if (Argc == 1) {
Print (L"Argv[1] = NULL\n");
}
for (Index = 0; Index < Argc; Index++) {
Print(L"Argv[%d]: \"%s\"\n", Index, Argv[Index]);
}
return 0;
}
结果:
上面的工程文件中:
ENTRY_POINT = ShellCEntryLib
表明这个APP的实际入口应该是ShellCEntryLib,这个函数路径:
edk2/ShellPkg/Library/UefiShellCEntryLib/UefiShellCEntryLib.c
/**
UEFI entry point for an application that will in turn call the
ShellAppMain function which has parameters similar to a standard C
main function.
An application that uses UefiShellCEntryLib must have a ShellAppMain
function as prototyped in Include/Library/ShellCEntryLib.h.
Note that the Shell uses POSITIVE integers for error values, while UEFI
uses NEGATIVE values. If the application is to be used within a script,
it needs to return one of the SHELL_STATUS values defined in Protocol/Shell.h.
@param ImageHandle The image handle of the UEFI Application.
@param SystemTable A pointer to the EFI System Table.
@retval EFI_SUCCESS The application exited normally.
@retval Other An error occurred.
**/
EFI_STATUS
EFIAPI
ShellCEntryLib (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
INTN ReturnFromMain;
EFI_SHELL_PARAMETERS_PROTOCOL *EfiShellParametersProtocol;
EFI_SHELL_INTERFACE *EfiShellInterface;
EFI_STATUS Status;
ReturnFromMain = -1;
EfiShellParametersProtocol = NULL;
EfiShellInterface = NULL;
Status = SystemTable->BootServices->OpenProtocol(ImageHandle,
&gEfiShellParametersProtocolGuid,
(VOID **)&EfiShellParametersProtocol,
ImageHandle,
NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (!EFI_ERROR(Status)) {
//
// use shell 2.0 interface
//
ReturnFromMain = ShellAppMain (
EfiShellParametersProtocol->Argc,
EfiShellParametersProtocol->Argv
);
} else {
//
// try to get shell 1.0 interface instead.
//
Status = SystemTable->BootServices->OpenProtocol(ImageHandle,
&gEfiShellInterfaceGuid,
(VOID **)&EfiShellInterface,
ImageHandle,
NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (!EFI_ERROR(Status)) {
//
// use shell 1.0 interface
//
ReturnFromMain = ShellAppMain (
EfiShellInterface->Argc,
EfiShellInterface->Argv
);
} else {
ASSERT(FALSE);
}
}
return ReturnFromMain;
}
上面我们可以看到,在 shell app的ShellAppMain是在ShellCEntryLib里面调用的,而传给ShellAppMain的参数实参是:
EfiShellInterface->Argc
EfiShellInterface->Argv
这两个参数是根据EFI_SHELL_PARAMETERS_PROTOCOL得到的
typedef struct _EFI_SHELL_PARAMETERS_PROTOCOL {
///
/// Points to an Argc-element array of points to NULL-terminated strings containing
/// the command-line parameters. The first entry in the array is always the full file
/// path of the executable. Any quotation marks that were used to preserve
/// whitespace have been removed.
///
CHAR16 **Argv;
///
/// The number of elements in the Argv array.
///
UINTN Argc;
///
/// The file handle for the standard input for this executable. This may be different
/// from the ConInHandle in EFI_SYSTEM_TABLE.
///
SHELL_FILE_HANDLE StdIn;
///
/// The file handle for the standard output for this executable. This may be different
/// from the ConOutHandle in EFI_SYSTEM_TABLE.
///
SHELL_FILE_HANDLE StdOut;
///
/// The file handle for the standard error output for this executable. This may be
/// different from the StdErrHandle in EFI_SYSTEM_TABLE.
///
SHELL_FILE_HANDLE StdErr;
} EFI_SHELL_PARAMETERS_PROTOCOL;