--- trunk/grubby/grubby.c 2012/02/18 00:32:14 1714 +++ trunk/grubby/grubby.c 2012/02/18 00:49:41 1718 @@ -51,6 +51,9 @@ #define MAX_EXTRA_INITRDS 16 /* code segment checked by --bootloader-probe */ #define CODE_SEG_SIZE 128 /* code segment checked by --bootloader-probe */ +#define NOOP_OPCODE 0x90 +#define JMP_SHORT_OPCODE 0xeb + /* comments get lumped in with indention */ struct lineElement { char * item; @@ -156,8 +159,30 @@ { NULL, 0, 0 }, }; +const char *grubFindConfig(struct configFileInfo *cfi) { + static const char *configFiles[] = { + "/etc/grub.conf", + "/boot/grub/grub.conf", + "/boot/grub/menu.lst", + NULL + }; + static int i = -1; + + if (i == -1) { + for (i = 0; configFiles[i] != NULL; i++) { + dbgPrintf("Checking \"%s\": ", configFiles[i]); + if (!access(configFiles[i], R_OK)) { + dbgPrintf("found\n"); + return configFiles[i]; + } + dbgPrintf("not found\n"); + } + } + return configFiles[i]; +} + struct configFileInfo grubConfigType = { - .defaultConfig = "/boot/grub/grub.conf", + .findConfig = grubFindConfig, .keywords = grubKeywords, .defaultIsIndex = 1, .defaultSupportSaved = 1, @@ -2446,12 +2471,22 @@ if (memcmp(boot, bootSect, 3)) return 0; - if (boot[1] == 0xeb) { + if (boot[1] == JMP_SHORT_OPCODE) { offset = boot[2] + 2; } else if (boot[1] == 0xe8 || boot[1] == 0xe9) { offset = (boot[3] << 8) + boot[2] + 2; - } else if (boot[0] == 0xeb) { - offset = boot[1] + 2; + } else if (boot[0] == JMP_SHORT_OPCODE) { + offset = boot[1] + 2; + /* + * it looks like grub, when copying stage1 into the mbr, patches stage1 + * right after the JMP location, replacing other instructions such as + * JMPs for NOOPs. So, relax the check a little bit by skipping those + * different bytes. + */ + if ((bootSect[offset + 1] == NOOP_OPCODE) + && (bootSect[offset + 2] == NOOP_OPCODE)) { + offset = offset + 3; + } } else if (boot[0] == 0xe8 || boot[0] == 0xe9) { offset = (boot[2] << 8) + boot[1] + 2; } else { @@ -3343,7 +3378,7 @@ defaultKernel = NULL; } - if (!strcmp(grubConfig, "-") && !outputFile) { + if (grubConfig && !strcmp(grubConfig, "-") && !outputFile) { fprintf(stderr, _("grubby: output file must be specified if stdin " "is used\n")); return 1; @@ -3390,8 +3425,9 @@ gr2c = checkForGrub2(gconfig); } - if (!access(grubConfigType.defaultConfig, F_OK)) { - gconfig = readConfig(grubConfigType.defaultConfig, &grubConfigType); + const char *grubconfig = grubFindConfig(&grubConfigType); + if (!access(grubconfig, F_OK)) { + gconfig = readConfig(grubconfig, &grubConfigType); if (!gconfig) grc = 1; else