--- trunk/grubby/grubby.c 2012/10/01 12:08:46 1934 +++ trunk/grubby/grubby.c 2012/10/01 12:39:50 1940 @@ -56,6 +56,8 @@ #define NOOP_OPCODE 0x90 #define JMP_SHORT_OPCODE 0xeb +int isEfi = 0; + /* comments get lumped in with indention */ struct lineElement { char * item; @@ -82,7 +84,9 @@ LT_MENUENTRY = 1 << 17, LT_ENTRY_END = 1 << 18, LT_SET_VARIABLE = 1 << 19, - LT_UNKNOWN = 1 << 20, + LT_KERNEL_EFI = 1 << 20, + LT_INITRD_EFI = 1 << 21, + LT_UNKNOWN = 1 << 22, }; struct singleLine { @@ -205,9 +209,9 @@ { "default", LT_DEFAULT, ' ' }, { "fallback", LT_FALLBACK, ' ' }, { "linux", LT_KERNEL, ' ' }, - { "linuxefi", LT_KERNEL, ' ' }, + { "linuxefi", LT_KERNEL_EFI, ' ' }, { "initrd", LT_INITRD, ' ', ' ' }, - { "initrdefi", LT_INITRD, ' ', ' ' }, + { "initrdefi", LT_INITRD_EFI, ' ', ' ' }, { "module", LT_MBMODULE, ' ' }, { "kernel", LT_HYPER, ' ' }, { NULL, 0, 0 }, @@ -273,6 +277,14 @@ return 0; } +static int iskernel(enum lineType_e type) { + return (type == LT_KERNEL || type == LT_KERNEL_EFI); +} + +static int isinitrd(enum lineType_e type) { + return (type == LT_INITRD || type == LT_INITRD_EFI); +} + char *grub2ExtractTitle(struct singleLine * line) { char * current; char * current_indent; @@ -572,6 +584,21 @@ return buf; } +static enum lineType_e preferredLineType(enum lineType_e type, + struct configFileInfo *cfi) { + if (isEfi && cfi == &grub2ConfigType) { + switch (type) { + case LT_KERNEL: + return LT_KERNEL_EFI; + case LT_INITRD: + return LT_INITRD_EFI; + default: + return type; + } + } + return type; +} + static struct keywordTypes * getKeywordByType(enum lineType_e type, struct configFileInfo * cfi) { for (struct keywordTypes *kw = cfi->keywords; kw->key; kw++) { @@ -996,7 +1023,7 @@ cfg->flags &= ~GRUB_CONFIG_NO_DEFAULT; defaultLine = line; - } else if (line->type == LT_KERNEL) { + } else if (iskernel(line->type)) { /* if by some freak chance this is multiboot and the "module" * lines came earlier in the template, make sure to use LT_HYPER * instead of LT_KERNEL now @@ -1013,7 +1040,7 @@ for (struct singleLine *l = entry->lines; l; l = l->next) { if (l->type == LT_HYPER) break; - else if (l->type == LT_KERNEL) { + else if (iskernel(l->type)) { l->type = LT_HYPER; break; } @@ -1567,7 +1594,7 @@ return 0; } - line = getLineByType(LT_KERNEL|LT_HYPER, entry->lines); + line = getLineByType(LT_KERNEL|LT_HYPER|LT_KERNEL_EFI, entry->lines); if (!line) { notSuitablePrintf(entry, "no line found\n"); return 0; @@ -1697,7 +1724,7 @@ entry = findEntryByIndex(config, indexVars[i]); if (!entry) return NULL; - line = getLineByType(LT_KERNEL|LT_HYPER, entry->lines); + line = getLineByType(LT_KERNEL|LT_HYPER|LT_KERNEL_EFI, entry->lines); if (!line) return NULL; if (index) *index = indexVars[i]; @@ -1746,9 +1773,9 @@ /* check all the lines matching checkType */ for (line = entry->lines; line; line = line->next) { - line = getLineByType(entry->multiboot && checkType == LT_KERNEL ? - LT_KERNEL|LT_MBMODULE|LT_HYPER : - checkType, line); + line = getLineByType(entry->multiboot && checkType == LT_KERNEL + ? LT_KERNEL|LT_KERNEL_EFI|LT_MBMODULE|LT_HYPER + : checkType, line); if (!line) break; /* not found in this entry */ if (line && line->type != LT_MENUENTRY && @@ -1768,7 +1795,7 @@ * non-Linux boot entries (could find netbsd etc, though, which is * unfortunate) */ - if (line && getLineByType(LT_KERNEL|LT_HYPER, entry->lines)) + if (line && getLineByType(LT_KERNEL|LT_HYPER|LT_KERNEL_EFI, entry->lines)) break; /* found 'im! */ } @@ -1957,7 +1984,7 @@ printf("index=%d\n", index); - line = getLineByType(LT_KERNEL|LT_HYPER, entry->lines); + line = getLineByType(LT_KERNEL|LT_HYPER|LT_KERNEL_EFI, entry->lines); if (!line) { printf("non linux entry\n"); return; @@ -2022,7 +2049,7 @@ printf("root=%s\n", s); } - line = getLineByType(LT_INITRD, entry->lines); + line = getLineByType(LT_INITRD|LT_INITRD_EFI, entry->lines); if (line && line->numElements >= 2) { if (!strncmp(prefix, line->elements[1].item, strlen(prefix))) @@ -2423,6 +2450,13 @@ { struct singleLine * newLine = lineDup(tmplLine); + if (isEfi && cfi == &grub2ConfigType) { + enum lineType_e old = newLine->type; + newLine->type = preferredLineType(newLine->type, cfi); + if (old != newLine->type) + newLine->elements[0].item = getKeyByType(newLine->type, cfi); + } + if (val) { /* override the inherited value with our own. * This is a little weak because it only applies to elements[1] @@ -2432,7 +2466,7 @@ insertElement(newLine, val, 1, cfi); /* but try to keep the rootspec from the template... sigh */ - if (tmplLine->type & (LT_HYPER|LT_KERNEL|LT_MBMODULE|LT_INITRD)) { + if (tmplLine->type & (LT_HYPER|LT_KERNEL|LT_MBMODULE|LT_INITRD|LT_KERNEL_EFI|LT_INITRD_EFI)) { char * rootspec = getRootSpecifier(tmplLine->elements[1].item); if (rootspec != NULL) { free(newLine->elements[1].item); @@ -2469,7 +2503,6 @@ /* NB: This function shouldn't allocate items on the heap, rather on the * stack since it calls addLineTmpl which will make copies. */ - if (type == LT_TITLE && cfi->titleBracketed) { /* we're doing a bracketed title (zipl) */ tmpl.type = type; @@ -2803,7 +2836,7 @@ firstElement = 2; } else { - line = getLineByType(LT_KERNEL|LT_MBMODULE, entry->lines); + line = getLineByType(LT_KERNEL|LT_MBMODULE|LT_KERNEL_EFI, entry->lines); if (!line) { /* no LT_KERNEL or LT_MBMODULE in this entry? */ continue; @@ -2968,10 +3001,10 @@ if (!image) return 0; for (; (entry = findEntryByPath(cfg, image, prefix, &index)); index++) { - kernelLine = getLineByType(LT_KERNEL, entry->lines); + kernelLine = getLineByType(LT_KERNEL|LT_KERNEL_EFI, entry->lines); if (!kernelLine) continue; - line = getLineByType(LT_INITRD, entry->lines); + line = getLineByType(LT_INITRD|LT_INITRD_EFI, entry->lines); if (line) removeLine(entry, line); if (prefix) { @@ -2982,7 +3015,8 @@ endLine = getLineByType(LT_ENTRY_END, entry->lines); if (endLine) removeLine(entry, endLine); - line = addLine(entry, cfg->cfi, LT_INITRD, kernelLine->indent, initrd); + line = addLine(entry, cfg->cfi, preferredLineType(LT_INITRD, cfg->cfi), + kernelLine->indent, initrd); if (!line) return 1; if (endLine) { @@ -3395,8 +3429,7 @@ while (*chptr && isspace(*chptr)) chptr++; if (*chptr == '#') continue; - if (tmplLine->type == LT_KERNEL && - tmplLine->numElements >= 2) { + if (iskernel(tmplLine->type) && tmplLine->numElements >= 2) { if (!template->multiboot && (needs & NEED_MB)) { /* it's not a multiboot template and this is the kernel * line. Try to be intelligent about inserting the @@ -3473,30 +3506,32 @@ /* template is multi but new is not, * insert the kernel in the first module slot */ - tmplLine->type = LT_KERNEL; + tmplLine->type = preferredLineType(LT_KERNEL, config->cfi); free(tmplLine->elements[0].item); tmplLine->elements[0].item = - strdup(getKeywordByType(LT_KERNEL, config->cfi)->key); + strdup(getKeywordByType(tmplLine->type, + config->cfi)->key); newLine = addLineTmpl(new, tmplLine, newLine, - newKernelPath + strlen(prefix), config->cfi); + newKernelPath + strlen(prefix), + config->cfi); needs &= ~NEED_KERNEL; } else if (needs & NEED_INITRD) { char *initrdVal; /* template is multi but new is not, * insert the initrd in the second module slot */ - tmplLine->type = LT_INITRD; + tmplLine->type = preferredLineType(LT_INITRD, config->cfi); free(tmplLine->elements[0].item); tmplLine->elements[0].item = - strdup(getKeywordByType(LT_INITRD, config->cfi)->key); + strdup(getKeywordByType(tmplLine->type, + config->cfi)->key); initrdVal = getInitrdVal(config, prefix, tmplLine, newKernelInitrd, extraInitrds, extraInitrdCount); newLine = addLineTmpl(new, tmplLine, newLine, initrdVal, config->cfi); free(initrdVal); needs &= ~NEED_INITRD; } - } else if (tmplLine->type == LT_INITRD && - tmplLine->numElements >= 2) { + } else if (isinitrd(tmplLine->type) && tmplLine->numElements >= 2) { if (needs & NEED_INITRD && new->multiboot && !template->multiboot && config->cfi->mbInitRdIsModule) { @@ -3550,7 +3585,8 @@ static const char *prefix = "'Loading "; if (tmplLine->numElements > 1 && strstr(tmplLine->elements[1].item, prefix) && - masterLine->next && masterLine->next->type == LT_KERNEL) { + masterLine->next && + iskernel(masterLine->next->type)) { char *newTitle = malloc(strlen(prefix) + strlen(newKernelTitle) + 2); @@ -3577,10 +3613,12 @@ */ switch (config->cfi->entryStart) { case LT_KERNEL: + case LT_KERNEL_EFI: if (new->multiboot && config->cfi->mbHyperFirst) { /* fall through to LT_HYPER */ } else { - newLine = addLine(new, config->cfi, LT_KERNEL, + newLine = addLine(new, config->cfi, + preferredLineType(LT_KERNEL, config->cfi), config->primaryIndent, newKernelPath + strlen(prefix)); needs &= ~NEED_KERNEL; @@ -3656,8 +3694,9 @@ if (needs & NEED_KERNEL) { newLine = addLine(new, config->cfi, (new->multiboot && getKeywordByType(LT_MBMODULE, - config->cfi)) ? - LT_MBMODULE : LT_KERNEL, + config->cfi)) + ? LT_MBMODULE + : preferredLineType(LT_KERNEL, config->cfi), config->secondaryIndent, newKernelPath + strlen(prefix)); needs &= ~NEED_KERNEL; @@ -3673,8 +3712,9 @@ initrdVal = getInitrdVal(config, prefix, NULL, newKernelInitrd, extraInitrds, extraInitrdCount); newLine = addLine(new, config->cfi, (new->multiboot && getKeywordByType(LT_MBMODULE, - config->cfi)) ? - LT_MBMODULE : LT_INITRD, + config->cfi)) + ? LT_MBMODULE + : preferredLineType(LT_INITRD, config->cfi), config->secondaryIndent, initrdVal); free(initrdVal); @@ -3790,6 +3830,8 @@ _("display the title of the default kernel") }, { "elilo", 0, POPT_ARG_NONE, &configureELilo, 0, _("configure elilo bootloader") }, + { "efi", 0, POPT_ARG_NONE, &isEfi, 0, + _("force grub2 stanzas to use efi") }, { "extlinux", 0, POPT_ARG_NONE, &configureExtLinux, 0, _("configure extlinux bootloader (from syslinux)") }, { "grub", 0, POPT_ARG_NONE, &configureGrub, 0, @@ -4102,7 +4144,7 @@ if (!entry) return 0; if (!suitableImage(entry, bootPrefix, 0, flags)) return 0; - line = getLineByType(LT_KERNEL|LT_HYPER, entry->lines); + line = getLineByType(LT_KERNEL|LT_HYPER|LT_KERNEL_EFI, entry->lines); if (!line) return 0; rootspec = getRootSpecifier(line->elements[1].item);