aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2007-02-19 17:41:35 -0800
committerH. Peter Anvin <hpa@zytor.com>2007-02-19 17:41:35 -0800
commitee015a347664a62a36b507658b2abfc202ecb305 (patch)
tree972366b4661089fe2e6494bb477b4f664b8e7fc6
parentb3ccb4d99d1d220446c357912e0036cd73ac09cb (diff)
downloadsyslinux-ee015a347664a62a36b507658b2abfc202ecb305.tar.gz
syslinux-ee015a347664a62a36b507658b2abfc202ecb305.tar.xz
syslinux-ee015a347664a62a36b507658b2abfc202ecb305.zip
Support multiple image types in the menu system
-rw-r--r--com32/modules/menu.h21
-rw-r--r--com32/modules/menumain.c29
-rw-r--r--com32/modules/readconfig.c52
3 files changed, 86 insertions, 16 deletions
diff --git a/com32/modules/menu.h b/com32/modules/menu.h
index a70ba925..acdbb348 100644
--- a/com32/modules/menu.h
+++ b/com32/modules/menu.h
@@ -1,6 +1,6 @@
/* ----------------------------------------------------------------------- *
*
- * Copyright 2004-2005 H. Peter Anvin - All Rights Reserved
+ * Copyright 2004-2007 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
@@ -37,6 +37,25 @@ struct menu_entry {
unsigned char hotkey;
};
+enum kernel_type {
+ /* Meta-types for internal use */
+ KT_NONE,
+ KT_LOCALBOOT,
+
+ /* The ones we can pass off to SYSLINUX, in order */
+ KT_KERNEL, /* Undefined type */
+ KT_LINUX, /* Linux kernel */
+ KT_BOOT, /* Bootstrap program */
+ KT_BSS, /* Boot sector with patch */
+ KT_PXE, /* PXE NBP */
+ KT_FDIMAGE, /* Floppy disk image */
+ KT_COMBOOT, /* COMBOOT image */
+ KT_COM32, /* COM32 image */
+ KT_CONFIG, /* Configuration file */
+};
+
+extern const char *kernel_types[];
+
/* 512 is the current definition inside syslinux */
#define MAX_CMDLINE_LEN 512
diff --git a/com32/modules/menumain.c b/com32/modules/menumain.c
index 9d33babb..14e0af2c 100644
--- a/com32/modules/menumain.c
+++ b/com32/modules/menumain.c
@@ -1,6 +1,6 @@
/* ----------------------------------------------------------------------- *
*
- * Copyright 2004-2006 H. Peter Anvin - All Rights Reserved
+ * Copyright 2004-2007 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
@@ -794,11 +794,11 @@ run_menu(void)
static void
-execute(const char *cmdline)
+execute(const char *cmdline, enum kernel_type type)
{
#ifdef __COM32__
com32sys_t ireg;
- const char *p;
+ const char *p, **pp;
char *q = __com32.cs_bounce;
const char *kernel, *args;
@@ -817,17 +817,30 @@ execute(const char *cmdline)
strcpy(q, p);
- if ( !strcmp(kernel, ".localboot") ) {
+ if (kernel[0] == '.' && type == KT_NONE) {
+ /* It might be a type specifier */
+ enum kernel_type type = KT_NONE;
+ for (pp = kernel_types; *pp; pp++, type++) {
+ if (!strcmp(kernel+1, *pp)) {
+ execute(p, type); /* Strip the type specifier and retry */
+ }
+ }
+ }
+
+ if (type == KT_LOCALBOOT) {
ireg.eax.w[0] = 0x0014; /* Local boot */
- ireg.edx.w[0] = strtoul(args, NULL, 0);
+ ireg.edx.w[0] = strtoul(kernel, NULL, 0);
} else {
+ if (type < KT_KERNEL)
+ type = KT_KERNEL;
+
ireg.eax.w[0] = 0x0016; /* Run kernel image */
ireg.esi.w[0] = OFFS(kernel);
ireg.ds = SEG(kernel);
ireg.ebx.w[0] = OFFS(args);
ireg.es = SEG(args);
+ ireg.edx.l = type-KT_KERNEL;
/* ireg.ecx.l = 0; */ /* We do ipappend "manually" */
- /* ireg.edx.l = 0; */
}
__intcall(0x22, &ireg, NULL);
@@ -881,9 +894,9 @@ int menu_main(int argc, char *argv[])
console_cleanup();
if ( cmdline ) {
- execute(cmdline);
+ execute(cmdline, KT_NONE);
if ( onerror )
- execute(onerror);
+ execute(onerror, KT_NONE);
} else {
return 0; /* Exit */
}
diff --git a/com32/modules/readconfig.c b/com32/modules/readconfig.c
index ddcfd136..183ca851 100644
--- a/com32/modules/readconfig.c
+++ b/com32/modules/readconfig.c
@@ -1,6 +1,6 @@
/* ----------------------------------------------------------------------- *
*
- * Copyright 2004-2006 H. Peter Anvin - All Rights Reserved
+ * Copyright 2004-2007 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
@@ -50,6 +50,21 @@ struct menu_entry *menu_hotkeys[256];
if ( __p ) memcpy(__p, __x, __n); \
__p; })
+const char *kernel_types[] = {
+ "none",
+ "localboot",
+ "kernel",
+ "linux",
+ "boot",
+ "bss",
+ "pxe",
+ "fdimage",
+ "comboot",
+ "com32",
+ "config",
+ NULL
+};
+
const char *ipappends[32];
static void
@@ -123,6 +138,7 @@ looking_at(char *line, const char *kwd)
struct labeldata {
char *label;
char *kernel;
+ enum kernel_type type;
char *append;
char *menulabel;
char *passwd;
@@ -166,7 +182,13 @@ record(struct labeldata *ld, char *append)
if ( !a ) a = append;
if ( !a || (a[0] == '-' && !a[1]) ) a = "";
s = a[0] ? " " : "";
- asprintf(&me->cmdline, "%s%s%s%s", ld->kernel, s, a, ipoptions);
+ if (ld->type == KT_KERNEL) {
+ asprintf(&me->cmdline, "%s%s%s%s",
+ ld->kernel, s, a, ipoptions);
+ } else {
+ asprintf(&me->cmdline, ".%s %s%s%s%s",
+ kernel_types[ld->type], ld->kernel, s, a, ipoptions);
+ }
ld->label = NULL;
ld->passwd = NULL;
@@ -372,9 +394,26 @@ static struct labeldata ld;
static int parse_one_config(const char *filename);
+static char *is_kernel_type(char *cmdstr, enum kernel_type *type)
+{
+ const char **p;
+ char *q;
+ enum kernel_type t = KT_NONE;
+
+ for (p = kernel_types; *p; p++, t++) {
+ if ((q = looking_at(cmdstr, *p))) {
+ *type = t;
+ return q;
+ }
+ }
+
+ return NULL;
+}
+
static void parse_config_file(FILE *f)
{
char line[MAX_LINE], *p, *ep, ch;
+ enum kernel_type type;
while ( fgets(line, sizeof line, f) ) {
p = strchr(line, '\r');
@@ -487,15 +526,17 @@ static void parse_config_file(FILE *f)
record(&ld, append);
ld.label = strdup(p);
ld.kernel = strdup(p);
+ ld.type = KT_KERNEL;
ld.passwd = NULL;
ld.append = NULL;
ld.menulabel = NULL;
ld.ipappend = ipappend;
ld.menudefault = ld.menuhide = 0;
- } else if ( looking_at(p, "kernel") ) {
+ } else if ( (p = is_kernel_type(p, &type)) ) {
if ( ld.label ) {
free(ld.kernel);
- ld.kernel = strdup(skipspace(p+6));
+ ld.kernel = strdup(skipspace(p));
+ ld.type = type;
}
} else if ( looking_at(p, "timeout") ) {
timeout = (atoi(skipspace(p+7))*CLK_TCK+9)/10;
@@ -510,9 +551,6 @@ static void parse_config_file(FILE *f)
ld.ipappend = atoi(skipspace(p+8));
else
ipappend = atoi(skipspace(p+8));
- } else if ( looking_at(p, "localboot") ) {
- ld.kernel = strdup(".localboot");
- ld.append = strdup(skipspace(p+9));
}
}
}