1 #include <linux/list.h>
13 #include "syslinux/adv.h"
14 #include "syslinux/boot.h"
15 #include "syslinux/config.h"
17 #include <sys/module.h>
21 enum kernel_type type
;
24 static const struct file_ext file_extensions
[] = {
25 { ".c32", IMAGE_TYPE_COM32
},
26 { ".img", IMAGE_TYPE_FDIMAGE
},
27 { ".bss", IMAGE_TYPE_BSS
},
28 { ".bin", IMAGE_TYPE_BOOT
},
29 { ".bs", IMAGE_TYPE_BOOT
},
30 { ".0", IMAGE_TYPE_PXE
},
35 * Return a pointer to one byte after the last character of the
38 static inline const char *find_command(const char *str
)
43 while (*p
&& !my_isspace(*p
))
48 __export
uint32_t parse_image_type(const char *kernel
)
50 const struct file_ext
*ext
;
54 /* Find the end of the command */
55 p
= find_command(kernel
);
58 for (ext
= file_extensions
; ext
->name
; ext
++) {
59 int elen
= strlen(ext
->name
);
61 if (!strncmp(kernel
+ len
- elen
, ext
->name
, elen
))
65 /* use IMAGE_TYPE_KERNEL as default */
66 return IMAGE_TYPE_KERNEL
;
70 * Returns the kernel name with file extension if one wasn't present.
72 static const char *get_extension(const char *kernel
)
74 const struct file_ext
*ext
;
78 /* Find the end of the command */
79 p
= find_command(kernel
);
82 for (ext
= file_extensions
; ext
->name
; ext
++) {
84 int elen
= strlen(ext
->name
);
87 str
= malloc(len
+ elen
+ 1);
89 strncpy(str
, kernel
, len
);
90 strncpy(str
+ len
, ext
->name
, elen
);
91 str
[len
+ elen
] = '\0';
104 const char *apply_extension(const char *kernel
, const char *ext
)
108 int len
= strlen(kernel
);
109 int elen
= strlen(ext
);
111 k
= malloc(len
+ elen
+ 1);
115 p
= find_command(kernel
);
119 /* Copy just the kernel name */
120 memcpy(k
, kernel
, len
);
122 /* Append the extension */
123 if (strncmp(p
- elen
, ext
, elen
)) {
124 memcpy(k
+ len
, ext
, elen
);
128 /* Copy the rest of the command line */
131 k
[len
+ strlen(p
)] = '\0';
137 * Attempt to load a kernel after deciding what type of image it is.
139 * We only return from this function if something went wrong loading
140 * the the kernel. If we return the caller should call enter_cmdline()
141 * so that the user can help us out.
143 __export
void load_kernel(const char *command_line
)
145 struct menu_entry
*me
;
150 kernel
= strdup(command_line
);
154 /* Virtual kernel? */
155 me
= find_label(kernel
);
159 size_t len
= strlen(me
->cmdline
) + 1;
161 /* Find the end of the command */
162 args
= find_command(kernel
);
163 while(*args
&& my_isspace(*args
))
167 len
+= strlen(args
) + 1; /* +1 for space (' ') */
174 snprintf(cmd
, len
, "%s %s", me
->cmdline
, args
);
176 strncpy(cmd
, me
->cmdline
, len
);
178 type
= parse_image_type(cmd
);
179 execute(cmd
, type
, false);
180 /* We shouldn't return */
187 /* Insert a null character to ignore any user-specified options */
189 char *p
= (char *)find_command(kernel
);
193 type
= parse_image_type(kernel
);
194 if (type
== IMAGE_TYPE_KERNEL
) {
198 * Automatically lookup the extension if one wasn't
199 * supplied by the user.
201 ext
= get_extension(kernel
);
205 k
= apply_extension(kernel
, ext
);
209 free((void *)kernel
);
212 type
= parse_image_type(kernel
);
216 execute(kernel
, type
, true);
217 free((void *)kernel
);
222 * If we fail to boot the kernel execute the "onerror" command
226 me
= find_label(onerror
);
228 rsprintf(&cmdline
, "%s %s", me
->cmdline
, default_cmd
);
230 rsprintf(&cmdline
, "%s %s", onerror
, default_cmd
);
232 type
= parse_image_type(cmdline
);
233 execute(cmdline
, type
, true);
238 * If this function returns you must call ldinux_enter_command() to
239 * preserve the 4.0x behaviour.
241 void ldlinux_auto_boot(void)
244 if (strlen(ConfigName
))
245 printf("No DEFAULT or UI configuration directive found!\n");
249 load_kernel(default_cmd
);
252 static void enter_cmdline(void)
256 /* Enter endless command line prompt, should support "exit" */
265 cmdline
= edit_cmdline("boot:", 1, NULL
, cat_help_file
, &to
);
268 /* return if user only press enter or we timed out */
269 if (!cmdline
|| cmdline
[0] == '\0') {
270 if (to
&& ontimeoutlen
)
271 load_kernel(ontimeout
);
275 load_kernel(cmdline
);
279 void ldlinux_enter_command(void)
285 * Undo the work we did in openconsole().
287 static void __destructor
close_console(void)
291 for (i
= 0; i
<= 2; i
++)
295 void ldlinux_console_init(void)
297 openconsole(&dev_stdcon_r
, &dev_ansiserial_w
);
300 __export
int main(int argc __unused
, char **argv
)
306 ldlinux_console_init();
308 parse_configs(&argv
[1]);
310 __syslinux_set_serial_console_info();
312 adv
= syslinux_getadv(ADV_BOOTONCE
, &count
);
315 * We apparently have a boot-once set; clear it and
316 * then execute the boot-once.
322 cmdline
= dst
= malloc(count
+ 1);
324 printf("Failed to allocate memory for ADV\n");
325 ldlinux_enter_command();
328 for (i
= 0; i
< count
; i
++)
330 *dst
= '\0'; /* Null-terminate */
332 /* Clear the boot-once data from the ADV */
333 if (!syslinux_setadv(ADV_BOOTONCE
, 0, NULL
))
334 syslinux_adv_write();
336 load_kernel(cmdline
); /* Shouldn't return */
337 ldlinux_enter_command();
340 /* TODO: Check KbdFlags? */
344 if (defaultlevel
> 1)
347 ldlinux_enter_command();