execute(): move chainbooting code to its own file
[syslinux/sherbszt.git] / com32 / elflink / ldlinux / execute.c
blob97e5116859bf581d32c8f7b47ef5686570e11dac
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 * ----------------------------------------------------------------------- */
13 #include <stdlib.h>
14 #include <string.h>
15 #include <stdio.h>
16 #include <dprintf.h>
18 #include <com32.h>
19 #include <sys/exec.h>
20 #include <sys/io.h>
21 #include "core.h"
22 #include "menu.h"
23 #include "fs.h"
24 #include "config.h"
25 #include "localboot.h"
26 #include "bios.h"
28 #include <syslinux/bootrm.h>
29 #include <syslinux/movebits.h>
30 #include <syslinux/config.h>
32 /* Must match enum kernel_type */
33 const char *const kernel_types[] = {
34 "none",
35 "localboot",
36 "kernel",
37 "linux",
38 "boot",
39 "bss",
40 "pxe",
41 "fdimage",
42 "comboot",
43 "com32",
44 "config",
45 NULL
48 extern int create_args_and_load(char *);
50 void execute(const char *cmdline, enum kernel_type type)
52 const char *p, *const *pp;
53 const char *kernel, *args;
54 com32sys_t ireg;
55 char *q;
57 memset(&ireg, 0, sizeof ireg);
59 /* for parameter will be passed to __intcall, we need use
60 * lmalloc a block of low memory */
61 q = lmalloc(128);
62 if (!q) {
63 printf("%s(): Fail to lmalloc a buffer to exec %s\n",
64 __func__, cmdline);
65 return;
68 kernel = q;
69 p = cmdline;
70 while (*p && !my_isspace(*p))
71 *q++ = *p++;
72 *q++ = '\0';
74 args = q;
75 while (*p && my_isspace(*p))
76 p++;
78 strcpy(q, p);
80 dprintf("kernel is %s, args = %s type = %d \n", kernel, args, type);
82 if (kernel[0] == '.' && type == KT_NONE) {
83 /* It might be a type specifier */
84 enum kernel_type type = KT_NONE;
85 for (pp = kernel_types; *pp; pp++, type++) {
86 if (!strcmp(kernel + 1, *pp)) {
87 /* Strip the type specifier and retry */
88 execute(p, type);
93 if (type == KT_COM32) {
94 /* new entry for elf format c32 */
95 lfree((void *)kernel);
96 create_args_and_load((char *)cmdline);
97 } else if (type == KT_CONFIG) {
98 char *argv[] = { "ldlinux.c32", NULL };
100 /* kernel contains the config file name */
101 realpath(ConfigName, kernel, FILENAME_MAX);
103 /* If we got anything on the command line, do a chdir */
104 if (*args)
105 mangle_name(config_cwd, args);
107 start_ldlinux(argv);
108 } else if (type == KT_LOCALBOOT) {
109 local_boot(strtoul(kernel, NULL, 0));
110 } else if (type == KT_PXE || type == KT_BSS || type == KT_BOOT) {
111 chainboot_file(kernel, type);
112 } else {
113 /* Need add one item for kernel load, as we don't use
114 * the assembly runkernel.inc any more */
115 new_linux_kernel((char *)kernel, (char *)cmdline);
118 lfree((void *)kernel);
120 /* If this returns, something went bad; return to menu */