iPXE
runtime.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2011 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  * Command line and initrd passed to iPXE at runtime
29  *
30  */
31 
32 #include <stddef.h>
33 #include <stdint.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <ctype.h>
37 #include <errno.h>
38 #include <assert.h>
39 #include <ipxe/init.h>
40 #include <ipxe/image.h>
41 #include <ipxe/script.h>
42 #include <realmode.h>
43 
44 /** Command line physical address
45  *
46  * This can be set by the prefix.
47  */
49 #define cmdline_phys __use_data16 ( cmdline_phys )
50 
51 /** initrd physical address
52  *
53  * This can be set by the prefix.
54  */
56 #define initrd_phys __use_data16 ( initrd_phys )
57 
58 /** initrd length
59  *
60  * This can be set by the prefix.
61  */
63 #define initrd_len __use_data16 ( initrd_len )
64 
65 /** Internal copy of the command line */
66 static char *cmdline_copy;
67 
68 /** Free command line image */
69 static void cmdline_image_free ( struct refcnt *refcnt ) {
70  struct image *image = container_of ( refcnt, struct image, refcnt );
71 
72  DBGC ( image, "RUNTIME freeing command line\n" );
73  free_image ( refcnt );
74  free ( cmdline_copy );
75 }
76 
77 /** Embedded script representing the command line */
78 static struct image cmdline_image = {
80  .name = "<CMDLINE>",
81  .flags = ( IMAGE_STATIC | IMAGE_STATIC_NAME ),
82  .type = &script_image_type,
83 };
84 
85 /** Colour for debug messages */
86 #define colour &cmdline_image
87 
88 /**
89  * Strip unwanted cruft from command line
90  *
91  * @v cmdline Command line
92  * @v cruft Initial substring of cruft to strip
93  */
94 static void cmdline_strip ( char *cmdline, const char *cruft ) {
95  char *strip;
96  char *strip_end;
97 
98  /* Find unwanted cruft, if present */
99  if ( ! ( strip = strstr ( cmdline, cruft ) ) )
100  return;
101 
102  /* Strip unwanted cruft */
103  strip_end = strchr ( strip, ' ' );
104  if ( strip_end ) {
105  *strip_end = '\0';
106  DBGC ( colour, "RUNTIME stripping \"%s\"\n", strip );
107  strcpy ( strip, ( strip_end + 1 ) );
108  } else {
109  DBGC ( colour, "RUNTIME stripping \"%s\"\n", strip );
110  *strip = '\0';
111  }
112 }
113 
114 /**
115  * Initialise command line
116  *
117  * @ret rc Return status code
118  */
119 static int cmdline_init ( void ) {
120  char *cmdline;
121  int rc;
122 
123  /* Do nothing if no command line was specified */
124  if ( ! cmdline_phys ) {
125  DBGC ( colour, "RUNTIME found no command line\n" );
126  return 0;
127  }
128 
129  /* Allocate and copy command line */
130  cmdline_copy = strdup ( phys_to_virt ( cmdline_phys ) );
131  if ( ! cmdline_copy ) {
132  DBGC ( colour, "RUNTIME could not allocate command line\n" );
133  rc = -ENOMEM;
134  goto err_alloc_cmdline_copy;
135  }
137  DBGC ( colour, "RUNTIME found command line \"%s\" at %08x\n",
139 
140  /* Mark command line as consumed */
141  cmdline_phys = 0;
142 
143  /* Strip unwanted cruft from the command line */
144  cmdline_strip ( cmdline, "BOOT_IMAGE=" );
145  cmdline_strip ( cmdline, "initrd=" );
146  while ( isspace ( *cmdline ) )
147  cmdline++;
148  DBGC ( colour, "RUNTIME using command line \"%s\"\n", cmdline );
149 
150  /* Prepare and register image */
153  if ( cmdline_image.len ) {
154  if ( ( rc = register_image ( &cmdline_image ) ) != 0 ) {
155  DBGC ( colour, "RUNTIME could not register command "
156  "line: %s\n", strerror ( rc ) );
157  goto err_register_image;
158  }
159  }
160 
161  /* Drop our reference to the image */
163 
164  return 0;
165 
166  err_register_image:
168  err_alloc_cmdline_copy:
169  return rc;
170 }
171 
172 /**
173  * Initialise initrd
174  *
175  * @ret rc Return status code
176  */
177 static int initrd_init ( void ) {
178  struct image *image;
179 
180  /* Do nothing if no initrd was specified */
181  if ( ! initrd_phys ) {
182  DBGC ( colour, "RUNTIME found no initrd\n" );
183  return 0;
184  }
185  if ( ! initrd_len ) {
186  DBGC ( colour, "RUNTIME found empty initrd\n" );
187  return 0;
188  }
189  DBGC ( colour, "RUNTIME found initrd at [%x,%x)\n",
191 
192  /* Create initrd image */
193  image = image_memory ( "<INITRD>", phys_to_virt ( initrd_phys ),
194  initrd_len );
195  if ( ! image ) {
196  DBGC ( colour, "RUNTIME could not create initrd image\n" );
197  return -ENOMEM;
198  }
199 
200  /* Mark initrd as consumed */
201  initrd_phys = 0;
202 
203  return 0;
204 }
205 
206 /**
207  * Initialise command line and initrd
208  *
209  */
210 static void runtime_init ( void ) {
211  int rc;
212 
213  /* Initialise command line */
214  if ( ( rc = cmdline_init() ) != 0 ) {
215  /* No way to report failure */
216  return;
217  }
218 
219  /* Initialise initrd */
220  if ( ( rc = initrd_init() ) != 0 ) {
221  /* No way to report failure */
222  return;
223  }
224 }
225 
226 /** Command line and initrd initialisation function */
227 struct startup_fn runtime_startup_fn __startup_fn ( STARTUP_NORMAL ) = {
228  .name = "runtime",
229  .startup = runtime_init,
230 };
#define STARTUP_NORMAL
Normal startup.
Definition: init.h:64
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
Error codes.
const void * data
Read-only data.
Definition: image.h:50
uint32_t type
Operating system type.
Definition: ena.h:12
static int cmdline_init(void)
Initialise command line.
Definition: runtime.c:119
struct startup_fn runtime_startup_fn __startup_fn(STARTUP_NORMAL)
Command line and initrd initialisation function.
#define DBGC(...)
Definition: compiler.h:505
static int initrd_init(void)
Initialise initrd.
Definition: runtime.c:177
An executable image.
Definition: image.h:23
Character types.
const char * name
Definition: init.h:43
iPXE scripts
static void runtime_init(void)
Initialise command line and initrd.
Definition: runtime.c:210
A reference counter.
Definition: refcnt.h:26
A startup/shutdown function.
Definition: init.h:42
#define cmdline_phys
Definition: runtime.c:49
char * strstr(const char *haystack, const char *needle)
Find substring.
Definition: string.c:309
#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
Assertions.
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
Executable images.
char * strcpy(char *dest, const char *src)
Copy string.
Definition: string.c:346
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
char * strchr(const char *src, int character)
Find character within a string.
Definition: string.c:271
char * strdup(const char *src)
Duplicate string.
Definition: string.c:393
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
unsigned int uint32_t
Definition: stdint.h:12
static struct image cmdline_image
Embedded script representing the command line.
Definition: runtime.c:78
struct image * image_memory(const char *name, const void *data, size_t len)
Create registered image from block of memory.
Definition: image.c:608
static void cmdline_strip(char *cmdline, const char *cruft)
Strip unwanted cruft from command line.
Definition: runtime.c:94
#define IMAGE_STATIC_NAME
Image name is statically allocated.
Definition: image.h:91
#define REF_INIT(free_fn)
Initialise a static reference counter.
Definition: refcnt.h:77
static void cmdline_image_free(struct refcnt *refcnt)
Free command line image.
Definition: runtime.c:69
#define initrd_phys
Definition: runtime.c:56
uint32_t cmdline
Definition: multiboot.h:16
String functions.
static char * cmdline_copy
Internal copy of the command line.
Definition: runtime.c:66
uint32_t __bss16(cmdline_phys)
Command line physical address.
#define colour
Colour for debug messages.
Definition: runtime.c:86
#define initrd_len
Definition: runtime.c:63
struct refcnt refcnt
Reference count.
Definition: image.h:25