diff --git a/AUTHORS b/AUTHORS index 814fa088c..c13a49a6a 100644 --- a/AUTHORS +++ b/AUTHORS @@ -4,6 +4,12 @@ VaX#n8 (real name unknown) wrote shared_src/fsys_ext2fs.c. Heiko Schroeder rewrote shared_src/stage1.S to be more readable. +The following authors assigned copyright on their work to the Free +Software Foundation: + Gordon Matzigkeit adopted GRUB into the GNU Project. He fixed several bugs, added symbolic link support to shared_src/fsys_ext2fs.c, and -implemented the grub configuration program. +began the implementation of /sbin/grub. + +OKUJI Yoshinori contributed many bugfixes and new features, such as +working LBA support, and /sbin/grub support for configuration files. diff --git a/ChangeLog b/ChangeLog index 2a9fad0ff..3553bbfc6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,57 @@ +1999-03-27 Gordon Matzigkeit + + * grub/main.c (usage): Display defaults for stage2 options. + + * grub/asmstub.c [NO_REMAPPING_LIBC_FUNCTIONS]: Rename to + WITHOUT_LIBC_STUBS. + * grub/main.c: Likewise. + * shared_src/shared.h: Likewise. + +1999-03-27 OKUJI Yoshinori + + * grub/asmstub.c (set_attrib): Use inch and addch, instead of + chgat, because chgat doesn't work as expected. + +1999-03-26 OKUJI Yoshinori + + * 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. + + 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 * char_io.c (get_cmdline): Call cl_setcpos even if lpos == llen, diff --git a/grub/Makefile.am b/grub/Makefile.am index e28f98c5d..131341e75 100644 --- a/grub/Makefile.am +++ b/grub/Makefile.am @@ -2,7 +2,7 @@ EXTRA_PROGRAMS = grub sbin_PROGRAMS = $(sbingrub) CLEANFILES = $(EXTRA_PROGRAMS) -COMPILE = $(CC) -DGRUB_UTIL=1 $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) +COMPILE = $(CC) -DGRUB_UTIL=1 -fwritable-strings $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) INCLUDES = -I$(top_srcdir)/shared_src grub_SOURCES = main.c asmstub.c diff --git a/grub/Makefile.in b/grub/Makefile.in index 2e30427ab..8e3a7c506 100644 --- a/grub/Makefile.in +++ b/grub/Makefile.in @@ -74,7 +74,7 @@ EXTRA_PROGRAMS = grub sbin_PROGRAMS = $(sbingrub) CLEANFILES = $(EXTRA_PROGRAMS) -COMPILE = $(CC) -DGRUB_UTIL=1 $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) +COMPILE = $(CC) -DGRUB_UTIL=1 -fwritable-strings $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) INCLUDES = -I$(top_srcdir)/shared_src grub_SOURCES = main.c asmstub.c diff --git a/grub/asmstub.c b/grub/asmstub.c index eb44d0431..b29335078 100644 --- a/grub/asmstub.c +++ b/grub/asmstub.c @@ -18,30 +18,31 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +/* Try to use glibc's transparant LFS support. */ +#define _LARGEFILE_SOURCE 1 + /* Simulator entry point. */ int grub_stage2 (void); -#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 +#define WITHOUT_LIBC_STUBS 1 +#include "shared.h" #include #include #include +#include +#include +#include +#include #ifdef __linux__ # include /* ioctl */ # include /* HDIO_GETGEO */ +/* FIXME: only include if libc doesn't have large file support. */ +# include +# include /* _llseek */ #endif /* __linux__ */ /* Simulated memory sizes. */ @@ -59,7 +60,7 @@ int grub_stage2 (void); 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 +129,7 @@ grub_stage2 (void) nonl (); scrollok (stdscr, TRUE); keypad (stdscr, TRUE); + nodelay (stdscr, TRUE); #endif /* Set our stack, and go for it. */ @@ -138,10 +140,10 @@ grub_stage2 (void) 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 ((FILE *) disks[i].flags); /* Release memory. */ free (disks); @@ -275,7 +277,8 @@ get_mmap_entry (struct mmar_desc *desc, int cont) int getrtsecs (void) { - return 0xff; + /* FIXME: exact value is not important, so just return time_t for now. */ + return time (0); } @@ -346,9 +349,15 @@ int 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); /* FIXME: ncurses-1.9.9g ungetch is buggy. */ + return c; #else - return getchar (); + /* Just pretend they hit the space bar. + return ' '; #endif } @@ -358,7 +367,13 @@ void set_attrib (int attr) { #ifdef HAVE_LIBCURSES + /* FIXME: I don't know why, but chgat doesn't work as expected, so + use this dirty way... - okuji */ + chtype ch = inch (); + addch ((ch & A_CHARTEXT) | attr); +# if 0 chgat (1, attr, 0, NULL); +# endif #endif } @@ -370,7 +385,7 @@ get_diskinfo (int drive, struct geometry *geometry) { /* 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 +427,15 @@ get_diskinfo (int drive, struct geometry *geometry) 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 +476,32 @@ biosdisk (int subfunc, int drive, struct geometry *geometry, int sector, int nsec, int segment) { char *buf; - FILE *fp; + int fd = geometry->flags; /* Get the file pointer from the geometry, and make sure it matches. */ - fp = (FILE *) geometry->flags; - if (! fp || fp != (FILE *) disks[drive].flags) + if (fd == -1 || fd != disks[drive].flags) return BIOSDISK_ERROR_GEOMETRY; /* Seek to the specified location. */ - if (fseek (fp, sector * SECTOR_SIZE, SEEK_SET)) - return -1; +#ifdef __linux__ + /* FIXME: only use this section if libc doesn't have large file support */ + { + 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) + /* FIXME: handle EINTR */ + if (read (fd, buf, nsec * SECTOR_SIZE, fp) != nsec * SECTOR_SIZE) return -1; return 0; } diff --git a/grub/main.c b/grub/main.c index 50b90edac..71b0b8a1e 100644 --- a/grub/main.c +++ b/grub/main.c @@ -24,12 +24,24 @@ int grub_stage2 (void); #include #include #include +#include +#include +#include + +#define WITHOUT_LIBC_STUBS 1 +#include "shared.h" char *program_name = 0; +static int default_boot_drive; +static int default_install_partition; +static char *default_config_file; #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 +49,9 @@ static struct option longopts[] = {"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,11 +68,15 @@ Usage: %s [OPTION]...\n\ \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\ + --boot-drive=DRIVE specify stage2 boot_drive [default=0x%x]\n\ + --config-file=FILE specify stage2 config_file [default=%s]\n\ + --help display this message and exit\n\ + --hold wait until a debugger will attach\n\ + --install-partition=PAR specify stage2 install_partition [default=0x%x]\n\ + --version print version information and exit\n\ ", - program_name); + program_name, default_boot_drive, default_config_file, + default_install_partition); exit (status); } @@ -69,6 +88,12 @@ main (int argc, char **argv) int c; int hold = 0; program_name = argv[0]; + default_boot_drive = boot_drive; + default_install_partition = install_partition; + if (config_file) + default_config_file = config_file; + else + default_config_file = "NONE"; /* Parse command-line options. */ do @@ -80,10 +105,6 @@ main (int argc, char **argv) /* Fall through the bottom of the loop. */ break; - case OPT_HOLD: - hold = 1; - break; - case OPT_HELP: usage (0); break; @@ -93,6 +114,32 @@ main (int argc, char **argv) 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, 0); + if (boot_drive == ULONG_MAX) + { + perror ("strtoul"); + exit (1); + } + break; + default: usage (1); } diff --git a/shared_src/shared.h b/shared_src/shared.h index 74f8767bd..61c6bb15a 100644 --- a/shared_src/shared.h +++ b/shared_src/shared.h @@ -201,8 +201,9 @@ extern char *grub_scratch_mem; #define DISP_UP 0x18 #define DISP_DOWN 0x19 -/* Remap some libc-API-compatible function names so that we can use - them alongside their libc counterparts. */ +/* Remap some libc-API-compatible function names so that we prevent + circularararity. */ +#ifndef WITHOUT_LIBC_STUBS #define bcopy grub_bcopy #define bzero grub_bzero #define isspace grub_isspace @@ -212,6 +213,7 @@ extern char *grub_scratch_mem; #define strncat grub_strncat #define strstr grub_strstr #define tolower grub_tolower +#endif /* WITHOUT_LIBC_STUBS */ #ifndef ASM_FILE @@ -276,7 +278,7 @@ typedef enum 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 +415,7 @@ void gotoxy (int x, int y); /* 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. */