I've implemented additional patch for /sbin/grub, and now it can
load a config file and provide the menu. This patch is incomplete yet,
but I think it's useful. Currently I know these bugs:

* the line the cursor points to is not reversed correctly. (Why???
  Possibly ncurses' bug?)
* install_partition and boot_drive are not changed even when the user
  specify a config file by --config-file option. (Just because I haven't
  implemented that)
* /sbin/grub waits for keyboard input without sleep, so it consumes
  much of cpu time.
* The configure script doesn't check if ungetch is broken or not. That
  is required because old ncurses (1.9.9) has the bug.


diff -urN grub.orig/ChangeLog grub/ChangeLog
--- grub.orig/ChangeLog Sat Mar 27 03:40:40 1999
+++ grub/ChangeLog      Sat Mar 27 02:14:31 1999
@@ -1,3 +1,45 @@
+1999-03-26  OKUJI Yoshinori  <[EMAIL PROTECTED]>
+
+       * grub/asmstub.c (grub_stage2) [HAVE_LIBCURSES]: Call nodelay.
+       (checkkey) [HAVE_LIBCURSES]: If getting an input character, then
+       ungetch it, because checkkey shouldn't modify the input queue.
+       
+1999-03-26  OKUJI Yoshinori  <[EMAIL PROTECTED]>
+
+       Use file descriptors instead of file pointers to support
+       >4GB disks in Linux.
+       
+       * grub/asmstub.c (grub_stage2): Call close instead of fclose.
+       (get_diskinfo): Call open instead of fopen.
+       (biosdisk) [__linux__]: Use _llseek instead of lseek.
+       (biosdisk): Call read instead of fread.
+
+       Add options so that the user can specify the config file.
+
+       * grub/Makefile.am (CPPFLAGS): Use -fwritable-strings, because
+       grub assumes that all strings resides at the data section.
+       
+       * grub/main.c: Define NO_REMAPPING_LIBC_FUNCTIONS before including
+       shared.h.
+       (OPT_CONFIG_FILE): New macro.
+       (OPT_INSTALL_PARTITION): Likewise.
+       (OPT_BOOT_DRIVE): Likewise.
+       (longopts): Add new options, config-file, install-partition and
+       boot-drive.
+       (usage): Add the documentation for them.
+       (main): Add handling code for OPT_CONFIG_FILE, OPT_INSTALL_PARTITION
+       and OPT_BOOT_DRIVE.
+
+       * grub/asmstub.c: Define NO_REMAPPING_LIBC_FUNCTIONS before including
+       shared.h.
+       (config_file): Make it char * instead of char [].
+       (getrtsecs): Return current time instead of 0xff.
+
+       * shared_src/shared.h [NO_REMAPPING_LIBC_FUNCTIONS]: Don't define
+       libc-API-compatible function names.
+       (config_file): Change the prototype from char [] to char *.
+       (grub_putchar): Renamed from putchar.
+       
 1999-03-25  OKUJI Yoshinori  <[EMAIL PROTECTED]>
 
        * char_io.c (get_cmdline): Call cl_setcpos even if lpos == llen,
diff -urN grub.orig/grub/Makefile.am grub/grub/Makefile.am
--- grub.orig/grub/Makefile.am  Sun Mar 14 12:31:56 1999
+++ grub/grub/Makefile.am       Fri Mar 26 16:44:03 1999
@@ -4,6 +4,7 @@
 
 COMPILE = $(CC) -DGRUB_UTIL=1 $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)
 INCLUDES = -I$(top_srcdir)/shared_src
+CPPFLAGS += -fwritable-strings
 
 grub_SOURCES = main.c asmstub.c
 grub_LDADD = boot.o common.o char_io.o cmdline.o disk_io.o gunzip.o \
diff -urN grub.orig/grub/Makefile.in grub/grub/Makefile.in
--- grub.orig/grub/Makefile.in  Sun Mar 14 12:31:56 1999
+++ grub/grub/Makefile.in       Fri Mar 26 16:44:07 1999
@@ -294,6 +294,7 @@
 clean-generic maintainer-clean-generic clean mostlyclean distclean \
 maintainer-clean
 
+CPPFLAGS += -fwritable-strings
 
 @SHARED_SRC_RULES@
 
diff -urN grub.orig/grub/asmstub.c grub/grub/asmstub.c
--- grub.orig/grub/asmstub.c    Mon Mar 22 08:50:31 1999
+++ grub/grub/asmstub.c Sat Mar 27 02:17:03 1999
@@ -21,27 +21,22 @@
 /* Simulator entry point. */
 int grub_stage2 (void);
 
+#define NO_REMAPPING_LIBC_FUNCTIONS
 #include "shared.h"
