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
24FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25FILE_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>
44
45/** EFI command line (may not be wNUL-terminated */
46const wchar_t *efi_cmdline;
47
48/** Length of EFI command line (in bytes) */
50
51/** Internal copy of the command line */
52static void *efi_cmdline_copy;
53
54/**
55 * Free command line image
56 *
57 * @v refcnt Reference count
58 */
59static 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" );
65}
66
67/** Embedded script representing the command line */
68static struct image efi_cmdline_image = {
69 .refcnt = REF_INIT ( efi_cmdline_free ),
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 */
83static int efi_cmdline_init ( void ) {
84 wchar_t *wcmdline;
85 char *cmdline;
86 size_t len;
87 int rc;
88
89 /* Do nothing if no command line was specified */
90 if ( ! efi_cmdline_len ) {
91 DBGC ( colour, "CMDLINE found no command line\n" );
92 return 0;
93 }
94
95 /* Create wNUL-terminated copy of command line */
96 len = ( efi_cmdline_len + 1 /* possible half CHAR16 */
97 + 2 /* wNUL */ );
99 if ( ! efi_cmdline_copy ) {
100 rc = -ENOMEM;
101 goto err_alloc;
102 }
104 wcmdline = efi_cmdline_copy;
105
106 /* Convert to ASCII in situ */
107 snprintf ( efi_cmdline_copy, len, "%ls", wcmdline );
109 wcmdline = NULL;
110 DBGC ( colour, "CMDLINE found command line \"%s\"\n", cmdline );
111
112 /* Mark command line as consumed */
113 efi_cmdline_len = 0;
114
115 /* Strip image name and surrounding whitespace */
116 while ( isspace ( *cmdline ) )
117 cmdline++;
118 while ( *cmdline && ( ! isspace ( *cmdline ) ) )
119 cmdline++;
120 while ( isspace ( *cmdline ) )
121 cmdline++;
122 DBGC ( colour, "CMDLINE using command line \"%s\"\n", cmdline );
123
124 /* Prepare and register image */
127 if ( efi_cmdline_image.len &&
128 ( ( rc = register_image ( &efi_cmdline_image ) ) != 0 ) ) {
129 DBGC ( colour, "CMDLINE could not register command line: %s\n",
130 strerror ( rc ) );
131 goto err_register_image;
132 }
133
134 /* Drop our reference to the image */
136
137 return 0;
138
139 err_register_image:
141 err_alloc:
142 return rc;
143}
144
145/**
146 * EFI command line startup function
147 *
148 */
149static void efi_cmdline_startup ( void ) {
150 int rc;
151
152 /* Initialise command line */
153 if ( ( rc = efi_cmdline_init() ) != 0 ) {
154 /* No way to report failure */
155 return;
156 }
157}
158
159/** Command line and initrd initialisation function */
160struct startup_fn efi_cmdline_startup_fn __startup_fn ( STARTUP_NORMAL ) = {
161 .name = "efi_cmdline",
162 .startup = efi_cmdline_startup,
163};
#define NULL
NULL pointer (VOID *).
Definition Base.h:321
#define colour
Colour for debug messages.
Definition acpi.c:42
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
int isspace(int character)
Check to see if character is a space.
Definition ctype.c:42
Character types.
ring len
Length.
Definition dwmac.h:226
static void efi_cmdline_free(struct refcnt *refcnt)
Free command line image.
Definition efi_cmdline.c:59
static int efi_cmdline_init(void)
Initialise EFI command line.
Definition efi_cmdline.c:83
size_t efi_cmdline_len
Length of EFI command line (in bytes).
Definition efi_cmdline.c:49
const wchar_t * efi_cmdline
EFI command line (may not be wNUL-terminated.
Definition efi_cmdline.c:46
static struct image efi_cmdline_image
Embedded script representing the command line.
Definition efi_cmdline.c:68
static void efi_cmdline_startup(void)
EFI command line startup function.
static void * efi_cmdline_copy
Internal copy of the command line.
Definition efi_cmdline.c:52
EFI command line.
uint32_t type
Operating system type.
Definition ena.h:1
Error codes.
#define DBGC(...)
Definition compiler.h:530
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:921
#define ENOMEM
Not enough space.
Definition errno.h:578
#define FILE_SECBOOT(_status)
Declare a file's UEFI Secure Boot permission status.
Definition compiler.h:951
#define STARTUP_NORMAL
Normal startup.
Definition init.h:65
void free_image(struct refcnt *refcnt)
Free executable image.
Definition image.c:89
int register_image(struct image *image)
Register executable image.
Definition image.c:336
Executable images.
#define IMAGE_STATIC_NAME
Image name is statically allocated.
Definition image.h:99
static void image_put(struct image *image)
Decrement reference count on an image.
Definition image.h:258
#define IMAGE_STATIC
Image is statically allocated.
Definition image.h:96
EFI API.
String functions.
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define __startup_fn(startup_order)
Declare a startup/shutdown function.
Definition init.h:53
Access to external ("user") memory.
void * zalloc(size_t size)
Allocate cleared memory.
Definition malloc.c:718
uint32_t cmdline
Definition multiboot.h:4
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
#define REF_INIT(free_fn)
Initialise a static reference counter.
Definition refcnt.h:78
iPXE scripts
#define container_of(ptr, type, field)
Get containing structure.
Definition stddef.h:36
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
size_t strlen(const char *src)
Get length of string.
Definition string.c:244
An executable image.
Definition image.h:24
A reference counter.
Definition refcnt.h:27
A startup/shutdown function.
Definition init.h:43
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition vsprintf.c:383