]> glassweightruler.freedombox.rocks Git - Ventoy.git/blob - IPXE/ipxe-3fe683e/src/arch/x86/core/runtime.c
Add German language (#57)
[Ventoy.git] / IPXE / ipxe-3fe683e / src / arch / x86 / core / runtime.c
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 <ctype.h>
36 #include <errno.h>
37 #include <assert.h>
38 #include <ipxe/init.h>
39 #include <ipxe/image.h>
40 #include <ipxe/script.h>
41 #include <ipxe/umalloc.h>
42 #include <realmode.h>
43 #include <ventoy.h>
44
45 /** Command line physical address
46 *
47 * This can be set by the prefix.
48 */
49 uint32_t __bss16 ( cmdline_phys );
50 #define cmdline_phys __use_data16 ( cmdline_phys )
51
52 /** initrd physical address
53 *
54 * This can be set by the prefix.
55 */
56 uint32_t __bss16 ( initrd_phys );
57 #define initrd_phys __use_data16 ( initrd_phys )
58
59 /** initrd length
60 *
61 * This can be set by the prefix.
62 */
63 uint32_t __bss16 ( initrd_len );
64 #define initrd_len __use_data16 ( initrd_len )
65
66 /** Internal copy of the command line */
67 static char *cmdline_copy;
68
69 /** Free command line image */
70 static void cmdline_image_free ( struct refcnt *refcnt ) {
71 struct image *image = container_of ( refcnt, struct image, refcnt );
72
73 DBGC ( image, "RUNTIME freeing command line\n" );
74 free ( cmdline_copy );
75 }
76
77 /** Embedded script representing the command line */
78 static struct image cmdline_image = {
79 .refcnt = REF_INIT ( cmdline_image_free ),
80 .name = "<CMDLINE>",
81 .type = &script_image_type,
82 };
83
84 /** Colour for debug messages */
85 #define colour &cmdline_image
86
87 /**
88 * Strip unwanted cruft from command line
89 *
90 * @v cmdline Command line
91 * @v cruft Initial substring of cruft to strip
92 */
93 static void cmdline_strip ( char *cmdline, const char *cruft ) {
94 char *strip;
95 char *strip_end;
96
97 /* Find unwanted cruft, if present */
98 if ( ! ( strip = strstr ( cmdline, cruft ) ) )
99 return;
100
101 /* Strip unwanted cruft */
102 strip_end = strchr ( strip, ' ' );
103 if ( strip_end ) {
104 *strip_end = '\0';
105 DBGC ( colour, "RUNTIME stripping \"%s\"\n", strip );
106 strcpy ( strip, ( strip_end + 1 ) );
107 } else {
108 DBGC ( colour, "RUNTIME stripping \"%s\"\n", strip );
109 *strip = '\0';
110 }
111 }
112
113 /**
114 * Initialise command line
115 *
116 * @ret rc Return status code
117 */
118 static int cmdline_init ( void ) {
119 userptr_t cmdline_user;
120 char *cmdline;
121 size_t len;
122 int rc;
123
124 /* Do nothing if no command line was specified */
125 if ( ! cmdline_phys ) {
126 DBGC ( colour, "RUNTIME found no command line\n" );
127 return 0;
128 }
129 cmdline_user = phys_to_user ( cmdline_phys );
130 len = ( strlen_user ( cmdline_user, 0 ) + 1 /* NUL */ );
131
132 /* Allocate and copy command line */
133 cmdline_copy = malloc ( len );
134 if ( ! cmdline_copy ) {
135 DBGC ( colour, "RUNTIME could not allocate %zd bytes for "
136 "command line\n", len );
137 rc = -ENOMEM;
138 goto err_alloc_cmdline_copy;
139 }
140 cmdline = cmdline_copy;
141 copy_from_user ( cmdline, cmdline_user, 0, len );
142 DBGC ( colour, "RUNTIME found command line \"%s\" at %08x\n",
143 cmdline, cmdline_phys );
144
145 /* Mark command line as consumed */
146 cmdline_phys = 0;
147
148 /* Strip unwanted cruft from the command line */
149 cmdline_strip ( cmdline, "BOOT_IMAGE=" );
150 cmdline_strip ( cmdline, "initrd=" );
151 while ( isspace ( *cmdline ) )
152 cmdline++;
153 DBGC ( colour, "RUNTIME using command line \"%s\"\n", cmdline );
154
155 /* Prepare and register image */
156 cmdline_image.data = virt_to_user ( cmdline );
157 cmdline_image.len = strlen ( cmdline );
158 if ( cmdline_image.len ) {
159 if ( ( rc = register_image ( &cmdline_image ) ) != 0 ) {
160 DBGC ( colour, "RUNTIME could not register command "
161 "line: %s\n", strerror ( rc ) );
162 goto err_register_image;
163 }
164 }
165
166 /* Drop our reference to the image */
167 image_put ( &cmdline_image );
168
169 return 0;
170
171 err_register_image:
172 image_put ( &cmdline_image );
173 err_alloc_cmdline_copy:
174 return rc;
175 }
176
177 /**
178 * Initialise initrd
179 *
180 * @ret rc Return status code
181 */
182 static int initrd_init ( void ) {
183 struct image *image;
184 int rc;
185
186 /* Do nothing if no initrd was specified */
187 if ( ! initrd_phys ) {
188 DBGC ( colour, "RUNTIME found no initrd\n" );
189 return 0;
190 }
191 if ( ! initrd_len ) {
192 DBGC ( colour, "RUNTIME found empty initrd\n" );
193 return 0;
194 }
195 DBGC ( colour, "RUNTIME found initrd at [%x,%x)\n",
196 initrd_phys, ( initrd_phys + initrd_len ) );
197
198 /* Allocate image */
199 image = alloc_image ( NULL );
200 if ( ! image ) {
201 DBGC ( colour, "RUNTIME could not allocate image for "
202 "initrd\n" );
203 rc = -ENOMEM;
204 goto err_alloc_image;
205 }
206 if ( ( rc = image_set_name ( image, "<INITRD>" ) ) != 0 ) {
207 DBGC ( colour, "RUNTIME could not set image name: %s\n",
208 strerror ( rc ) );
209 goto err_set_name;
210 }
211
212 /* Allocate and copy initrd content */
213 image->data = umalloc ( initrd_len );
214 if ( ! image->data ) {
215 DBGC ( colour, "RUNTIME could not allocate %d bytes for "
216 "initrd\n", initrd_len );
217 rc = -ENOMEM;
218 goto err_umalloc;
219 }
220 image->len = initrd_len;
221 memcpy_user ( image->data, 0, phys_to_user ( initrd_phys ), 0,
222 initrd_len );
223
224 g_initrd_addr = (void *)image->data;
225 g_initrd_len = image->len;
226 g_cmdline_copy = cmdline_copy;
227
228
229 /* Mark initrd as consumed */
230 initrd_phys = 0;
231
232 /* Register image */
233 if ( ( rc = register_image ( image ) ) != 0 ) {
234 DBGC ( colour, "RUNTIME could not register initrd: %s\n",
235 strerror ( rc ) );
236 goto err_register_image;
237 }
238
239 /* Drop our reference to the image */
240 image_put ( image );
241
242 return 0;
243
244 err_register_image:
245 err_umalloc:
246 err_set_name:
247 image_put ( image );
248 err_alloc_image:
249 return rc;
250 }
251
252 /**
253 * Initialise command line and initrd
254 *
255 */
256 static void runtime_init ( void ) {
257 int rc;
258
259 /* Initialise command line */
260 if ( ( rc = cmdline_init() ) != 0 ) {
261 /* No way to report failure */
262 return;
263 }
264
265 /* Initialise initrd */
266 if ( ( rc = initrd_init() ) != 0 ) {
267 /* No way to report failure */
268 return;
269 }
270 }
271
272 /** Command line and initrd initialisation function */
273 struct startup_fn runtime_startup_fn __startup_fn ( STARTUP_NORMAL ) = {
274 .name = "runtime",
275 .startup = runtime_init,
276 };