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