/*
* Copyright (C) 2001-2003 Hewlett-Packard Co.
* Contributed by Stephane Eranian <eranian@hpl.hp.com>
+ * Contributed by Fenghua Yu <fenghua.yu@intel.com>
+ * Contributed by Bibo Mao <bibo.mao@intel.com>
+ * Contributed by Chandramouli Narayanan <mouli@linux.intel.com>
*
* This file is part of the ELILO, the EFI Linux boot loader.
*
#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
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];
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];
{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},
{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)},
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");
}
* - 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;
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;
}
else {
if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '#' ||
- ch == '=' || ch == CHAR_EOF) {
+ ch == CHAR_EOF || (ch == '=' && !rhs)) {
again(ch);
*here = 0;
return TOK_STR;
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)
{
/*
* 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;
}
EFI_STATUS
-read_config(CHAR16 *filename, INTN retry)
+read_config(CHAR16 *filename)
{
EFI_STATUS status;
INTN ret;
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
{
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);
}
}
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;
/*
* 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;
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");
}
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;
}