1 /* ----------------------------------------------------------------------- *
3 * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
4 * Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin
6 * Permission is hereby granted, free of charge, to any person
7 * obtaining a copy of this software and associated documentation
8 * files (the "Software"), to deal in the Software without
9 * restriction, including without limitation the rights to use,
10 * copy, modify, merge, publish, distribute, sublicense, and/or
11 * sell copies of the Software, and to permit persons to whom
12 * the Software is furnished to do so, subject to the following
15 * The above copyright notice and this permission notice shall
16 * be included in all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
20 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25 * OTHER DEALINGS IN THE SOFTWARE.
27 * ----------------------------------------------------------------------- */
32 * Module to load a multiboot kernel
37 struct multiboot_info mbinfo
;
38 struct syslinux_pm_regs regs
;
39 struct my_options opt
, set
;
47 static int map_modules(struct module_data
*modules
, int nmodules
)
49 struct mod_list
*mod_list
;
51 size_t list_size
= nmodules
* sizeof *mod_list
;
54 mod_list
= malloc(list_size
);
56 printf("Failed to allocate module list\n");
60 map_list
= map_data(mod_list
, list_size
, 16, 0);
62 printf("Cannot map module list\n");
66 for (i
= 0; i
< nmodules
; i
++) {
70 dprintf("Module %d cmdline: \"%s\"\n", i
, modules
[i
].cmdline
);
72 cmd_map
= map_string(modules
[i
].cmdline
);
74 mod_map
= map_data(modules
[i
].data
, modules
[i
].len
, 4096, MAP_HIGH
);
76 printf("Failed to map module (memory fragmentation issue?)\n");
79 mod_list
[i
].mod_start
= mod_map
;
80 mod_list
[i
].mod_end
= mod_map
+ modules
[i
].len
;
81 mod_list
[i
].cmdline
= cmd_map
;
85 mbinfo
.flags
|= MB_INFO_MODS
;
86 mbinfo
.mods_count
= nmodules
;
87 mbinfo
.mods_addr
= map_list
;
91 static int get_modules(char **argv
, struct module_data
**mdp
)
94 struct module_data
*mp
;
98 const char module_separator
[] = "---";
100 for (argp
= argv
; *argp
; argp
++) {
101 if (!strcmp(*argp
, module_separator
))
105 *mdp
= mp
= malloc(module_count
* sizeof(struct module_data
));
107 error("Out of memory!\n");
113 /* Note: it seems Grub transparently decompresses all compressed files,
114 not just the primary kernel. */
115 printf("Loading %s... ", *argp
);
116 rv
= zloadfile(*argp
, &mp
->data
, &mp
->len
);
125 * Note: Grub includes the kernel filename in the command line, so we
126 * want to match that behavior.
129 for (argx
= argp
; *argx
&& strcmp(*argx
, module_separator
); argx
++)
130 arglen
+= strlen(*argx
) + 1;
133 mp
->cmdline
= strdup("");
136 mp
->cmdline
= p
= malloc(arglen
);
137 for (; *argp
&& strcmp(*argp
, module_separator
); argp
++) {
138 p
= stpcpy(p
, *argp
);
145 argp
++; /* Advance past module_separator */
151 int main(int argc
, char *argv
[])
154 struct module_data
*modules
;
155 struct multiboot_header
*mbh
;
156 bool keeppxe
= false;
158 openconsole(&dev_null_r
, &dev_stdcon_w
);
160 (void)argc
; /* Unused */
165 const char *p
= *argv
;
167 if (!memcmp(p
, "-no", 3)) {
172 if (!strcmp(p
, "-solaris")) {
175 } else if (!strcmp(p
, "-aout")) {
185 ("Usage: mboot.c32 [opts] mboot_file args... [--- module args...]...\n"
187 " -solaris Enable Solaris DHCP information passing\n"
188 " -aout Use the \"a.out kludge\" if enabled, even for ELF\n"
189 " This matches the Multiboot spec, but differs from Grub\n");
194 nmodules
= get_modules(argv
, &modules
);
196 error("No files found!\n");
197 return 1; /* Failure */
201 return 1; /* Failed to allocate initial map */
204 * Map the primary image. This should be done before mapping anything
205 * else, since it will have fixed address requirements.
207 mbh
= map_image(modules
[0].data
, modules
[0].len
);
211 /* Map the mbinfo structure */
212 regs
.ebx
= map_data(&mbinfo
, sizeof mbinfo
, 4, 0);
214 error("Failed to map Multiboot info structure!\n");
218 /* Map the primary command line */
219 if (modules
[0].cmdline
) {
220 mbinfo
.cmdline
= map_string(modules
[0].cmdline
);
221 dprintf("Main cmdline: \"%s\"\n", modules
[0].cmdline
);
223 mbinfo
.flags
|= MB_INFO_CMDLINE
;
226 /* Map auxilliary images */
228 if (map_modules(modules
+ 1, nmodules
- 1))
232 /* Add auxilliary information */
235 mboot_syslinux_info();
238 mboot_solaris_dhcp_hack();
240 /* Set the graphics mode if requested */
241 set_graphics_mode(mbh
, &mbinfo
);
244 mboot_run(keeppxe
? 3 : 0);
245 error("mboot.c32: boot failed\n");