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 
26 /** @file
27  *
28  * EFI command line
29  *
30  */
31 
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <ctype.h>
36 #include <errno.h>
37 #include <ipxe/init.h>
38 #include <ipxe/image.h>
39 #include <ipxe/script.h>
40 #include <ipxe/uaccess.h>
41 #include <ipxe/efi/efi.h>
42 #include <ipxe/efi/efi_cmdline.h>
43 
44 /** EFI command line (may not be wNUL-terminated */
45 const wchar_t *efi_cmdline;
46 
47 /** Length of EFI command line (in bytes) */
49 
50 /** Internal copy of the command line */
51 static char *efi_cmdline_copy;
52 
53 /**
54  * Free command line image
55  *
56  * @v refcnt Reference count
57  */
58 static void efi_cmdline_free ( struct refcnt *refcnt ) {
59  struct image *image = container_of ( refcnt, struct image, refcnt );
60 
61  DBGC ( image, "CMDLINE freeing command line\n" );
62  free_image ( refcnt );
64 }
65 
66 /** Embedded script representing the command line */
67 static struct image efi_cmdline_image = {
69  .name = "<CMDLINE>",
70  .flags = ( IMAGE_STATIC | IMAGE_STATIC_NAME ),
71  .type = &script_image_type,
72 };
73 
74 /** Colour for debug messages */
75 #define colour &efi_cmdline_image
76 
77 /**
78  * Initialise EFI command line
79  *
80  * @ret rc Return status code
81  */
82 static int efi_cmdline_init ( void ) {
83  char *cmdline;
84  size_t len;
85  int rc;
86 
87  /* Do nothing if no command line was specified */
88  if ( ! efi_cmdline_len ) {
89  DBGC ( colour, "CMDLINE found no command line\n" );
90  return 0;
91  }
92 
93  /* Allocate ASCII copy of command line */
94  len = ( ( efi_cmdline_len / sizeof ( efi_cmdline[0] ) ) + 1 /* NUL */ );
96  if ( ! efi_cmdline_copy ) {
97  rc = -ENOMEM;
98  goto err_alloc;
99  }
101  snprintf ( cmdline, len, "%ls", efi_cmdline );
102  DBGC ( colour, "CMDLINE found command line \"%s\"\n", cmdline );
103 
104  /* Mark command line as consumed */
105  efi_cmdline_len = 0;
106 
107  /* Strip image name and surrounding whitespace */
108  while ( isspace ( *cmdline ) )
109  cmdline++;
110  while ( *cmdline && ( ! isspace ( *cmdline ) ) )
111  cmdline++;
112  while ( isspace ( *cmdline ) )
113  cmdline++;
114  DBGC ( colour, "CMDLINE using command line \"%s\"\n", cmdline );
115 
116  /* Prepare and register image */
119  if ( efi_cmdline_image.len &&
120  ( ( rc = register_image ( &efi_cmdline_image ) ) != 0 ) ) {
121  DBGC ( colour, "CMDLINE could not register command line: %s\n",
122  strerror ( rc ) );
123  goto err_register_image;
124  }
125 
126  /* Drop our reference to the image */
128 
129  return 0;
130 
131  err_register_image:
133  err_alloc:
134  return rc;
135 }
136 
137 /**
138  * EFI command line startup function
139  *
140  */
141 static void efi_cmdline_startup ( void ) {
142  int rc;
143 
144  /* Initialise command line */
145  if ( ( rc = efi_cmdline_init() ) != 0 ) {
146  /* No way to report failure */
147  return;
148  }
149 }
150 
151 /** Command line and initrd initialisation function */
152 struct startup_fn efi_cmdline_startup_fn __startup_fn ( STARTUP_NORMAL ) = {
153  .name = "efi_cmdline",
154  .startup = efi_cmdline_startup,
155 };
#define STARTUP_NORMAL
Normal startup.
Definition: init.h:64
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:45
Error codes.
const void * data
Read-only data.
Definition: image.h:50
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:141
An executable image.
Definition: image.h:23
Character types.
const char * name
Definition: init.h:43
iPXE scripts
A reference counter.
Definition: refcnt.h:26
A startup/shutdown function.
Definition: init.h:42
#define ENOMEM
Not enough space.
Definition: errno.h:534
void free_image(struct refcnt *refcnt)
Free executable image.
Definition: image.c:85
#define IMAGE_STATIC
Image is statically allocated.
Definition: image.h:88
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:35
Access to external ("user") memory.
Executable images.
static void efi_cmdline_free(struct refcnt *refcnt)
Free command line image.
Definition: efi_cmdline.c:58
ring len
Length.
Definition: dwmac.h:231
static int efi_cmdline_init(void)
Initialise EFI command line.
Definition: efi_cmdline.c:82
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
int register_image(struct image *image)
Register executable image.
Definition: image.c:314
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
size_t len
Length of raw file image.
Definition: image.h:55
int isspace(int character)
Check to see if character is a space.
Definition: ctype.c:41
size_t strlen(const char *src)
Get length of string.
Definition: string.c:243
static void image_put(struct image *image)
Decrement reference count on an image.
Definition: image.h:249
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:620
#define colour
Colour for debug messages.
Definition: efi_cmdline.c:75
static char * efi_cmdline_copy
Internal copy of the command line.
Definition: efi_cmdline.c:51
EFI API.
#define IMAGE_STATIC_NAME
Image name is statically allocated.
Definition: image.h:91
EFI command line.
#define REF_INIT(free_fn)
Initialise a static reference counter.
Definition: refcnt.h:77
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition: vsprintf.c:382
size_t efi_cmdline_len
Length of EFI command line (in bytes)
Definition: efi_cmdline.c:48
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:67
struct refcnt refcnt
Reference count.
Definition: image.h:25