1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
|
/* ----------------------------------------------------------------------- *
*
* Copyright 2004-2008 H. Peter Anvin - All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston MA 02110-1301, USA; either version 2 of the License, or
* (at your option) any later version; incorporated herein by reference.
*
* ----------------------------------------------------------------------- */
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <dprintf.h>
#include <com32.h>
#include <sys/exec.h>
#include <sys/io.h>
#include <sys/module.h>
#include "core.h"
#include "menu.h"
#include "fs.h"
#include "config.h"
#include "localboot.h"
#include "bios.h"
#include <syslinux/bootrm.h>
#include <syslinux/movebits.h>
#include <syslinux/config.h>
#include <syslinux/boot.h>
const struct image_types image_boot_types[] = {
{ "localboot", IMAGE_TYPE_LOCALBOOT },
{ "kernel", IMAGE_TYPE_KERNEL },
{ "linux", IMAGE_TYPE_LINUX },
{ "boot", IMAGE_TYPE_BOOT },
{ "bss", IMAGE_TYPE_BSS },
{ "pxe", IMAGE_TYPE_PXE },
{ "fdimage", IMAGE_TYPE_FDIMAGE },
{ "com32", IMAGE_TYPE_COM32 },
{ "config", IMAGE_TYPE_CONFIG },
{ NULL, 0 },
};
extern int create_args_and_load(char *);
__export void execute(const char *cmdline, uint32_t type, bool sysappend)
{
const char *kernel, *args;
const char *p;
com32sys_t ireg;
char *q, ch;
memset(&ireg, 0, sizeof ireg);
if (strlen(cmdline) >= MAX_CMDLINE_LEN) {
printf("cmdline too long\n");
return;
}
q = malloc(MAX_CMDLINE_LEN);
if (!q) {
printf("%s(): Fail to malloc a buffer to exec %s\n",
__func__, cmdline);
return;
}
kernel = q;
p = cmdline;
while (*p && !my_isspace(*p))
*q++ = *p++;
*q++ = '\0';
args = q;
while (*p && my_isspace(*p))
p++;
do {
*q++ = ch = *p++;
} while (ch);
if (sysappend) {
/* If we've seen some args, insert a space */
if (--q != args)
*q++ = ' ';
do_sysappend(q);
}
dprintf("kernel is %s, args = %s type = %d \n", kernel, args, type);
if (kernel[0] == '.') {
/* It might be a type specifier */
const struct image_types *t;
for (t = image_boot_types; t->name; t++) {
if (!strcmp(kernel + 1, t->name)) {
/*
* Strip the type specifier, apply the
* filename extension if COM32 and
* retry.
*/
p = args;
if (t->type == IMAGE_TYPE_COM32) {
p = apply_extension(p, ".c32");
if (!p)
return;
}
execute(p, t->type, sysappend);
return;
}
}
}
if (type == IMAGE_TYPE_COM32) {
/*
* We may be called with the console in an unknown
* state, so initialise it.
*/
ldlinux_console_init();
/* new entry for elf format c32 */
if (create_args_and_load((char *)cmdline))
printf("Failed to load COM32 file %s\n", kernel);
/*
* The old COM32 module code would run the module then
* drop the user back at the command prompt,
* irrespective of how the COM32 module was loaded,
* e.g. from vesamenu.c32.
*/
unload_modules_since(LDLINUX);
/* Restore the console */
ldlinux_console_init();
ldlinux_enter_command();
} else if (type == IMAGE_TYPE_CONFIG) {
char *argv[] = { LDLINUX, NULL, NULL };
char *config;
int rv;
/* kernel contains the config file name */
config = malloc(FILENAME_MAX);
if (!config)
goto out;
realpath(config, kernel, FILENAME_MAX);
/* If we got anything on the command line, do a chdir */
if (*args)
mangle_name(config_cwd, args);
argv[1] = config;
rv = start_ldlinux(2, argv);
printf("Failed to exec %s: %s\n", LDLINUX, strerror(rv));
} else if (type == IMAGE_TYPE_LOCALBOOT) {
local_boot(strtoul(kernel, NULL, 0));
} else if (type == IMAGE_TYPE_PXE || type == IMAGE_TYPE_BSS ||
type == IMAGE_TYPE_BOOT) {
chainboot_file(kernel, type);
} else {
/* Need add one item for kernel load, as we don't use
* the assembly runkernel.inc any more */
new_linux_kernel((char *)kernel, (char *)args);
}
out:
free((void *)kernel);
/* If this returns, something went bad; return to menu */
}
|