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 <ctype.h>
35 #include <errno.h>
36 #include <ipxe/init.h>
37 #include <ipxe/image.h>
38 #include <ipxe/script.h>
39 #include <ipxe/efi/efi.h>
40 #include <ipxe/efi/efi_cmdline.h>
41 
42 /** EFI command line (may not be wNUL-terminated */
43 const wchar_t *efi_cmdline;
44 
45 /** Length of EFI command line (in bytes) */
47 
48 /** Internal copy of the command line */
49 static char *efi_cmdline_copy;
50 
51 /**
52  * Free command line image
53  *
54  * @v refcnt Reference count
55  */
56 static void efi_cmdline_free ( struct refcnt *refcnt ) {
57  struct image *image = container_of ( refcnt, struct image, refcnt );
58 
59  DBGC ( image, "CMDLINE freeing command line\n" );
61 }
62 
63 /** Embedded script representing the command line */
64 static struct image efi_cmdline_image = {
66  .name = "<CMDLINE>",
67  .type = &script_image_type,
68 };
69 
70 /** Colour for debug messages */
71 #define colour &efi_cmdline_image
72 
73 /**
74  * Initialise EFI command line
75  *
76  * @ret rc Return status code
77  */
78 static int efi_cmdline_init ( void ) {
79  char *cmdline;
80  size_t len;
81  int rc;
82 
83  /* Do nothing if no command line was specified */
84  if ( ! efi_cmdline_len ) {
85  DBGC ( colour, "CMDLINE found no command line\n" );
86  return 0;
87  }
88 
89  /* Allocate ASCII copy of command line */
90  len = ( ( efi_cmdline_len / sizeof ( efi_cmdline[0] ) ) + 1 /* NUL */ );
92  if ( ! efi_cmdline_copy ) {
93  rc = -ENOMEM;
94  goto err_alloc;
95  }
97  snprintf ( cmdline, len, "%ls", efi_cmdline );
98  DBGC ( colour, "CMDLINE found command line \"%s\"\n", cmdline );
99 
100  /* Mark command line as consumed */
101  efi_cmdline_len = 0;
102 
103  /* Strip image name and surrounding whitespace */
104  while ( isspace ( *cmdline ) )
105  cmdline++;
106  while ( *cmdline && ( ! isspace ( *cmdline ) ) )
107  cmdline++;
108  while ( isspace ( *cmdline ) )
109  cmdline++;
110  DBGC ( colour, "CMDLINE using command line \"%s\"\n", cmdline );
111 
112  /* Prepare and register image */
115  if ( efi_cmdline_image.len &&
116  ( ( rc = register_image ( &efi_cmdline_image ) ) != 0 ) ) {
117  DBGC ( colour, "CMDLINE could not register command line: %s\n",
118  strerror ( rc ) );
119  goto err_register_image;
120  }
121 
122  /* Drop our reference to the image */
124 
125  return 0;
126 
127  err_register_image:
129  err_alloc:
130  return rc;
131 }
132 
133 /**
134  * EFI command line startup function
135  *
136  */
137 static void efi_cmdline_startup ( void ) {
138  int rc;
139 
140  /* Initialise command line */
141  if ( ( rc = efi_cmdline_init() ) != 0 ) {
142  /* No way to report failure */
143  return;
144  }
145 }
146 
147 /** Command line and initrd initialisation function */
148 struct startup_fn efi_cmdline_startup_fn __startup_fn ( STARTUP_NORMAL ) = {
149  .name = "efi_cmdline",
150  .startup = efi_cmdline_startup,
151 };
#define STARTUP_NORMAL
Normal startup.
Definition: init.h:63
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
userptr_t data
Raw file image.
Definition: image.h:41
const wchar_t * efi_cmdline
EFI command line (may not be wNUL-terminated.
Definition: efi_cmdline.c:43
Error codes.
#define DBGC(...)
Definition: compiler.h:505
static void efi_cmdline_startup(void)
EFI command line startup function.
Definition: efi_cmdline.c:137
An executable image.
Definition: image.h:24
Character types.
const char * name
Definition: init.h:42
iPXE scripts
A reference counter.
Definition: refcnt.h:26
A startup/shutdown function.
Definition: init.h:41
#define ENOMEM
Not enough space.
Definition: errno.h:534
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
Executable images.
static void efi_cmdline_free(struct refcnt *refcnt)
Free command line image.
Definition: efi_cmdline.c:56
static int efi_cmdline_init(void)
Initialise EFI command line.
Definition: efi_cmdline.c:78
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
int register_image(struct image *image)
Register executable image.
Definition: image.c:264
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:43
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:228
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:583
#define colour
Colour for debug messages.
Definition: efi_cmdline.c:71
static char * efi_cmdline_copy
Internal copy of the command line.
Definition: efi_cmdline.c:49
EFI API.
uint32_t len
Length.
Definition: ena.h:14
EFI command line.
userptr_t virt_to_user(volatile const void *addr)
Convert virtual address to user pointer.
#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:46
uint32_t cmdline
Definition: multiboot.h:16
static struct image efi_cmdline_image
Embedded script representing the command line.
Definition: efi_cmdline.c:64
struct refcnt refcnt
Reference count.
Definition: image.h:26