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
);
157 type
= parse_image_type(me
->cmdline
);
159 execute(me
->cmdline
, type
);
160 /* We shouldn't return */
167 /* Insert a null character to ignore any user-specified options */
169 char *p
= (char *)find_command(kernel
);
173 type
= parse_image_type(kernel
);
174 if (type
== IMAGE_TYPE_KERNEL
) {
178 * Automatically lookup the extension if one wasn't
179 * supplied by the user.
181 ext
= get_extension(kernel
);
185 k
= apply_extension(kernel
, ext
);
189 free((void *)kernel
);
192 type
= parse_image_type(kernel
);
196 execute(kernel
, type
);
197 free((void *)kernel
);
202 * If we fail to boot the kernel execute the "onerror" command
206 me
= find_label(onerror
);
208 rsprintf(&cmdline
, "%s %s", me
->cmdline
, default_cmd
);
210 rsprintf(&cmdline
, "%s %s", onerror
, default_cmd
);
212 type
= parse_image_type(cmdline
);
213 execute(cmdline
, type
);
218 * If this function returns you must call ldinux_enter_command() to
219 * preserve the 4.0x behaviour.
221 void ldlinux_auto_boot(void)
224 if (strlen(ConfigName
))
225 printf("No DEFAULT or UI configuration directive found!\n");
229 load_kernel(default_cmd
);
232 static void enter_cmdline(void)
236 /* Enter endless command line prompt, should support "exit" */
245 cmdline
= edit_cmdline("boot:", 1, NULL
, cat_help_file
, &to
);
248 /* return if user only press enter or we timed out */
249 if (!cmdline
|| cmdline
[0] == '\0') {
250 if (to
&& ontimeoutlen
)
251 load_kernel(ontimeout
);
255 load_kernel(cmdline
);
259 void ldlinux_enter_command(void)
265 * Undo the work we did in openconsole().
267 static void __destructor
close_console(void)
271 for (i
= 0; i
<= 2; i
++)
275 void ldlinux_console_init(void)
277 openconsole(&dev_stdcon_r
, &dev_ansiserial_w
);
280 __export
int main(int argc __unused
, char **argv __unused
)
285 char *config_argv
[2] = { NULL
, NULL
};
287 ldlinux_console_init();
290 config_argv
[0] = ConfigName
;
292 parse_configs(config_argv
);
294 __syslinux_set_serial_console_info();
296 adv
= syslinux_getadv(ADV_BOOTONCE
, &count
);
299 * We apparently have a boot-once set; clear it and
300 * then execute the boot-once.
306 cmdline
= dst
= malloc(count
+ 1);
308 printf("Failed to allocate memory for ADV\n");
309 ldlinux_enter_command();
312 for (i
= 0; i
< count
; i
++)
314 *dst
= '\0'; /* Null-terminate */
316 /* Clear the boot-once data from the ADV */
317 if (!syslinux_setadv(ADV_BOOTONCE
, 0, NULL
))
318 syslinux_adv_write();
320 load_kernel(cmdline
); /* Shouldn't return */
321 ldlinux_enter_command();
324 /* TODO: Check KbdFlags? */
328 if (defaultlevel
> 1)
331 ldlinux_enter_command();