1 /* ----------------------------------------------------------------------- *
3 * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
8 * Boston MA 02110-1301, USA; either version 2 of the License, or
9 * (at your option) any later version; incorporated herein by reference.
11 * ----------------------------------------------------------------------- */
21 #include <sys/module.h>
26 #include "localboot.h"
29 #include <syslinux/bootrm.h>
30 #include <syslinux/movebits.h>
31 #include <syslinux/config.h>
32 #include <syslinux/boot.h>
34 const struct image_types image_boot_types
[] = {
35 { "localboot", IMAGE_TYPE_LOCALBOOT
},
36 { "kernel", IMAGE_TYPE_KERNEL
},
37 { "linux", IMAGE_TYPE_LINUX
},
38 { "boot", IMAGE_TYPE_BOOT
},
39 { "bss", IMAGE_TYPE_BSS
},
40 { "pxe", IMAGE_TYPE_PXE
},
41 { "fdimage", IMAGE_TYPE_FDIMAGE
},
42 { "com32", IMAGE_TYPE_COM32
},
43 { "config", IMAGE_TYPE_CONFIG
},
47 extern int create_args_and_load(char *);
49 __export
void execute(const char *cmdline
, uint32_t type
, bool sysappend
)
51 const char *kernel
, *args
;
56 memset(&ireg
, 0, sizeof ireg
);
58 if (strlen(cmdline
) >= MAX_CMDLINE_LEN
) {
59 printf("cmdline too long\n");
63 q
= malloc(MAX_CMDLINE_LEN
);
65 printf("%s(): Fail to malloc a buffer to exec %s\n",
72 while (*p
&& !my_isspace(*p
))
77 while (*p
&& my_isspace(*p
))
85 /* If we've seen some args, insert a space */
92 dprintf("kernel is %s, args = %s type = %d \n", kernel
, args
, type
);
94 if (kernel
[0] == '.') {
95 /* It might be a type specifier */
96 const struct image_types
*t
;
97 for (t
= image_boot_types
; t
->name
; t
++) {
98 if (!strcmp(kernel
+ 1, t
->name
)) {
100 * Strip the type specifier, apply the
101 * filename extension if COM32 and
105 if (t
->type
== IMAGE_TYPE_COM32
) {
106 p
= apply_extension(p
, ".c32");
111 execute(p
, t
->type
, sysappend
);
117 if (type
== IMAGE_TYPE_COM32
) {
119 * We may be called with the console in an unknown
120 * state, so initialise it.
122 ldlinux_console_init();
124 /* new entry for elf format c32 */
125 if (create_args_and_load((char *)cmdline
))
126 printf("Failed to load COM32 file %s\n", kernel
);
129 * The old COM32 module code would run the module then
130 * drop the user back at the command prompt,
131 * irrespective of how the COM32 module was loaded,
132 * e.g. from vesamenu.c32.
134 unload_modules_since(LDLINUX
);
136 /* Restore the console */
137 ldlinux_console_init();
139 ldlinux_enter_command();
140 } else if (type
== IMAGE_TYPE_CONFIG
) {
141 char *argv
[] = { LDLINUX
, NULL
, NULL
};
145 /* kernel contains the config file name */
146 config
= malloc(FILENAME_MAX
);
150 realpath(config
, kernel
, FILENAME_MAX
);
152 /* If we got anything on the command line, do a chdir */
154 mangle_name(config_cwd
, args
);
157 rv
= start_ldlinux(2, argv
);
158 printf("Failed to exec %s: %s\n", LDLINUX
, strerror(rv
));
159 } else if (type
== IMAGE_TYPE_LOCALBOOT
) {
160 local_boot(strtoul(kernel
, NULL
, 0));
161 } else if (type
== IMAGE_TYPE_PXE
|| type
== IMAGE_TYPE_BSS
||
162 type
== IMAGE_TYPE_BOOT
) {
163 chainboot_file(kernel
, type
);
165 /* Need add one item for kernel load, as we don't use
166 * the assembly runkernel.inc any more */
167 new_linux_kernel((char *)kernel
, (char *)args
);
171 free((void *)kernel
);
173 /* If this returns, something went bad; return to menu */