-/* We want to prevent any circularararity in our stubs, as well as
-   libc name clashes. */
-#undef NULL
-#undef bcopy
-#undef bzero
-#undef getc
-#undef isspace
-#undef printf
-#undef putchar
-#undef strncat
-#undef strstr
-#undef tolower
 
 #include <stdlib.h>
 #include <assert.h>
 #include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <time.h>
 
 #ifdef __linux__
 # include <sys/ioctl.h>                /* ioctl */
 # include <linux/hdreg.h>      /* HDIO_GETGEO */
+# include <unistd.h>
+# include <linux/unistd.h>     /* _llseek */
 #endif /* __linux__ */
 
 /* Simulated memory sizes. */
@@ -59,7 +54,7 @@
 unsigned long install_partition = 0x20000;
 unsigned long boot_drive = 0;
 char version_string[] = "0.5";
-char config_file[] = "/boot/grub/menu.lst";
+char *config_file = "/boot/grub/menu.lst";
 
 /* Emulation requirements. */
 char *grub_scratch_mem = 0;
@@ -128,6 +123,7 @@
   nonl ();
   scrollok (stdscr, TRUE);
   keypad (stdscr, TRUE);
+  nodelay (stdscr, TRUE);
 #endif
 
   /* Set our stack, and go for it. */
@@ -138,10 +134,10 @@
   endwin ();
 #endif
 
-  /* Close off the file pointers we used. */
+  /* Close off the file descriptors we used. */
   for (i = 0; i < NUM_DISKS; i ++)
     if (disks[i].flags)
-      fclose ((FILE *) disks[i].flags);
+      close (disks[i].flags);
 
   /* Release memory. */
   free (disks);
@@ -275,7 +271,8 @@
 int
 getrtsecs (void)
 {
-  return 0xff;
+  /* XXX the exact value is not important, so just return time_t.  */
+  return time (0);
 }
 
 
@@ -346,7 +343,12 @@
 checkkey (void)
 {
 #ifdef HAVE_LIBCURSES
-  return getch ();
+  int c;
+  c = getch ();
+  /* If C is not ERR, then put it back in the input queue.  */
+  if (c != ERR)
+    ungetch (c);       /* XXX the ungetch of ncurses-1.9.9g is buggy.  */
+  return c;
 #else
   return getchar ();
 #endif
@@ -370,7 +372,7 @@
 {
   /* FIXME: this function is truly horrid.  We try opening the device,
      then severely abuse the GEOMETRY->flags field to pass a file
-     pointer to biosdisk.  Thank God nobody's looking at this comment,
+     descriptor to biosdisk.  Thank God nobody's looking at this comment,
      or my reputation would be ruined. --Gord */
 
   /* See if we have a cached device. */
@@ -412,16 +414,15 @@
       devname[8] = '\0';
 
       /* Open read/write, or read-only if that failed. */
-      disks[drive].flags = (int) fopen (devname, "r+");
+      disks[drive].flags = open (devname, O_RDWR);
       if (! disks[drive].flags)
-       disks[drive].flags = (int) fopen (devname, "r");
+       disks[drive].flags = open (devname, O_RDONLY);
 
       if (disks[drive].flags)
        {
 #ifdef __linux__
          struct hd_geometry hdg;
-         if (! ioctl (fileno ((FILE *) disks[drive].flags),
-                      HDIO_GETGEO, &hdg))
+         if (! ioctl (disks[drive].flags, HDIO_GETGEO, &hdg))
            {
              /* Got the geometry, so save it. */
              disks[drive].cylinders = hdg.cylinders;
@@ -462,19 +463,32 @@
          int sector, int nsec, int segment)
 {
   char *buf;
-  FILE *fp;
+  int fd;
 
-  /* Get the file pointer from the geometry, and make sure it matches. */
-  fp = (FILE *) geometry->flags;
-  if (! fp || fp != (FILE *) disks[drive].flags)
+  /* Get the file descriptor from the geometry, and make sure it matches. */
+  fd = geometry->flags;
+  if (! fd || fd != disks[drive].flags)
     return BIOSDISK_ERROR_GEOMETRY;
 
   /* Seek to the specified location. */
-  if (fseek (fp, sector * SECTOR_SIZE, SEEK_SET))
+#ifdef __linux__
+  /* In Linux, use 64bits seek.  */
+  {
+    loff_t offset, result;
+    _syscall5 (int, _llseek, uint, fd, ulong, hi, ulong, lo,
+              loff_t *, res, uint, wh);
+    
+    offset = (loff_t) sector * (loff_t) SECTOR_SIZE;
+    if (_llseek (fd, offset >> 32, offset & 0xffffffff, &result, SEEK_SET))
+      return -1;
+  }
+#else
+  if (lseek (fd, sector * SECTOR_SIZE, SEEK_SET))
     return -1;
+#endif /* __linux__ */
 
   buf = (char *) (segment << 4);
-  if (fread (buf, nsec * SECTOR_SIZE, 1, fp) != 1)
+  if (read (fd, buf, nsec * SECTOR_SIZE) != nsec * SECTOR_SIZE)
     return -1;
   return 0;
 }
diff -urN grub.orig/grub/main.c grub/grub/main.c
--- grub.orig/grub/main.c       Thu Mar 25 13:05:03 1999
+++ grub/grub/main.c    Fri Mar 26 16:40:59 1999
@@ -24,12 +24,21 @@
 #include <stdio.h>
 #include <getopt.h>
 #include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <limits.h>
+
+#define NO_REMAPPING_LIBC_FUNCTIONS
+#include "shared.h"
 
 char *program_name = 0;
 
 #define OPT_HELP -2
 #define OPT_VERSION -3
 #define OPT_HOLD -4
+#define OPT_CONFIG_FILE -5
+#define OPT_INSTALL_PARTITION -6
+#define OPT_BOOT_DRIVE -7
 #define OPTSTRING ""
 
 static struct option longopts[] =
@@ -37,6 +46,9 @@
   {"help", no_argument, 0, OPT_HELP},
   {"version", no_argument, 0, OPT_VERSION},
   {"hold", no_argument, 0, OPT_HOLD},
+  {"config-file", required_argument, 0, OPT_CONFIG_FILE},
+  {"install-partition", required_argument, 0, OPT_INSTALL_PARTITION},
+  {"boot-drive", required_argument, 0, OPT_BOOT_DRIVE},
   {0},
 };
 
@@ -53,9 +65,12 @@
 \n\
 Enter the GRand Unified Bootloader command shell.\n\
 \n\
-    --help                display this message and exit\n\
-    --hold                wait forever so that a debugger may be attached\n\
-    --version             print version information and exit\n\
+    --help                   display this message and exit\n\
+    --version                print version information and exit\n\
+    --hold                   wait until a debugger will attach\n\
+    --config-file=FILE       set config_file to FILE\n\
+    --install-partition=PAR  set install_partition to PAR\n\
+    --boot-drive=DRIVE       set boot_drive to DRIVE\n\
 ",
            program_name);
 
@@ -80,10 +95,6 @@
          /* Fall through the bottom of the loop. */
          break;
 
-       case OPT_HOLD:
-         hold = 1;
-         break;
-
        case OPT_HELP:
          usage (0);
          break;
@@ -93,13 +104,39 @@
          exit (0);
          break;
 
+       case OPT_HOLD:
+         hold = 1;
+         break;
+
+       case OPT_CONFIG_FILE:
+         config_file = strdup (optarg);
+         break;
+
+       case OPT_INSTALL_PARTITION:
+         install_partition = strtoul (optarg, 0, 16);
+         if (install_partition == ULONG_MAX)
+           {
+             perror ("strtoul");
+             exit (1);
+           }
+         break;
+
+       case OPT_BOOT_DRIVE:
+         boot_drive = strtoul (optarg, 0, 16);
+         if (boot_drive == ULONG_MAX)
+           {
+             perror ("strtoul");
+             exit (1);
+           }
+         break;
+         
        default:
          usage (1);
        }
     }
   while (c != EOF);
 
