Increase grub timeout
Matthew Garrett
mjg at redhat.com
Wed May 19 18:10:06 UTC 2010
This patch, that is.
--
Matthew Garrett | mjg59 at srcf.ucam.org
-------------- next part --------------
diff -ur grub-0.97.clean/stage2/asm.S grub-0.97/stage2/asm.S
--- grub-0.97.clean/stage2/asm.S 2010-05-19 13:18:50.638314187 -0400
+++ grub-0.97/stage2/asm.S 2010-05-19 13:23:39.273210663 -0400
@@ -90,6 +90,8 @@
/* This variable is here only because of a historical reason. */
VARIABLE(saved_entryno)
.long 0
+VARIABLE(failed_boot)
+ .byte 0
VARIABLE(stage2_id)
.byte STAGE2_ID
VARIABLE(force_lba)
diff -ur grub-0.97.clean/stage2/builtins.c grub-0.97/stage2/builtins.c
--- grub-0.97.clean/stage2/builtins.c 2010-05-19 13:18:50.692309957 -0400
+++ grub-0.97/stage2/builtins.c 2010-05-19 13:37:36.757188824 -0400
@@ -78,13 +78,23 @@
int grub_timeout = -1;
/* Whether to show the menu or not. */
int show_menu = 1;
+/* The bootflag. */
+char grub_bootflag = 0;
/* The BIOS drive map. */
static unsigned short bios_drive_map[DRIVE_MAP_SIZE + 1];
/* Prototypes for allowing straightfoward calling of builtins functions
inside other functions. */
static int configfile_func (char *arg, int flags);
-
+#if !defined(SUPPORT_DISKLESS) && !defined(GRUB_UTIL) && !defined(PLATFORM_EFI)
+static int bootflag_get (char *bootflag);
+#else
+static int bootflag_get (char *bootflag)
+{
+ *bootflag = 0;
+ return 0;
+}
+#endif
/* Initialize the data for builtins. */
void
init_builtins (void)
@@ -104,6 +114,8 @@
fallback_entryno = -1;
fallback_entries[0] = -1;
grub_timeout = -1;
+ if (bootflag_get(&grub_bootflag))
+ grub_bootflag = 0;
}
/* Check a password for correctness. Returns 0 if password was
@@ -401,6 +413,206 @@
"Boot the OS/chain-loader which has been loaded."
};
+#if !defined(SUPPORT_DISKLESS) && !defined(GRUB_UTIL) && !defined(PLATFORM_EFI)
+/* Get current boot flag from stage2 */
+static int
+bootflag_get(char *value)
+{
+ char *bootflag_ptr
+
+ /* Get the geometry of the boot drive (i.e. the disk which contains
+ this stage2). */
+ if (get_diskinfo (boot_drive, &buf_geom))
+ {
+ errnum = ERR_NO_DISK;
+ return 1;
+ }
+
+ /* Load the second sector of this stage2. */
+ if (! rawread (boot_drive, install_second_sector, 0, SECTOR_SIZE, buffer))
+ {
+ return 1;
+ }
+
+ /* Sanity check. */
+ if (buffer[STAGE2_STAGE2_ID] != STAGE2_ID_STAGE2
+ || *((short *) (buffer + STAGE2_VER_MAJ_OFFS)) != COMPAT_VERSION)
+ {
+ errnum = ERR_BAD_VERSION;
+ return 1;
+ }
+
+ bootflag_ptr = (char *) (buffer + STAGE2_FAILED_BOOT);
+ *value = *bootflag_ptr;
+ return 0;
+}
+
+/* Write boot flag into stage2 */
+static int
+bootflag_helper(int value)
+{
+ char *bootflag_ptr;
+
+ /* Get the geometry of the boot drive (i.e. the disk which contains
+ this stage2). */
+ if (get_diskinfo (boot_drive, &buf_geom))
+ {
+ errnum = ERR_NO_DISK;
+ return 1;
+ }
+
+ /* Load the second sector of this stage2. */
+ if (! rawread (boot_drive, install_second_sector, 0, SECTOR_SIZE, buffer))
+ {
+ return 1;
+ }
+
+ /* Sanity check. */
+ if (buffer[STAGE2_STAGE2_ID] != STAGE2_ID_STAGE2
+ || *((short *) (buffer + STAGE2_VER_MAJ_OFFS)) != COMPAT_VERSION)
+ {
+ errnum = ERR_BAD_VERSION;
+ return 1;
+ }
+
+ bootflag_ptr = (char *) (buffer + STAGE2_FAILED_BOOT);
+
+ *bootflag_ptr = value;
+
+ /* Save the image in the disk. */
+ if (! rawwrite (boot_drive, install_second_sector, buffer))
+ return 1;
+
+ /* Clear the cache. */
+ buf_track = -1;
+
+ return 0;
+}
+#endif
+
+#if !defined(SUPPORT_DISKLESS) && defined(GRUB_UTIL)
+static int
+bootflag_shell(char *arg, int flags)
+{
+ char *stage2_os_file = "/boot/grub/stage2"; /* Default filename */
+ FILE *fp;
+ char buffer[512];
+ char *bootflag_ptr;
+ int new_bootflag;
+
+ while (1)
+ {
+ if (grub_memcmp ("--stage2=", arg, sizeof ("--stage2=") - 1) == 0)
+ {
+ stage2_os_file = arg + sizeof ("--stage2=") - 1;
+ arg = skip_to (0, arg);
+ nul_terminate (stage2_os_file);
+ }
+ else if (grub_memcmp ("--bootflag=", arg, sizeof ("--bootflag=") - 1) == 0)
+ {
+ char *p = arg + sizeof ("--bootflag=") - 1;
+ if (! safe_parse_maxint (&p, &new_bootflag))
+ return 1;
+ arg = skip_to (0, arg);
+ }
+ else
+ break;
+ }
+
+ if (! (fp = fopen(stage2_os_file, "r+")))
+ {
+ errnum = ERR_FILE_NOT_FOUND;
+ return 1;
+ }
+
+ if (fseek (fp, SECTOR_SIZE, SEEK_SET) != 0)
+ {
+ fclose (fp);
+ errnum = ERR_BAD_VERSION;
+ return 1;
+ }
+
+ if (fread (buffer, 1, SECTOR_SIZE, fp) != SECTOR_SIZE)
+ {
+ fclose (fp);
+ errnum = ERR_READ;
+ return 1;
+ }
+
+ /* Sanity check. */
+ if (buffer[STAGE2_STAGE2_ID] != STAGE2_ID_STAGE2
+ || *((short *) (buffer + STAGE2_VER_MAJ_OFFS)) != COMPAT_VERSION)
+ {
+ errnum = ERR_BAD_VERSION;
+ return 1;
+ }
+
+ bootflag_ptr = (char *) (buffer + STAGE2_FAILED_BOOT);
+
+ *bootflag_ptr = new_bootflag;
+
+ if (fseek (fp, SECTOR_SIZE, SEEK_SET) != 0)
+ {
+ fclose (fp);
+ errnum = ERR_BAD_VERSION;
+ return 1;
+ }
+
+ if (fwrite (buffer, 1, SECTOR_SIZE, fp) != SECTOR_SIZE)
+ {
+ fclose (fp);
+ errnum = ERR_WRITE;
+ return 1;
+ }
+
+ (void)fflush (fp);
+ fclose (fp);
+ return 0;
+}
+#endif
+
+/* bootflag */
+static int
+bootflag_func (char *arg, int flags)
+{
+#if !defined(SUPPORT_DISKLESS)
+#if !defined(GRUB_UTIL)
+#if !defined(PLATFORM_EFI)
+ /* This command is only useful when you boot an entry from the menu
+ interface. */
+ if (! (flags & BUILTIN_SCRIPT))
+ {
+ errnum = ERR_UNRECOGNIZED;
+ return 1;
+ }
+
+ return bootflag_helper(1);
+#else /* defined(PLATFORM_EFI) */
+ return 1; /* FIXME EFI support */
+#endif
+#else /* defined(GRUB_UTIL) */
+ return bootflag_shell(arg, flags);
+#endif
+#else /* ! SUPPORT_DISKLESS && ! GRUB_UTIL */
+ errnum = ERR_UNRECOGNIZED;
+ return 1;
+#endif /* ! SUPPORT_DISKLESS && ! GRUB_UTIL */
+}
+
+static struct builtin builtin_bootflag =
+{
+ "bootflag",
+ bootflag_func,
+ BUILTIN_CMDLINE,
+#ifdef GRUB_UTIL
+ "bootflag [--stage2=STAGE2_FILE] [--bootflag=DEFAULT]",
+ "Set DEFAULT as the bootflag entry in STAGE2_FILE."
+#else
+ "bootflag",
+ "Set the stage 2 bootflag to 1."
+#endif
+};
+
#ifdef SUPPORT_NETBOOT
/* bootp */
@@ -4975,6 +5187,13 @@
/* One-shot default shenanigans -- don't piss around with the menu! */
if (grub_timeout != -1)
return 0;
+
+ if (grub_bootflag != 0)
+ {
+ grub_timeout = 30;
+ return 0;
+ }
+
if ((saved_entryno & STAGE2_ONCEONLY_ENTRY) != 0)
{
grub_timeout = 0;
@@ -5185,6 +5404,7 @@
#endif
&builtin_blocklist,
&builtin_boot,
+ &builtin_bootflag,
#ifdef SUPPORT_NETBOOT
&builtin_bootp,
#endif /* SUPPORT_NETBOOT */
diff -ur grub-0.97.clean/stage2/shared.h grub-0.97/stage2/shared.h
--- grub-0.97.clean/stage2/shared.h 2010-05-19 13:18:50.699309128 -0400
+++ grub-0.97/stage2/shared.h 2010-05-19 13:32:55.436310548 -0400
@@ -197,9 +197,10 @@
#define STAGE2_VER_MAJ_OFFS 0x6
#define STAGE2_INSTALLPART 0x8
#define STAGE2_SAVED_ENTRYNO 0xc
-#define STAGE2_STAGE2_ID 0x10
-#define STAGE2_FORCE_LBA 0x11
-#define STAGE2_VER_STR_OFFS 0x12
+#define STAGE2_FAILED_BOOT 0x10
+#define STAGE2_STAGE2_ID 0x11
+#define STAGE2_FORCE_LBA 0x12
+#define STAGE2_VER_STR_OFFS 0x13
#define STAGE2_ONCEONLY_ENTRY 0x10000
@@ -881,6 +882,7 @@
extern kernel_t kernel_type;
extern int show_menu;
extern int grub_timeout;
+extern char grub_bootflag;
void init_builtins (void);
void init_config (void);
More information about the devel
mailing list