Bläddra i källkod

From: David Decotigny <decot@googlers.com>
Date: Thu, 31 Jul 2014 13:42:23 -0700
Subject: [PATCH 4/4] Use Shell protocols to retrieve argc/argv, when
available.

New header files efishellintf.h efishellparm.h are coming from EDK
II, initial location and license at top of files. Only modifications:
- efishellintf.h: s/EFI_FILE_PROTOCOL/EFI_FILE/ + expand BITx macros (1<<x)
- efishellparm.h: typedef VOID *SHELL_FILE_HANDLE to avoid including
ShellBase.h
- both: removed extern EFI_GUID variable decls

This also adds apps/t8.c, a simple demo.

Signed-off-by: David Decotigny <decot@googlers.com>
Signed-off-by: Nigel Croxon <nigel.croxon@hp.com>

Nigel Croxon 10 år sedan
förälder
incheckning
f42974dd9a

+ 1 - 1
gnu-efi-3.0/apps/Makefile

@@ -61,7 +61,7 @@ LOADLIBES	+= -T $(LDSCRIPT)
 FORMAT		= efi-app-$(ARCH)
 
 TARGET_APPS = t.efi t2.efi t3.efi t4.efi t5.efi t6.efi \
-	      printenv.efi t7.efi tcc.efi modelist.efi \
+	      printenv.efi t7.efi t8.efi tcc.efi modelist.efi \
 	      route80h.efi drv0_use.efi AllocPages.efi \
 	      FreePages.efi
 TARGET_BSDRIVERS = drv0.efi

+ 19 - 0
gnu-efi-3.0/apps/t8.c

