X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=config.c;h=5ad8de624ea420f2b0d67060c0d3ad7f2d5ec035;hb=81447a679eb7778b32954d46c78ed637fc2ecbb3;hp=ac789b9bc61a35d6b0cc470ea70338a5157d244d;hpb=054761502f884ae2cb147c75bd17a660fe63b071;p=debian%2Felilo diff --git a/config.c b/config.c index ac789b9..5ad8de6 100644 --- a/config.c +++ b/config.c @@ -1,6 +1,9 @@ /* * Copyright (C) 2001-2003 Hewlett-Packard Co. * Contributed by Stephane Eranian + * Contributed by Fenghua Yu + * Contributed by Bibo Mao + * Contributed by Chandramouli Narayanan * * This file is part of the ELILO, the EFI Linux boot loader. * @@ -42,6 +45,8 @@ #define ELILO_ARCH_DEFAULT_CONFIG L"elilo-ia64.conf" #elif defined (CONFIG_ia32) #define ELILO_ARCH_DEFAULT_CONFIG L"elilo-ia32.conf" +#elif defined (CONFIG_x86_64) +#define ELILO_ARCH_DEFAULT_CONFIG L"elilo-x86_64.conf" #else #error "You need to specfy your default arch config file" #endif @@ -68,6 +73,7 @@ typedef struct boot_image { CHAR16 kname[FILENAME_MAXLEN]; CHAR16 options[MAX_STRING]; CHAR16 initrd[FILENAME_MAXLEN]; + CHAR16 vmcode[FILENAME_MAXLEN]; CHAR16 root[FILENAME_MAXLEN]; CHAR16 fallback[MAX_STRING]; CHAR16 description[MAX_STRING]; @@ -93,6 +99,7 @@ typedef enum { typedef struct { CHAR16 root[FILENAME_MAXLEN]; /* globally defined root fs */ CHAR16 initrd[FILENAME_MAXLEN];/* globally defined initrd */ + CHAR16 vmcode[FILENAME_MAXLEN];/* globally defined boot-time module */ CHAR16 options[MAX_STRING]; CHAR16 default_image_name[MAX_STRING]; CHAR16 message_file[MAX_MESSAGES][FILENAME_MAXLEN]; @@ -144,6 +151,7 @@ static config_option_t global_common_options[]={ {OPT_BOOL, OPT_GLOBAL, L"noedd30", NULL, NULL, &global_config.edd30_no_force}, {OPT_CMD, OPT_GLOBAL, L"append", NULL, NULL, global_config.options}, {OPT_FILE, OPT_GLOBAL, L"initrd", NULL, NULL, global_config.initrd}, +{OPT_FILE, OPT_GLOBAL, L"vmm", NULL, NULL, global_config.vmcode}, {OPT_FILE, OPT_GLOBAL, L"image", do_image, NULL, opt_offsetof(kname)}, {OPT_BOOL, OPT_GLOBAL, L"checkalt", NULL, NULL, &global_config.alt_check}, {OPT_STR, OPT_GLOBAL, L"chooser", NULL, check_chooser, global_config.chooser}, @@ -168,6 +176,7 @@ static config_option_t image_common_options[]={ {OPT_CMD, OPT_IMAGE, L"append", do_options, NULL, opt_offsetof(options)}, {OPT_CMD, OPT_IMAGE, L"literal", do_literal, NULL, NULL}, {OPT_FILE, OPT_IMAGE, L"initrd", NULL, NULL, opt_offsetof(initrd)}, + {OPT_FILE, OPT_IMAGE, L"vmm", NULL, NULL, opt_offsetof(vmcode)}, {OPT_STR, OPT_IMAGE, L"label", NULL, NULL, opt_offsetof(label)}, {OPT_FILE, OPT_IMAGE, L"image", do_image, NULL, opt_offsetof(kname)}, {OPT_STR, OPT_IMAGE, L"description", NULL, NULL, opt_offsetof(description)}, @@ -200,14 +209,8 @@ static fops_fd_t config_fd; static VOID config_error(CHAR16 *msg,...) { - va_list ap; - extern UINTN _IPrint (UINTN, UINTN, SIMPLE_TEXT_OUTPUT_INTERFACE *, CHAR16 *, CHAR8 *, va_list); - Print(L"near line %d: ",line_num); - - va_start(ap,msg); - _IPrint((UINTN)-1, (UINTN)-1, systab->ConOut, msg, NULL, ap); - va_end(ap); + IPrint(systab->ConOut, msg); Print(L"\n"); } @@ -252,7 +255,16 @@ next(VOID) back = 0; return ch; } - return getc(); +/* + * config files served from pxe/tftpboot windows servers can contain + * extraneous '\r' characters, often the first char in the file, and + * we need to simply skip over those and continue on + */ + ch = getc(); + if(ch == '\r') + ch = getc(); + + return ch; } /* @@ -301,23 +313,23 @@ find_option(config_option_group_t *grp, CHAR16 *str) * - TOK_ERR: in case of (parsing) error */ static token_t -get_token(CHAR16 *str, UINTN maxlen) +get_token_core(CHAR16 *str, UINTN maxlen, BOOLEAN rhs) { INTN ch, escaped; CHAR16 *here; for (;;) { - while ((ch = next()), ch == ' ' || ch == '\t' || ch == '\n') if (ch == '\n') line_num++; + while ((ch = next()), ch == ' ' || ch == '\t' || ch == '\n') if (ch == '\n' ) line_num++; if (ch == CHAR_EOF) return TOK_EOF; + /* skip comment line */ if (ch != '#') break; - /* skip comment line */ while ((ch = next()), ch != '\n') if (ch == CHAR_EOF) return TOK_EOF; line_num++; } - if (ch == '=') return TOK_EQUAL; + if (ch == '=' && !rhs) return TOK_EQUAL; if (ch == '"') { here = str; @@ -370,7 +382,7 @@ get_token(CHAR16 *str, UINTN maxlen) } else { if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '#' || - ch == '=' || ch == CHAR_EOF) { + ch == CHAR_EOF || (ch == '=' && !rhs)) { again(ch); *here = 0; return TOK_STR; @@ -383,6 +395,18 @@ get_token(CHAR16 *str, UINTN maxlen) return TOK_ERR; } +static token_t +get_token(CHAR16 *str, UINTN maxlen) +{ + return get_token_core(str, maxlen, FALSE); +} + +static token_t +get_token_rhs(CHAR16 *str, UINTN maxlen) +{ + return get_token_core(str, maxlen, TRUE); +} + static INTN image_check(boot_image_t *img) { @@ -676,7 +700,7 @@ do_string_core(config_option_t *p, CHAR16 *str, UINTN maxlen, CHAR16 *msg) /* * now get the value */ - tok = get_token(str, maxlen); + tok = get_token_rhs(str, maxlen); if (tok != TOK_STR) { config_error(L"Option %s expects %s", p->name, msg); return -1; @@ -747,7 +771,10 @@ config_parse(VOID) if (tok == TOK_EOF) break; - if (tok == TOK_ERR) return -1; + if (tok == TOK_ERR) { + Print(L"Bad Token from elilo config file, parser read: %s\n elilo exiting\n", str); + return -1; + } if ( (p = find_option(current_options, str)) == NULL) { config_error(L"Unkown option %s", str); @@ -843,7 +870,7 @@ get_config_file(VOID) } EFI_STATUS -read_config(CHAR16 *filename, INTN retry) +read_config(CHAR16 *filename) { EFI_STATUS status; INTN ret; @@ -856,49 +883,8 @@ read_config(CHAR16 *filename, INTN retry) status = fops_open(filename, &config_fd); if (EFI_ERROR(status)) { - /* - * if the user explicitely specified a filename and we can't - * find it, then we must fail. - */ - if (elilo_opt.parse_only || retry == 0) { - VERB_PRT(3, Print(L"cannot open config file %s\n", filename)); - return status; - } - /* - * if not already submitted filename, - */ - if (StrCmp(filename, ELILO_ARCH_DEFAULT_CONFIG)) { - /* - * try the arch default file, now - */ - VERB_PRT(3,Print(L"config file %s not found, trying %s\n", - filename, ELILO_ARCH_DEFAULT_CONFIG)); - - StrCpy(global_config.config_file,ELILO_ARCH_DEFAULT_CONFIG); - - status = fops_open(ELILO_ARCH_DEFAULT_CONFIG, &config_fd); - } - /* - * if arch specific did not work, try generic - */ - if (EFI_ERROR(status) && StrCmp(filename, ELILO_DEFAULT_CONFIG)) { - /* - * try the default file as a last resort - */ - VERB_PRT(3,Print(L"config file %s not found, trying %s\n", - ELILO_ARCH_DEFAULT_CONFIG, ELILO_DEFAULT_CONFIG)); - - StrCpy(global_config.config_file, ELILO_DEFAULT_CONFIG); - status = fops_open(ELILO_DEFAULT_CONFIG, &config_fd); - } - /* - * if nothing worked, then bail out - */ - if (EFI_ERROR(status)) { - VERB_PRT(3, Print(L"no valid config file found\n")); - global_config.config_file[0] = CHAR_NULL; - return status; - } + VERB_PRT(3, Print(L"cannot open config file %s\n", filename)); + return status; } /* * start numbering at line 1 @@ -923,10 +909,10 @@ print_label_list(VOID) { boot_image_t *img, *dfl = global_config.default_image; - if (dfl) Print(L"%s ", dfl->label); + if (dfl) Print(L"\t%s\n", dfl->label); for (img = image_list; img; img = img->next) { - if (img != dfl) Print(L"%s ", img->label); + if (img != dfl) Print(L"\t%s\n", img->label); } } @@ -973,8 +959,39 @@ find_description(CHAR16 *label) return NULL; } +static void +add_root_to_options(CHAR16 *options, CHAR16 *root, CHAR16 *vmcode) +{ + CHAR16 *o, ko[CMDLINE_MAXLEN]; + + if (vmcode[0]) { + for (o = options; *o; o++) { + if (*o == '-' && *(o+1) == '-') + break; + } + if (! *o) { + /* no separator found, add one */ + StrCpy(o, L" -- "); + o++; + } + + /* advance past separator and whitespace */ + o += 2; + while (*o == ' ') o++; + } else { + o = options; + } + + /* insert root param at this point */ + StrCpy(ko, o); + StrCpy(o, L"root="); + StrCat(o, root); + StrCat(o, L" "); + StrCat(o, ko); +} + INTN -find_label(CHAR16 *label, CHAR16 *kname, CHAR16 *options, CHAR16 *initrd) +find_label(CHAR16 *label, CHAR16 *kname, CHAR16 *options, CHAR16 *initrd, CHAR16 *vmcode) { boot_image_t *img; @@ -995,18 +1012,16 @@ find_label(CHAR16 *label, CHAR16 *kname, CHAR16 *options, CHAR16 *initrd) /* * when the label does not exist, we still propagate the global options */ - if (global_config.root[0]) { - StrCpy(options, L" root="); - StrCat(options, global_config.root); - } - if (global_config.options[0]) { StrCat(options, L" "); StrCat(options, global_config.options); } + if (global_config.root[0]) + add_root_to_options(options, global_config.root, global_config.vmcode); if (global_config.readonly) StrCat(options, L" ro"); if (global_config.initrd[0]) StrCpy(initrd, global_config.initrd); + if (global_config.vmcode[0]) StrCpy(vmcode, global_config.vmcode); /* make sure we don't get garbage here */ elilo_opt.sys_img_opts = NULL; @@ -1015,21 +1030,33 @@ find_label(CHAR16 *label, CHAR16 *kname, CHAR16 *options, CHAR16 *initrd) found: StrCpy(kname, img->kname); + /* per image initrd has precedence over global initrd */ + if (img->initrd[0]) + StrCpy(initrd, img->initrd); + else + StrCpy(initrd, global_config.initrd); + + /* per image vmcode has precedence over global vmcode */ + if (img->vmcode[0]) + StrCpy(vmcode, img->vmcode); + else + StrCpy(vmcode, global_config.vmcode); + /* * literal option overrides any other image-based or global option * * In any case, the image option has priority over the global option */ if (img->literal == 0) { - if (img->root[0] || global_config.root[0]) { - StrCat(options, L"root="); - StrCat(options, img->root[0] ? img->root : global_config.root); - } /* XXX: check max length */ if (img->options[0] || global_config.options[0]) { StrCat(options, L" "); StrCat(options, img->options[0] ? img->options: global_config.options); } + if (img->root[0] || global_config.root[0]) { + add_root_to_options(options, img->root[0] + ? img->root : global_config.root, vmcode); + } if (img->readonly || global_config.readonly) { StrCat(options, L" ro"); } @@ -1038,18 +1065,12 @@ found: StrCpy(options, img->options); } - /* per image initrd has precedence over global initrd */ - if (img->initrd[0]) - StrCpy(initrd, img->initrd); - else if (global_config.initrd[0]) - StrCpy(initrd, global_config.initrd); - /* * point to architecture dependent options for this image */ elilo_opt.sys_img_opts = &img->sys_img_opts; - DBG_PRT((L"label %s: kname=%s options=%s initrd=%s", img->label, kname, options, initrd)); + DBG_PRT((L"label %s: kname=%s options=%s initrd=%s vmcode=%s", img->label, kname, options, initrd, vmcode)); return 0; }