Adding upstream version 6.00+dfgs.
[syslinux-debian/hramrach.git] / com32 / elflink / ldlinux / execute.c
blob653c880dcc871fa2ee0902e6e4586b51a4cf8a96
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 <sys/module.h>
22 #include "core.h"
23 #include "menu.h"
24 #include "fs.h"
25 #include "config.h"
26 #include "localboot.h"
27 #include "bios.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 },
44 { NULL, 0 },
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;
52 const char *p;
53 com32sys_t ireg;
54 char *q, ch;
56 memset(&ireg, 0, sizeof ireg);
58 if (strlen(cmdline) >= MAX_CMDLINE_LEN) {
59 printf("cmdline too long\n");
60 return;
63 q = malloc(MAX_CMDLINE_LEN);
64 if (!q) {
65 printf("%s(): Fail to malloc a buffer to exec %s\n",
66 __func__, cmdline);
67 return;
70 kernel = q;
71 p = cmdline;
72 while (*p && !my_isspace(*p))
73 *q++ = *p++;
74 *q++ = '\0';
76 args = q;
77 while (*p && my_isspace(*p))
78 p++;
80 do {
81 *q++ = ch = *p++;
82 } while (ch);
84 if (sysappend) {
85 /* If we've seen some args, insert a space */
86 if (--q != args)
87 *q++ = ' ';
89 do_sysappend(q);
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
102 * retry.
104 p = args;
105 if (t->type == IMAGE_TYPE_COM32) {
106 p = apply_extension(p, ".c32");
107 if (!p)
108 return;
111 execute(p, t->type, sysappend);
112 return;
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 };
142 char *config;
143 int rv;
145 /* kernel contains the config file name */
146 config = malloc(FILENAME_MAX);
147 if (!config)
148 goto out;
150 realpath(config, kernel, FILENAME_MAX);
152 /* If we got anything on the command line, do a chdir */
153 if (*args)
154 mangle_name(config_cwd, args);
156 argv[1] = config;
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);
164 } else {
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);
170 out:
171 free((void *)kernel);
173 /* If this returns, something went bad; return to menu */