diff options
author | H. Peter Anvin <hpa@zytor.com> | 2007-02-19 17:41:35 -0800 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2007-02-19 17:41:35 -0800 |
commit | ee015a347664a62a36b507658b2abfc202ecb305 (patch) | |
tree | 972366b4661089fe2e6494bb477b4f664b8e7fc6 | |
parent | b3ccb4d99d1d220446c357912e0036cd73ac09cb (diff) | |
download | syslinux-ee015a347664a62a36b507658b2abfc202ecb305.tar.gz |
Support multiple image types in the menu system
-rw-r--r-- | com32/modules/menu.h | 21 | ||||
-rw-r--r-- | com32/modules/menumain.c | 29 | ||||
-rw-r--r-- | com32/modules/readconfig.c | 52 |
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)); } } } |