@@ -0,0 +1,19 @@
+#include <efi.h>
+#include <efilib.h>
+
+EFI_STATUS
+efi_main (EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
+{
+  INTN Argc, i;
+  CHAR16 **Argv;
+
+  InitializeLib(ImageHandle, SystemTable);
+  Argc = GetShellArgcArgv(ImageHandle, &Argv);
+
+  Print(L"Hello World, started with Argc=%d\n", Argc);
+  for (i = 0 ; i < Argc ; ++i)
+    Print(L"  Argv[%d] = '%s'\n", i, Argv[i]);
+
+  Print(L"Bye.\n");
+  return EFI_SUCCESS;
+}

+ 94 - 0
gnu-efi-3.0/inc/efishellintf.h

@@ -0,0 +1,94 @@
+/** @file
+  SHELL_INTERFACE_PROTOCOL from EDK shell (no spec).
+
+  Shell Interface - additional information (over image_info) provided
+  to an application started by the shell.
+
+  ConIo provides a file-style interface to the console.
+
+  The shell interface's and data (including ConIo) are only valid during
+  the applications Entry Point.  Once the application returns from it's
+  entry point the data is freed by the invoking shell.
+
+  Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+/*
+ * This is based on ShellPkg/Include/Protocol/EfiShellInterface.h from EDK II.
+ */
+
+#ifndef _SHELLINTERFACE_H_
+#define _SHELLINTERFACE_H_
+
+
+#define SHELL_INTERFACE_PROTOCOL_GUID \
+  { \
+    0x47c7b223, 0xc42a, 0x11d2, {0x8e, 0x57, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b} \
+  }
+
+///
+/// Bit definitions for EFI_SHELL_ARG_INFO
+///
+typedef enum {
+  ARG_NO_ATTRIB         = 0x0,
+  ARG_IS_QUOTED         = 1<<0,
+  ARG_PARTIALLY_QUOTED  = 1<<1,
+  ARG_FIRST_HALF_QUOTED = 1<<2,
+  ARG_FIRST_CHAR_IS_ESC = 1<<3
+} EFI_SHELL_ARG_INFO_TYPES;
+
+///
+/// Attributes for an argument.
+///
+typedef struct _EFI_SHELL_ARG_INFO {
+  UINT32  Attributes;
+} EFI_SHELL_ARG_INFO;
+
+///
+/// This protocol provides access to additional information about a shell application.
+///
+typedef struct {
+  ///
+  /// Handle back to original image handle & image information.
+  ///
+  EFI_HANDLE                ImageHandle;
+  EFI_LOADED_IMAGE *Info;
+
+  ///
+  /// Parsed arg list converted more C-like format.
+  ///
+  CHAR16                    **Argv;
+  UINTN                     Argc;
+
+  ///
+  /// Storage for file redirection args after parsing.
+  ///
+  CHAR16                    **RedirArgv;
+  UINTN                     RedirArgc;
+
+  ///
+  /// A file style handle for console io.
+  ///
+  EFI_FILE         *StdIn;
+  EFI_FILE         *StdOut;
+  EFI_FILE         *StdErr;
+
+  ///
+  /// List of attributes for each argument.
+  ///
+  EFI_SHELL_ARG_INFO        *ArgInfo;
+
+  ///
+  /// Whether we are echoing.
+  ///
+  BOOLEAN                   EchoOn;
+} EFI_SHELL_INTERFACE;
+
+#endif

+ 63 - 0
gnu-efi-3.0/inc/efishellparm.h

@@ -0,0 +1,63 @@
+/** @file
+  EFI_SHELL_PARAMETERS_PROTOCOL as defined in the UEFI Shell 2.0 specification.
+
+  Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+/*
+ * This is based on ShellPkg/Include/Protocol/EfiShellParameters.h from EDK II.
+ */
+
+#ifndef __EFI_SHELL_PARAMETERS_PROTOCOL__
+#define __EFI_SHELL_PARAMETERS_PROTOCOL__
+
+
+// EDK2's ShellBase.h
+typedef VOID *SHELL_FILE_HANDLE;
+
+#define EFI_SHELL_PARAMETERS_PROTOCOL_GUID \
+  { \
+  0x752f3136, 0x4e16, 0x4fdc, { 0xa2, 0x2a, 0xe5, 0xf4, 0x68, 0x12, 0xf4, 0xca } \
+  }
+
+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;
+
+#endif

+ 55 - 1
gnu-efi-3.0/lib/cmdline.c

@@ -1,5 +1,9 @@
 #include "lib.h"
 
+#include "efiprot.h"
+#include "efishellintf.h"
+#include "efishellparm.h"
+
 #ifndef MAX_ARGV_CONTENTS_SIZE
 # define MAX_CMDLINE_SIZE 1024
 #endif
@@ -19,8 +23,9 @@
   For safety, we support the trailing \0 without a space before, as
   well as several consecutive spaces (-> several args).
 */
+static
 INTN
-GetShellArgcArgv(
+GetShellArgcArgvFromLoadedImage(
     EFI_HANDLE ImageHandle,
     CHAR16 **ResultArgv[]
     )
@@ -62,6 +67,55 @@ GetShellArgcArgv(
   if ((*ArgStart != L'\0') && (Argc < MAX_CMDLINE_ARGC))
     Argv[Argc++] = ArgStart;
 
+  // Print(L"Got argc/argv from loaded image proto\n");
   *ResultArgv = Argv;
   return Argc;
 }
+
+INTN GetShellArgcArgv(EFI_HANDLE ImageHandle, CHAR16 **Argv[])
+{
+  // Code inspired from EDK2's
+  // ShellPkg/Library/UefiShellCEntryLib/UefiShellCEntryLib.c (BSD)
+  EFI_STATUS Status;
+  static const EFI_GUID EfiShellParametersProtocolGuid
+      = EFI_SHELL_PARAMETERS_PROTOCOL_GUID;
+  static const EFI_GUID ShellInterfaceProtocolGuid
+      = SHELL_INTERFACE_PROTOCOL_GUID;
+  EFI_SHELL_PARAMETERS_PROTOCOL *EfiShellParametersProtocol = NULL;
+  EFI_SHELL_INTERFACE *EfiShellInterfaceProtocol = NULL;
+
+  Status = uefi_call_wrapper(BS->OpenProtocol, 6,
+                             ImageHandle,
+                             &EfiShellParametersProtocolGuid,
+                             (VOID **)&EfiShellParametersProtocol,
+                             ImageHandle,
+                             NULL,
+                             EFI_OPEN_PROTOCOL_GET_PROTOCOL
+                             );
+  if (!EFI_ERROR(Status))
+  {
+    // use shell 2.0 interface
+    // Print(L"Got argc/argv from shell intf proto\n");
+    *Argv = EfiShellParametersProtocol->Argv;
+    return EfiShellParametersProtocol->Argc;
+  }
+
+  // try to get shell 1.0 interface instead.
+  Status = uefi_call_wrapper(BS->OpenProtocol, 6,
+                             ImageHandle,
+                             &ShellInterfaceProtocolGuid,
+                             (VOID **)&EfiShellInterfaceProtocol,
+                             ImageHandle,
+                             NULL,
+                             EFI_OPEN_PROTOCOL_GET_PROTOCOL
+                             );
+  if (!EFI_ERROR(Status))
+  {
+    // Print(L"Got argc/argv from shell params proto\n");
+    *Argv = EfiShellInterfaceProtocol->Argv;
+    return EfiShellInterfaceProtocol->Argc;
+  }
+
+  // shell 1.0 and 2.0 interfaces failed
+  return GetShellArgcArgvFromLoadedImage(ImageHandle, Argv);
+}