iPXE
efi_cmdline.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2023 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  *
19  * You can also choose to distribute this program under the terms of
20  * the Unmodified Binary Distribution Licence (as given in the file
21  * COPYING.UBDL), provided that you have satisfied its requirements.
22  */
23 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 FILE_SECBOOT ( PERMITTED );
26 
27 /** @file
28  *
29  * EFI command line
30  *
31  */
32 
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <ctype.h>
37 #include <errno.h>
38 #include <ipxe/init.h>
39 #include <ipxe/image.h>
40 #include <ipxe/script.h>
41 #include <ipxe/uaccess.h>
42 #include <ipxe/efi/efi.h>
43 #include <ipxe/efi/efi_cmdline.h>
44 
45 /** EFI command line (may not be wNUL-terminated */
46 const wchar_t *efi_cmdline;
47 
48 /** Length of EFI command line (in bytes) */
50 
51 /** Internal copy of the command line */
52 static char *efi_cmdline_copy;
53 
54 /**
55  * Free command line image
56  *
57  * @v refcnt Reference count
58  */
59 static void efi_cmdline_free ( struct refcnt *refcnt ) {
60  struct image *image = container_of ( refcnt, struct image, refcnt );
61 
62  DBGC ( image, "CMDLINE freeing command line\n" );
63  free_image ( refcnt );
65 }
66 
67 /** Embedded script representing the command line */
68 static struct image efi_cmdline_image = {
70  .name = "<CMDLINE>",
71  .flags = ( IMAGE_STATIC | IMAGE_STATIC_NAME ),
72  .type = &script_image_type,
73 };
74 
75 /** Colour for debug messages */
76 #define colour &efi_cmdline_image
77 
78 /**
79  * Initialise EFI command line
80  *
81  * @ret rc Return status code
82  */
83 static int efi_cmdline_init ( void ) {
84  char *cmdline;
85  size_t len;
86  int rc;
87 
88  /* Do nothing if no command line was specified */
89  if ( ! efi_cmdline_len ) {
90  DBGC ( colour, "CMDLINE found no command line\n" );
91  return 0;
92  }
93 
94  /* Allocate ASCII copy of command line */
95  len = ( ( efi_cmdline_len / sizeof ( efi_cmdline[0] ) ) + 1 /* NUL */ );
97  if ( ! efi_cmdline_copy ) {
98  rc = -ENOMEM;
99  goto err_alloc;
100  }
102  snprintf ( cmdline, len, "%ls", efi_cmdline );
103  DBGC ( colour, "CMDLINE found command line \"%s\"\n", cmdline );
104 
105  /* Mark command line as consumed */
106  efi_cmdline_len = 0;
107 
108  /* Strip image name and surrounding whitespace */
109  while ( isspace ( *cmdline ) )
110  cmdline++;
111  while ( *cmdline && ( ! isspace ( *cmdline ) ) )
112  cmdline++;
113  while ( isspace ( *cmdline ) )
114  cmdline++;
115  DBGC ( colour, "CMDLINE using command line \"%s\"\n", cmdline );
116 
117  /* Prepare and register image */
120  if ( efi_cmdline_image.len &&
121  ( ( rc = register_image ( &efi_cmdline_image ) ) != 0 ) ) {
122  DBGC ( colour, "CMDLINE could not register command line: %s\n",
123  strerror ( rc ) );
124  goto err_register_image;
125  }
126 
127  /* Drop our reference to the image */
129 
130  return 0;
131 
132  err_register_image:
134  err_alloc:
135  return rc;
136 }
137 
138 /**
139  * EFI command line startup function
140  *
141  */
142 static void efi_cmdline_startup ( void ) {
143  int rc;
144 
145  /* Initialise command line */
146  if ( ( rc = efi_cmdline_init() ) != 0 ) {
147  /* No way to report failure */
148  return;
149  }
150 }
151 
152 /** Command line and initrd initialisation function */
153 struct startup_fn efi_cmdline_startup_fn __startup_fn ( STARTUP_NORMAL ) = {
154  .name = "efi_cmdline",
155  .startup = efi_cmdline_startup,
156 };
#define STARTUP_NORMAL
Normal startup.
Definition: init.h:65
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
const wchar_t * efi_cmdline
EFI command line (may not be wNUL-terminated.
Definition: efi_cmdline.c:46
Error codes.
const void * data
Read-only data.
Definition: image.h:51
uint32_t type
Operating system type.
Definition: ena.h:12
#define DBGC(...)
Definition: compiler.h:505
static void efi_cmdline_startup(void)
EFI command line startup function.
Definition: efi_cmdline.c:142
An executable image.
Definition: image.h:24
Character types.
const char * name
Definition: init.h:44
iPXE scripts
A reference counter.
Definition: refcnt.h:27
A startup/shutdown function.
Definition: init.h:43
#define ENOMEM
Not enough space.
Definition: errno.h:535
void free_image(struct refcnt *refcnt)
Free executable image.
Definition: image.c:86
#define IMAGE_STATIC
Image is statically allocated.
Definition: image.h:89
struct startup_fn efi_cmdline_startup_fn __startup_fn(STARTUP_NORMAL)
Command line and initrd initialisation function.
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:36
Access to external ("user") memory.
Executable images.
static void efi_cmdline_free(struct refcnt *refcnt)
Free command line image.
Definition: efi_cmdline.c:59
ring len
Length.
Definition: dwmac.h:231
static int efi_cmdline_init(void)
Initialise EFI command line.
Definition: efi_cmdline.c:83
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
int register_image(struct image *image)
Register executable image.
Definition: image.c:315
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:55
size_t len
Length of raw file image.
Definition: image.h:56
int isspace(int character)
Check to see if character is a space.
Definition: ctype.c:42
size_t strlen(const char *src)
Get length of string.
Definition: string.c:244
static void image_put(struct image *image)
Decrement reference count on an image.
Definition: image.h:250
FILE_SECBOOT(PERMITTED)
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:621
#define colour
Colour for debug messages.
Definition: efi_cmdline.c:76
static char * efi_cmdline_copy
Internal copy of the command line.
Definition: efi_cmdline.c:52
EFI API.
#define IMAGE_STATIC_NAME
Image name is statically allocated.
Definition: image.h:92
EFI command line.
#define REF_INIT(free_fn)
Initialise a static reference counter.
Definition: refcnt.h:78
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition: vsprintf.c:383
size_t efi_cmdline_len
Length of EFI command line (in bytes)
Definition: efi_cmdline.c:49
uint32_t cmdline
Definition: multiboot.h:16
String functions.
static struct image efi_cmdline_image
Embedded script representing the command line.
Definition: efi_cmdline.c:68
struct refcnt refcnt
Reference count.
Definition: image.h:26