--- trunk/grubby/grubby.c 2013/10/21 14:02:25 2258 +++ trunk/grubby/grubby.c 2014/07/16 10:41:38 2687 @@ -90,7 +90,10 @@ LT_SET_VARIABLE = 1 << 19, LT_KERNEL_EFI = 1 << 20, LT_INITRD_EFI = 1 << 21, - LT_UNKNOWN = 1 << 22, + LT_KERNEL_16 = 1 << 22, + LT_INITRD_16 = 1 << 23, + LT_DEVTREE = 1 << 24, + LT_UNKNOWN = 1 << 25, }; struct singleLine { @@ -119,6 +122,7 @@ #define NEED_ARGS (1 << 3) #define NEED_MB (1 << 4) #define NEED_END (1 << 5) +#define NEED_DEVTREE (1 << 6) #define MAIN_DEFAULT (1 << 0) #define DEFAULT_SAVED -2 @@ -182,6 +186,8 @@ "/boot/grub/grub.conf", "/boot/grub/menu.lst", "/etc/grub.conf", + "/boot/grub2/grub.cfg", + "/boot/grub2-efi/grub.cfg", NULL }; static int i = -1; @@ -221,10 +227,13 @@ { "fallback", LT_FALLBACK, ' ' }, { "linux", LT_KERNEL, ' ' }, { "linuxefi", LT_KERNEL_EFI, ' ' }, + { "linux16", LT_KERNEL_16, ' ' }, { "initrd", LT_INITRD, ' ', ' ' }, { "initrdefi", LT_INITRD_EFI, ' ', ' ' }, + { "initrd16", LT_INITRD_16, ' ', ' ' }, { "module", LT_MBMODULE, ' ' }, { "kernel", LT_HYPER, ' ' }, + { "devicetree", LT_DEVTREE, ' ' }, { NULL, 0, 0 }, }; @@ -273,8 +282,8 @@ static char buf[1025]; char *s = NULL; char *ret = NULL; - char *envFile = info->envFile ? info->envFile : "/boot/grub2/grubenv"; - int rc = asprintf(&s, "grub2-editenv %s list | grep '^%s='", envFile, name); + char *envFile = info->envFile ? info->envFile : "/boot/grub/grubenv"; + int rc = asprintf(&s, "grub-editenv %s list | grep '^%s='", envFile, name); if (rc < 0) return NULL; @@ -338,14 +347,14 @@ { char *s = NULL; int rc = 0; - char *envFile = info->envFile ? info->envFile : "/boot/grub2/grubenv"; + char *envFile = info->envFile ? info->envFile : "/boot/grub/grubenv"; unquote(value); value = shellEscape(value); if (!value) return -1; - rc = asprintf(&s, "grub2-editenv %s set '%s=%s'", envFile, name, value); + rc = asprintf(&s, "grub-editenv %s set '%s=%s'", envFile, name, value); free(value); if (rc <0) return -1; @@ -396,11 +405,11 @@ } static int iskernel(enum lineType_e type) { - return (type == LT_KERNEL || type == LT_KERNEL_EFI); + return (type == LT_KERNEL || type == LT_KERNEL_EFI || type == LT_KERNEL_16); } static int isinitrd(enum lineType_e type) { - return (type == LT_INITRD || type == LT_INITRD_EFI); + return (type == LT_INITRD || type == LT_INITRD_EFI || type == LT_INITRD_16); } char *grub2ExtractTitle(struct singleLine * line) { @@ -711,13 +720,31 @@ struct configFileInfo *cfi) { if (isEfi && cfi == &grub2ConfigType) { switch (type) { +#if defined(__aarch64__) + case LT_KERNEL: + return LT_KERNEL; + case LT_INITRD: + return LT_INITRD; +#else case LT_KERNEL: return LT_KERNEL_EFI; case LT_INITRD: return LT_INITRD_EFI; +#endif default: return type; } +#if defined(__i386__) || defined(__x86_64__) + } else if (cfi == &grub2ConfigType) { + switch (type) { + case LT_KERNEL: + return LT_KERNEL_16; + case LT_INITRD: + return LT_INITRD_16; + default: + return type; + } +#endif } return type; } @@ -1805,7 +1832,7 @@ return 0; } - line = getLineByType(LT_KERNEL|LT_HYPER|LT_KERNEL_EFI, entry->lines); + line = getLineByType(LT_KERNEL|LT_HYPER|LT_KERNEL_EFI|LT_KERNEL_16, entry->lines); if (!line) { notSuitablePrintf(entry, 0, "no line found\n"); return 0; @@ -1939,7 +1966,7 @@ entry = findEntryByIndex(config, indexVars[i]); if (!entry) return NULL; - line = getLineByType(LT_KERNEL|LT_HYPER|LT_KERNEL_EFI, entry->lines); + line = getLineByType(LT_KERNEL|LT_HYPER|LT_KERNEL_EFI|LT_KERNEL_16, entry->lines); if (!line) return NULL; if (index) *index = indexVars[i]; @@ -1990,9 +2017,9 @@ for (line = entry->lines; line; line = line->next) { enum lineType_e ct = checkType; if (entry->multiboot && checkType == LT_KERNEL) - ct = LT_KERNEL|LT_KERNEL_EFI|LT_MBMODULE|LT_HYPER; + ct = LT_KERNEL|LT_KERNEL_EFI|LT_MBMODULE|LT_HYPER|LT_KERNEL_16; else if (checkType & LT_KERNEL) - ct = checkType | LT_KERNEL_EFI; + ct = checkType | LT_KERNEL_EFI | LT_KERNEL_16; line = getLineByType(ct, line); if (!line) break; /* not found in this entry */ @@ -2014,7 +2041,7 @@ * non-Linux boot entries (could find netbsd etc, though, which is * unfortunate) */ - if (line && getLineByType(LT_KERNEL|LT_HYPER|LT_KERNEL_EFI, entry->lines)) + if (line && getLineByType(LT_KERNEL|LT_HYPER|LT_KERNEL_EFI|LT_KERNEL_16, entry->lines)) break; /* found 'im! */ } @@ -2248,7 +2275,7 @@ printf("index=%d\n", index); - line = getLineByType(LT_KERNEL|LT_HYPER|LT_KERNEL_EFI, entry->lines); + line = getLineByType(LT_KERNEL|LT_HYPER|LT_KERNEL_EFI|LT_KERNEL_16, entry->lines); if (!line) { printf("non linux entry\n"); return; @@ -2313,7 +2340,7 @@ printf("root=%s\n", s); } - line = getLineByType(LT_INITRD|LT_INITRD_EFI, entry->lines); + line = getLineByType(LT_INITRD|LT_INITRD_EFI|LT_INITRD_16, entry->lines); if (line && line->numElements >= 2) { if (!strncmp(prefix, line->elements[1].item, strlen(prefix))) @@ -2730,7 +2757,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|LT_KERNEL_EFI|LT_INITRD_EFI)) { + if (tmplLine->type & (LT_HYPER|LT_KERNEL|LT_MBMODULE|LT_INITRD|LT_KERNEL_EFI|LT_INITRD_EFI|LT_KERNEL_16|LT_INITRD_16)) { char * rootspec = getRootSpecifier(tmplLine->elements[1].item); if (rootspec != NULL) { free(newLine->elements[1].item); @@ -3100,7 +3127,7 @@ firstElement = 2; } else { - line = getLineByType(LT_KERNEL|LT_MBMODULE|LT_KERNEL_EFI, entry->lines); + line = getLineByType(LT_KERNEL|LT_MBMODULE|LT_KERNEL_EFI|LT_KERNEL_16, entry->lines); if (!line) { /* no LT_KERNEL or LT_MBMODULE in this entry? */ continue; @@ -3256,6 +3283,42 @@ return rc; } +int addMBInitrd(struct grubConfig * cfg, const char *newMBKernel, + const char * image, const char * prefix, const char * initrd) { + struct singleEntry * entry; + struct singleLine * line, * kernelLine, *endLine = NULL; + int index = 0; + + if (!image) return 0; + + for (; (entry = findEntryByPath(cfg, newMBKernel, prefix, &index)); index++) { + kernelLine = getLineByType(LT_MBMODULE, entry->lines); + if (!kernelLine) continue; + + if (prefix) { + int prefixLen = strlen(prefix); + if (!strncmp(initrd, prefix, prefixLen)) + initrd += prefixLen; + } + endLine = getLineByType(LT_ENTRY_END, entry->lines); + if (endLine) + removeLine(entry, endLine); + line = addLine(entry, cfg->cfi, preferredLineType(LT_MBMODULE,cfg->cfi), + kernelLine->indent, initrd); + if (!line) + return 1; + if (endLine) { + line = addLine(entry, cfg->cfi, LT_ENTRY_END, "", NULL); + if (!line) + return 1; + } + + break; + } + + return 0; +} + int updateInitrd(struct grubConfig * cfg, const char * image, const char * prefix, const char * initrd) { struct singleEntry * entry; @@ -3265,10 +3328,10 @@ if (!image) return 0; for (; (entry = findEntryByPath(cfg, image, prefix, &index)); index++) { - kernelLine = getLineByType(LT_KERNEL|LT_KERNEL_EFI, entry->lines); + kernelLine = getLineByType(LT_KERNEL|LT_KERNEL_EFI|LT_KERNEL_16, entry->lines); if (!kernelLine) continue; - line = getLineByType(LT_INITRD|LT_INITRD_EFI, entry->lines); + line = getLineByType(LT_INITRD|LT_INITRD_EFI|LT_INITRD_16, entry->lines); if (line) removeLine(entry, line); if (prefix) { @@ -3279,8 +3342,21 @@ endLine = getLineByType(LT_ENTRY_END, entry->lines); if (endLine) removeLine(entry, endLine); - line = addLine(entry, cfg->cfi, preferredLineType(LT_INITRD, cfg->cfi), - kernelLine->indent, initrd); + enum lineType_e lt; + switch(kernelLine->type) { + case LT_KERNEL: + lt = LT_INITRD; + break; + case LT_KERNEL_EFI: + lt = LT_INITRD_EFI; + break; + case LT_KERNEL_16: + lt = LT_INITRD_16; + break; + default: + lt = preferredLineType(LT_INITRD, cfg->cfi); + } + line = addLine(entry, cfg->cfi, lt, kernelLine->indent, initrd); if (!line) return 1; if (endLine) { @@ -3639,7 +3715,8 @@ const char * newKernelPath, const char * newKernelTitle, const char * newKernelArgs, const char * newKernelInitrd, const char ** extraInitrds, int extraInitrdCount, - const char * newMBKernel, const char * newMBKernelArgs) { + const char * newMBKernel, const char * newMBKernelArgs, + const char * newDevTreePath) { struct singleEntry * new; struct singleLine * newLine = NULL, * tmplLine = NULL, * masterLine = NULL; int needs; @@ -3680,6 +3757,8 @@ needs |= NEED_MB; new->multiboot = 1; } + if (newDevTreePath && getKeywordByType(LT_DEVTREE, config->cfi)) + needs |= NEED_DEVTREE; if (template) { for (masterLine = template->lines; @@ -3865,6 +3944,21 @@ newLine = addLineTmpl(new, tmplLine, newLine, NULL, config->cfi); } + } else if (tmplLine->type == LT_DEVTREE && + tmplLine->numElements == 2 && newDevTreePath) { + newLine = addLineTmpl(new, tmplLine, newLine, + newDevTreePath + strlen(prefix), + config->cfi); + needs &= ~NEED_DEVTREE; + } else if (tmplLine->type == LT_ENTRY_END && needs & NEED_DEVTREE) { + const char *ndtp = newDevTreePath; + if (!strncmp(newDevTreePath, prefix, strlen(prefix))) + ndtp += strlen(prefix); + newLine = addLine(new, config->cfi, LT_DEVTREE, + config->secondaryIndent, + ndtp); + needs &= ~NEED_DEVTREE; + newLine = addLineTmpl(new, tmplLine, newLine, NULL, config->cfi); } else { /* pass through other lines from the template */ newLine = addLineTmpl(new, tmplLine, newLine, NULL, config->cfi); @@ -3878,6 +3972,7 @@ switch (config->cfi->entryStart) { case LT_KERNEL: case LT_KERNEL_EFI: + case LT_KERNEL_16: if (new->multiboot && config->cfi->mbHyperFirst) { /* fall through to LT_HYPER */ } else { @@ -3984,12 +4079,19 @@ free(initrdVal); needs &= ~NEED_INITRD; } + if (needs & NEED_DEVTREE) { + newLine = addLine(new, config->cfi, LT_DEVTREE, + config->secondaryIndent, + newDevTreePath); + needs &= ~NEED_DEVTREE; + } + + /* NEEDS_END must be last on bootloaders that need it... */ if (needs & NEED_END) { newLine = addLine(new, config->cfi, LT_ENTRY_END, config->secondaryIndent, NULL); needs &= ~NEED_END; } - if (needs) { printf(_("grubby: needs=%d, aborting\n"), needs); abort(); @@ -4035,7 +4137,7 @@ char * newKernelArgs = NULL; char * newKernelInitrd = NULL; char * newKernelTitle = NULL; - char * newKernelVersion = NULL; + char * newDevTreePath = NULL; char * newMBKernel = NULL; char * newMBKernelArgs = NULL; char * removeMBKernelArgs = NULL; @@ -4093,6 +4195,8 @@ _("display the index of the default kernel") }, { "default-title", 0, 0, &displayDefaultTitle, 0, _("display the title of the default kernel") }, + { "devtree", 0, POPT_ARG_STRING, &newDevTreePath, 0, + _("device tree file for new stanza"), _("dtb-path") }, { "elilo", 0, POPT_ARG_NONE, &configureELilo, 0, _("configure elilo bootloader") }, { "efi", 0, POPT_ARG_NONE, &isEfi, 0, @@ -4258,7 +4362,7 @@ grubConfig = cfi->defaultConfig; } - if (bootloaderProbe && (displayDefault || kernelInfo || newKernelVersion || + if (bootloaderProbe && (displayDefault || kernelInfo || newKernelPath || removeKernelPath || makeDefault || defaultKernel || displayDefaultIndex || displayDefaultTitle || (defaultIndex >= 0))) { @@ -4267,7 +4371,7 @@ return 1; } - if ((displayDefault || kernelInfo) && (newKernelVersion || newKernelPath || + if ((displayDefault || kernelInfo) && (newKernelPath || removeKernelPath)) { fprintf(stderr, _("grubby: --default-kernel and --info may not " "be used when adding or removing kernels\n")); @@ -4436,7 +4540,7 @@ if (!entry) return 0; if (!suitableImage(entry, bootPrefix, 0, flags)) return 0; - line = getLineByType(LT_KERNEL|LT_HYPER|LT_KERNEL_EFI, entry->lines); + line = getLineByType(LT_KERNEL|LT_HYPER|LT_KERNEL_EFI|LT_KERNEL_16, entry->lines); if (!line) return 0; rootspec = getRootSpecifier(line->elements[1].item); @@ -4497,13 +4601,20 @@ if (updateImage(config, updateKernelPath, bootPrefix, newKernelArgs, removeArgs, newMBKernelArgs, removeMBKernelArgs)) return 1; if (updateKernelPath && newKernelInitrd) { - if (updateInitrd(config, updateKernelPath, bootPrefix, - newKernelInitrd)) return 1; + if (newMBKernel) { + if (addMBInitrd(config, newMBKernel, updateKernelPath, + bootPrefix, newKernelInitrd)) + return 1; + } else { + if (updateInitrd(config, updateKernelPath, bootPrefix, + newKernelInitrd)) + return 1; + } } if (addNewKernel(config, template, bootPrefix, newKernelPath, newKernelTitle, newKernelArgs, newKernelInitrd, (const char **)extraInitrds, extraInitrdCount, - newMBKernel, newMBKernelArgs)) return 1; + newMBKernel, newMBKernelArgs, newDevTreePath)) return 1; if (numEntries(config) == 0) {