1 #include <linux/list.h>
13 #include "syslinux/adv.h"
14 #include "syslinux/boot.h"
16 #include <sys/module.h>
20 enum kernel_type type
;
23 static const struct file_ext file_extensions
[] = {
24 { ".com", IMAGE_TYPE_COMBOOT
},
25 { ".cbt", IMAGE_TYPE_COMBOOT
},
26 { ".c32", IMAGE_TYPE_COM32
},
27 { ".img", IMAGE_TYPE_FDIMAGE
},
28 { ".bss", IMAGE_TYPE_BSS
},
29 { ".bin", IMAGE_TYPE_BOOT
},
30 { ".bs", IMAGE_TYPE_BOOT
},
31 { ".0", IMAGE_TYPE_PXE
},
36 * Return a pointer to one byte after the last character of the
39 static inline const char *find_command(const char *str
)
44 while (*p
&& !my_isspace(*p
))
49 uint32_t parse_image_type(const char *kernel
)
51 const struct file_ext
*ext
;
55 /* Find the end of the command */
56 p
= find_command(kernel
);
59 for (ext
= file_extensions
; ext
->name
; ext
++) {
60 int elen
= strlen(ext
->name
);
62 if (!strncmp(kernel
+ len
- elen
, ext
->name
, elen
))
66 /* use IMAGE_TYPE_KERNEL as default */
67 return IMAGE_TYPE_KERNEL
;
71 * Returns the kernel name with file extension if one wasn't present.
73 static const char *get_extension(const char *kernel
)
75 const struct file_ext
*ext
;
79 /* Find the end of the command */
80 p
= find_command(kernel
);
83 for (ext
= file_extensions
; ext
->name
; ext
++) {
85 int elen
= strlen(ext
->name
);
88 str
= malloc(len
+ elen
+ 1);
90 strncpy(str
, kernel
, len
);
91 strncpy(str
+ len
, ext
->name
, elen
);
92 str
[len
+ elen
] = '\0';
104 static 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 memcpy(k
+ len
, ext
, elen
);
125 /* Copy the rest of the command line */
126 strcpy(k
+ len
+ elen
, p
);
128 k
[len
+ elen
+ strlen(p
)] = '\0';
134 * Attempt to load a kernel after deciding what type of image it is.
136 * We only return from this function if something went wrong loading
137 * the the kernel. If we return the caller should call enter_cmdline()
138 * so that the user can help us out.
140 void load_kernel(const char *command_line
)
142 struct menu_entry
*me
;
147 kernel
= strdup(command_line
);
151 /* Virtual kernel? */
152 me
= find_label(kernel
);
154 type
= parse_image_type(me
->cmdline
);
156 execute(me
->cmdline
, type
);
157 /* We shouldn't return */
164 /* Insert a null character to ignore any user-specified options */
166 char *p
= (char *)find_command(kernel
);
170 type
= parse_image_type(kernel
);
171 if (type
== IMAGE_TYPE_KERNEL
) {
175 * Automatically lookup the extension if one wasn't
176 * supplied by the user.
178 ext
= get_extension(kernel
);
182 k
= apply_extension(kernel
, ext
);
186 free((void *)kernel
);
189 type
= parse_image_type(kernel
);
193 execute(kernel
, type
);
194 free((void *)kernel
);
199 * If we fail to boot the kernel execute the "onerror" command
203 rsprintf(&cmdline
, "%s %s", onerror
, default_cmd
);
204 execute(cmdline
, IMAGE_TYPE_COM32
);
208 static void enter_cmdline(void)
212 /* Enter endless command line prompt, should support "exit" */
214 cmdline
= edit_cmdline("boot:", 1, NULL
, cat_help_file
);
217 /* return if user only press enter or we timed out */
218 if (!cmdline
|| cmdline
[0] == '\0')
221 load_kernel(cmdline
);
225 int main(int argc __unused
, char **argv __unused
)
230 char *config_argv
[2] = { NULL
, NULL
};
232 openconsole(&dev_rawcon_r
, &dev_ansiserial_w
);
235 config_argv
[0] = ConfigName
;
237 parse_configs(config_argv
);
239 adv
= syslinux_getadv(ADV_BOOTONCE
, &count
);
242 * We apparently have a boot-once set; clear it and
243 * then execute the boot-once.
249 cmdline
= dst
= malloc(count
+ 1);
251 printf("Failed to allocate memory for ADV\n");
255 for (i
= 0; i
< count
; i
++)
257 *dst
= '\0'; /* Null-terminate */
259 /* Clear the boot-once data from the ADV */
260 if (!syslinux_setadv(ADV_BOOTONCE
, 0, NULL
))
261 syslinux_adv_write();
263 load_kernel(cmdline
); /* Shouldn't return */
267 /* TODO: Check KbdFlags? */
272 cmdline
= default_cmd
;
277 if (defaultlevel
|| noescape
) {
279 load_kernel(cmdline
); /* Shouldn't return */
281 printf("No DEFAULT or UI configuration directive found!\n");
289 /* Only returns if the user pressed enter or input timed out */
292 cmdline
= ontimeoutlen
? ontimeout
: default_cmd
;