-  /* Wait until the HOLD variable is cleared by an attached debugger. */
+  /* Wait until clear the variable `hold' by a debugger.  */
   while (hold)
     sleep (1);
 
diff -urN grub.orig/shared_src/shared.h grub/shared_src/shared.h
--- grub.orig/shared_src/shared.h       Mon Mar 22 08:50:33 1999
+++ grub/shared_src/shared.h    Fri Mar 26 15:57:11 1999
@@ -203,6 +203,7 @@
 
 /* Remap some libc-API-compatible function names so that we can use
    them alongside their libc counterparts. */
+#ifndef NO_REMAPPING_LIBC_FUNCTIONS
 #define bcopy grub_bcopy
 #define bzero grub_bzero
 #define isspace grub_isspace
@@ -212,7 +213,7 @@
 #define strncat grub_strncat
 #define strstr grub_strstr
 #define tolower grub_tolower
-
+#endif /* ! NO_REMAPPING_LIBC_FUNCTIONS */
 
 #ifndef ASM_FILE
 /*
@@ -276,7 +277,7 @@
 extern unsigned long install_partition;
 extern unsigned long boot_drive;
 extern char version_string[];
-extern char config_file[];
+extern char *config_file;
 
 #ifndef STAGE1_5
 /* GUI interface variables. */
@@ -413,7 +414,7 @@
 
 /* Displays an ASCII character.  IBM displays will translate some
    characters to special graphical ones (see the DISP_* constants). */
-void putchar (int c);
+void grub_putchar (int c);
 
 /* Wait for a keypress, and return its packed BIOS/ASCII key code.
    Use ASCII_CHAR(ret) to extract the ASCII code. */


----------------------------------------------------------------------
OKUJI Yoshinori  <[EMAIL PROTECTED]>           ^o-o^
http://duff.kuicr.kyoto-u.ac.jp/~okuji (in English)     m /

Reply via email to