|
@@ -23,6 +23,7 @@
|
23
|
23
|
*
|
24
|
24
|
*/
|
25
|
25
|
|
|
26
|
+#include <stdio.h>
|
26
|
27
|
#include <errno.h>
|
27
|
28
|
#include <assert.h>
|
28
|
29
|
#include <realmode.h>
|
|
@@ -51,6 +52,16 @@ struct image_type multiboot_image_type __image_type ( PROBE_MULTIBOOT );
|
51
|
52
|
*/
|
52
|
53
|
#define MAX_MODULES 8
|
53
|
54
|
|
|
55
|
+/**
|
|
56
|
+ * Maximum combined length of command lines
|
|
57
|
+ *
|
|
58
|
+ * Again; sorry. Some broken OSes zero out any non-base memory that
|
|
59
|
+ * isn't part of the loaded module set, so we can't just use
|
|
60
|
+ * virt_to_phys(cmdline) to point to the command lines, even though
|
|
61
|
+ * this would comply with the Multiboot spec.
|
|
62
|
+ */
|
|
63
|
+#define MB_MAX_CMDLINE 512
|
|
64
|
+
|
54
|
65
|
/** Multiboot flags that we support */
|
55
|
66
|
#define MB_SUPPORTED_FLAGS ( MB_FLAG_PGALIGN | MB_FLAG_MEMMAP | \
|
56
|
67
|
MB_FLAG_VIDMODE | MB_FLAG_RAW )
|
|
@@ -77,6 +88,13 @@ struct multiboot_header_info {
|
77
|
88
|
size_t offset;
|
78
|
89
|
};
|
79
|
90
|
|
|
91
|
+/** Multiboot module command lines */
|
|
92
|
+static char __bss16_array ( mb_cmdlines, [MB_MAX_CMDLINE] );
|
|
93
|
+#define mb_cmdlines __use_data16 ( mb_cmdlines )
|
|
94
|
+
|
|
95
|
+/** Offset within module command lines */
|
|
96
|
+static unsigned int mb_cmdline_offset;
|
|
97
|
+
|
80
|
98
|
/**
|
81
|
99
|
* Build multiboot memory map
|
82
|
100
|
*
|
|
@@ -118,6 +136,32 @@ static void multiboot_build_memmap ( struct image *image,
|
118
|
136
|
}
|
119
|
137
|
}
|
120
|
138
|
|
|
139
|
+/**
|
|
140
|
+ * Add command line in base memory
|
|
141
|
+ *
|
|
142
|
+ * @v cmdline Command line
|
|
143
|
+ * @ret physaddr Physical address of command line
|
|
144
|
+ */
|
|
145
|
+physaddr_t multiboot_add_cmdline ( const char *cmdline ) {
|
|
146
|
+ char *mb_cmdline;
|
|
147
|
+
|
|
148
|
+ if ( ! cmdline )
|
|
149
|
+ cmdline = "";
|
|
150
|
+
|
|
151
|
+ /* Copy command line to base memory buffer */
|
|
152
|
+ mb_cmdline = ( mb_cmdlines + mb_cmdline_offset );
|
|
153
|
+ mb_cmdline_offset +=
|
|
154
|
+ ( snprintf ( mb_cmdline,
|
|
155
|
+ ( sizeof ( mb_cmdlines ) - mb_cmdline_offset ),
|
|
156
|
+ "%s", cmdline ) + 1 );
|
|
157
|
+
|
|
158
|
+ /* Truncate to terminating NUL in buffer if necessary */
|
|
159
|
+ if ( mb_cmdline_offset > sizeof ( mb_cmdlines ) )
|
|
160
|
+ mb_cmdline_offset = ( sizeof ( mb_cmdlines ) - 1 );
|
|
161
|
+
|
|
162
|
+ return virt_to_phys ( mb_cmdline );
|
|
163
|
+}
|
|
164
|
+
|
121
|
165
|
/**
|
122
|
166
|
* Build multiboot module list
|
123
|
167
|
*
|
|
@@ -135,7 +179,6 @@ multiboot_build_module_list ( struct image *image,
|
135
|
179
|
unsigned int insert;
|
136
|
180
|
physaddr_t start;
|
137
|
181
|
physaddr_t end;
|
138
|
|
- char *cmdline;
|
139
|
182
|
unsigned int i;
|
140
|
183
|
|
141
|
184
|
/* Add each image as a multiboot module */
|
|
@@ -151,44 +194,35 @@ multiboot_build_module_list ( struct image *image,
|
151
|
194
|
if ( module_image == image )
|
152
|
195
|
continue;
|
153
|
196
|
|
154
|
|
- /* If we don't have a data structure to populate, just count */
|
155
|
|
- if ( modules ) {
|
156
|
|
-
|
157
|
|
- /* At least some OSes expect the multiboot
|
158
|
|
- * modules to be in ascending order, so we
|
159
|
|
- * have to support it.
|
160
|
|
- */
|
161
|
|
- start = user_to_phys ( module_image->data, 0 );
|
162
|
|
- end = user_to_phys ( module_image->data,
|
163
|
|
- module_image->len );
|
164
|
|
- for ( insert = 0 ; insert < count ; insert++ ) {
|
165
|
|
- if ( start < modules[insert].mod_start )
|
166
|
|
- break;
|
167
|
|
- }
|
168
|
|
- module = &modules[insert];
|
169
|
|
- memmove ( ( module + 1 ), module,
|
170
|
|
- ( ( count - insert ) * sizeof ( *module ) ));
|
171
|
|
- module->mod_start = start;
|
172
|
|
- module->mod_end = end;
|
173
|
|
- cmdline = ( module_image->cmdline ?
|
174
|
|
- module_image->cmdline : "" );
|
175
|
|
- module->string = virt_to_phys ( cmdline );
|
176
|
|
- module->reserved = 0;
|
177
|
|
-
|
178
|
|
- /* We promise to page-align modules */
|
179
|
|
- assert ( ( module->mod_start & 0xfff ) == 0 );
|
|
197
|
+ /* At least some OSes expect the multiboot modules to
|
|
198
|
+ * be in ascending order, so we have to support it.
|
|
199
|
+ */
|
|
200
|
+ start = user_to_phys ( module_image->data, 0 );
|
|
201
|
+ end = user_to_phys ( module_image->data, module_image->len );
|
|
202
|
+ for ( insert = 0 ; insert < count ; insert++ ) {
|
|
203
|
+ if ( start < modules[insert].mod_start )
|
|
204
|
+ break;
|
180
|
205
|
}
|
|
206
|
+ module = &modules[insert];
|
|
207
|
+ memmove ( ( module + 1 ), module,
|
|
208
|
+ ( ( count - insert ) * sizeof ( *module ) ) );
|
|
209
|
+ module->mod_start = start;
|
|
210
|
+ module->mod_end = end;
|
|
211
|
+ module->string =
|
|
212
|
+ multiboot_add_cmdline ( module_image->cmdline );
|
|
213
|
+ module->reserved = 0;
|
|
214
|
+
|
|
215
|
+ /* We promise to page-align modules */
|
|
216
|
+ assert ( ( module->mod_start & 0xfff ) == 0 );
|
181
|
217
|
|
182
|
218
|
count++;
|
183
|
219
|
}
|
184
|
220
|
|
185
|
221
|
/* Dump module configuration */
|
186
|
|
- if ( modules ) {
|
187
|
|
- for ( i = 0 ; i < count ; i++ ) {
|
188
|
|
- DBGC ( image, "MULTIBOOT %p module %d is [%lx,%lx)\n",
|
189
|
|
- image, i, modules[i].mod_start,
|
190
|
|
- modules[i].mod_end );
|
191
|
|
- }
|
|
222
|
+ for ( i = 0 ; i < count ; i++ ) {
|
|
223
|
+ DBGC ( image, "MULTIBOOT %p module %d is [%lx,%lx)\n",
|
|
224
|
+ image, i, modules[i].mod_start,
|
|
225
|
+ modules[i].mod_end );
|
192
|
226
|
}
|
193
|
227
|
|
194
|
228
|
return count;
|
|
@@ -225,7 +259,6 @@ static struct multiboot_module __bss16_array ( mbmodules, [MAX_MODULES] );
|
225
|
259
|
*/
|
226
|
260
|
static int multiboot_exec ( struct image *image ) {
|
227
|
261
|
physaddr_t entry = image->priv.phys;
|
228
|
|
- char *cmdline;
|
229
|
262
|
|
230
|
263
|
/* Populate multiboot information structure */
|
231
|
264
|
memset ( &mbinfo, 0, sizeof ( mbinfo ) );
|
|
@@ -233,8 +266,8 @@ static int multiboot_exec ( struct image *image ) {
|
233
|
266
|
MBI_FLAG_CMDLINE | MBI_FLAG_MODS );
|
234
|
267
|
multiboot_build_memmap ( image, &mbinfo, mbmemmap,
|
235
|
268
|
( sizeof(mbmemmap) / sizeof(mbmemmap[0]) ) );
|
236
|
|
- cmdline = ( image->cmdline ? image->cmdline : "" );
|
237
|
|
- mbinfo.cmdline = virt_to_phys ( cmdline );
|
|
269
|
+ mb_cmdline_offset = 0;
|
|
270
|
+ mbinfo.cmdline = multiboot_add_cmdline ( image->cmdline );
|
238
|
271
|
mbinfo.mods_count = multiboot_build_module_list ( image, mbmodules,
|
239
|
272
|
( sizeof(mbmodules) / sizeof(mbmodules[0]) ) );
|
240
|
273
|
mbinfo.mods_addr = virt_to_phys ( mbmodules );
|