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 /