diff --git a/ChangeLog b/ChangeLog index 6f84d46ef..773e61094 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,31 @@ +1999-09-11 OKUJI Yoshinori + + From Pavel Roskin: + * stage2/builtins.c (device_func) [GRUB_UTIL]: Use check_device + in order to make sure that DEVICE exists. + * grub/asmstub.c (check_device): New function. + (grub_stage2): Use check_device to probe a device. + + * stage2/builtins.c (geometry_func) [GRUB_UTIL]: Copy the + modified geometry to GEOM and reset BUF_DRIVE. Reported by Pavel + Roskin. + + * grub/main.c (no_floppy): New variable. + (probe_second_floppy): Likewise. + (OPT_NO_FLOPPY): New macro. + (OPT_PROBE_SECOND_FLOPPY): Likewise. + (longopts): Added no-floppy and probe-second-floppy. + (usage): Added the descriptions about --no-floppy and + --probe-second-floppy. + (main): Handle OPT_PROBE_SECOND_FLOPPY and OPT_NO_FLOPPY. + * grub/asmstub.c (grub_stage2): Print a message before the probe + routine. If NO_FLOPPY is non-zero, do not probe any floppy drive. + If PROBE_SECOND_FLOPPY is zero, skip the probe of the second + floppy drive. + (get_floppy_disk_name): New function. + (get_ide_disk_name): Likewise. + (get_scsi_disk_name): Likewise. + 1999-09-10 OKUJI Yoshinori * stage2/builtins.c (device_func): New function. diff --git a/NEWS b/NEWS index 9d1ccd12e..b8659b38c 100644 --- a/NEWS +++ b/NEWS @@ -4,7 +4,8 @@ New in 0.5.93: * ELF format of FreeBSD kernel is supported. * Support the partition ids for NetBSD and OpenBSD. * Exit from the grub shell just by pushing the key `q' in the menu. -* New options for configure can disable some functions in Stage 2. +* New options for configure can disable some functions in Stage 2. See + the output from `configure --help' for more information. * FAT32 support is added. * Minix fs support is added. * New commands "hide" and "unhide". @@ -18,6 +19,9 @@ New in 0.5.93: * The command "configfile" loads a configuration file interactively. * The command "device" assigns a BIOS drive to an arbitrary filename in the grub shell. +* The option `--no-floppy' force the grub shell to assume that there is + no floppy, and the option `--probe-second-floppy' enables the probe of + the second floppy drive. New in 0.5.92 - 1999-07-26: * Bug fixes (i.e. Stage 1.5 can work fine again). diff --git a/grub/asmstub.c b/grub/asmstub.c index 70d1e9dc4..130bee35e 100644 --- a/grub/asmstub.c +++ b/grub/asmstub.c @@ -81,6 +81,11 @@ char **device_map = 0; /* The jump buffer for exiting correctly. */ static jmp_buf env_for_exit; +/* Forward declarations. */ +static void get_floppy_disk_name (char *name, int unit); +static void get_ide_disk_name (char *name, int unit); +static void get_scsi_disk_name (char *name, int unit); + /* The main entry point into this mess. */ int grub_stage2 (void) @@ -141,77 +146,48 @@ grub_stage2 (void) for (i = 0; i < NUM_DISKS; i++) device_map[i] = 0; + /* Print something as the user does not think GRUB has been crashed. */ + fprintf (stderr, + "Probe devices to guess BIOS drives. This may take a long time.\n"); + /* Floppies. */ - assign_device_name (0, "/dev/fd0"); -#ifndef __linux__ - /* FIXME: leave linux out for now /dev/fd1 blocks for long time - if there is no second floppy ? */ - assign_device_name (1, "/dev/fd1"); -#endif + if (! no_floppy) + for (i = 0; i < 2; i++) + { + char name[16]; + if (i == 1 && ! probe_second_floppy) + break; + + get_floppy_disk_name (name, i); + if (check_device (name)) + assign_device_name (i, name); + } + /* IDE disks. */ for (i = 0; i < 4; i++) { - char name[10]; - FILE *fp; - char buf[512]; -#ifdef __linux__ - char unit = 'a' + i; -#elif defined(__GNU__) - char unit = '0' + i; -#else -#warning "BIOS drives cannot be guessed in your operating system." -#endif + char name[16]; - sprintf (name, "/dev/hd%c", unit); - fp = fopen (name, "r"); - if (! fp) + get_ide_disk_name (name, i); + if (check_device (name)) { - switch (errno) - { -#ifdef ENOMEDIUM - case ENOMEDIUM: -#if 0 - /* At the moment, this finds only CDROMs, which can't be - read anyway, so leave it out. Code should be - reactivated if `removable disks' and CDROMs are - supported. */ - /* register it, it may be inserted. */ - assign_device_name (num_hd++ + 0x80, name); -#endif - break; -#endif /* ENOMEDIUM */ - default: - /* break case and leave */ - break; - } - /* continue: there may be more disks sitting sparse on the - controllers */ - continue; + assign_device_name (num_hd + 0x80, name); + num_hd++; } - - /* Attempt to read the first sector. */ - if (fread (buf, 1, 512, fp) != 512) - { - fclose (fp); - break; - } - - fclose (fp); - assign_device_name (num_hd++ + 0x80, name); } - + /* The rest is SCSI disks. */ for (i = 0; i < 8; i++) { - char name[10]; + char name[16]; -#ifdef __linux__ - sprintf (name, "/dev/sd%c", i + 'a'); -#elif defined(__GNU__) - sprintf (name, "/dev/sd%d", i); -#endif - assign_device_name (num_hd++ + 0x80, name); + get_scsi_disk_name (name, i); + if (check_device (name)) + { + assign_device_name (num_hd + 0x80, name); + num_hd++; + } } /* Check some invariants. */ @@ -258,6 +234,8 @@ grub_stage2 (void) /* In Linux, invalidate the buffer cache. In other OSes, reboot is one of the solutions... */ ioctl (disks[i].flags, BLKFLSBUF, 0); +#else +# warning "In your operating system, the buffer cache will not be flushed." #endif close (disks[i].flags); } @@ -276,6 +254,96 @@ grub_stage2 (void) return status; } +/* These three functions are quite different among OSes. */ +static void +get_floppy_disk_name (char *name, int unit) +{ +#if defined(__linux__) || defined(__GNU__) + /* GNU/Linux and GNU/Hurd */ + sprintf (name, "/dev/fd%d", unit); +#else +# warning "BIOS drives cannot be guessed in your operating system." + /* Set NAME to a bogus string. */ + *name = 0; +#endif +} + +static void +get_ide_disk_name (char *name, int unit) +{ +#if defined(__linux__) + /* GNU/Linux */ + sprintf (name, "/dev/hd%c", unit + 'a'); +#elif defined(__GNU__) + /* GNU/Hurd */ + sprintf (name, "/dev/hd%d", unit); +#else +# warning "BIOS drives cannot be guessed in your operating system." + /* Set NAME to a bogus string. */ + *name = 0; +#endif +} + +static void +get_scsi_disk_name (char *name, int unit) +{ +#if defined(__linux__) + /* GNU/Linux */ + sprintf (name, "/dev/sd%c", unit + 'a'); +#elif defined(__GNU__) + /* GNU/Hurd */ + sprintf (name, "/dev/sd%d", unit); +#else +# warning "BIOS drives cannot be guessed in your operating system." + /* Set NAME to a bogus string. */ + *name = 0; +#endif +} + +/* Check if DEVICE can be read. If an error occurs, return zero, + otherwise return non-zero. */ +int +check_device (const char *device) +{ + char buf[512]; + FILE *fp; + + fp = fopen (device, "r"); + if (! fp) + { + switch (errno) + { +#ifdef ENOMEDIUM + case ENOMEDIUM: +# if 0 + /* At the moment, this finds only CDROMs, which can't be + read anyway, so leave it out. Code should be + reactivated if `removable disks' and CDROMs are + supported. */ + /* Accept it, it may be inserted. */ + return 1; +# endif + break; +#endif /* ENOMEDIUM */ + default: + /* Break case and leave. */ + break; + } + /* Error opening the device. */ + return 0; + } + + /* Attempt to read the first sector. */ + if (fread (buf, 1, 512, fp) != 512) + { + fclose (fp); + return 0; + } + + fclose (fp); + return 1; +} + /* Assign DRIVE to a device name DEVICE. */ void assign_device_name (int drive, const char *device) @@ -619,6 +687,9 @@ get_diskinfo (int drive, struct geometry *geometry) else /* FIXME: should have some other alternatives before using arbitrary defaults. */ +#else +# warning "In your operating system, automatic detection of geometries \ +will not be performed." #endif /* Set some arbitrary defaults. */ if (drive & 0x80) diff --git a/grub/main.c b/grub/main.c index ae1acfb83..29e84d060 100644 --- a/grub/main.c +++ b/grub/main.c @@ -36,6 +36,8 @@ int use_config_file = 1; int use_curses = 1; int verbose = 0; int read_only = 0; +int no_floppy = 0; +int probe_second_floppy = 0; static int default_boot_drive; static int default_install_partition; static char *default_config_file; @@ -51,21 +53,25 @@ static char *default_config_file; #define OPT_BATCH -10 #define OPT_VERBOSE -11 #define OPT_READ_ONLY -12 +#define OPT_PROBE_SECOND_FLOPPY -13 +#define OPT_NO_FLOPPY -14 #define OPTSTRING "" 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}, + {"batch", no_argument, 0, OPT_BATCH}, {"boot-drive", required_argument, 0, OPT_BOOT_DRIVE}, + {"config-file", required_argument, 0, OPT_CONFIG_FILE}, + {"help", no_argument, 0, OPT_HELP}, + {"hold", no_argument, 0, OPT_HOLD}, + {"install-partition", required_argument, 0, OPT_INSTALL_PARTITION}, {"no-config-file", no_argument, 0, OPT_NO_CONFIG_FILE}, {"no-curses", no_argument, 0, OPT_NO_CURSES}, - {"batch", no_argument, 0, OPT_BATCH}, - {"verbose", no_argument, 0, OPT_VERBOSE}, + {"no-floppy", no_argument, 0, OPT_NO_FLOPPY}, + {"probe-second-floppy", no_argument, 0, OPT_PROBE_SECOND_FLOPPY}, {"read-only", no_argument, 0, OPT_READ_ONLY}, + {"verbose", no_argument, 0, OPT_VERBOSE}, + {"version", no_argument, 0, OPT_VERSION}, {0}, }; @@ -89,6 +95,8 @@ Enter the GRand Unified Bootloader command shell.\n\ --install-partition=PAR specify stage2 install_partition [default=0x%x]\n\ --no-config-file do not use the config file\n\ --no-curses do not use curses\n\ + --no-floppy do not probe any floppy drive\n\ + --probe-second-floppy probe the second floppy drive\n\ --read-only do not write anything to devices\n\ --verbose print verbose messages\n\ --version print version information and exit\n\ @@ -188,6 +196,14 @@ main (int argc, char **argv) case OPT_VERBOSE: verbose = 1; break; + + case OPT_NO_FLOPPY: + no_floppy = 1; + break; + + case OPT_PROBE_SECOND_FLOPPY: + probe_second_floppy = 1; + break; default: usage (1); diff --git a/stage2/builtins.c b/stage2/builtins.c index 6482357f3..4433f64d7 100644 --- a/stage2/builtins.c +++ b/stage2/builtins.c @@ -300,7 +300,7 @@ device_func (char *arg, int flags) /* Get the device argument. */ device = skip_to (0, drive); - if (! *device) + if (! *device || ! check_device (device)) { errnum = ERR_FILE_NOT_FOUND; return 1; @@ -482,6 +482,9 @@ geometry_func (char *arg, int flags) disks[current_drive].total_sectors = num_cylinder * num_head * num_sector; errnum = 0; + + geom = disks[current_drive]; + buf_drive = -1; } #endif /* GRUB_UTIL */ diff --git a/stage2/shared.h b/stage2/shared.h index 7c72c821d..b59c742dc 100644 --- a/stage2/shared.h +++ b/stage2/shared.h @@ -334,10 +334,17 @@ extern int use_curses; extern int verbose; /* The flag for read-only. */ extern int read_only; +/* If this flag is true, assume that there is no floppy. */ +extern int no_floppy; +/* If this flag is true, probe the second floppy drive. */ +extern int probe_second_floppy; /* The map between BIOS drives and UNIX device file names. */ extern char **device_map; /* The array of geometries. */ extern struct geometry *disks; +/* Check if DEVICE can be read. If an error occurs, return zero, + otherwise return non-zero. */ +extern int check_device (const char *device); /* Assign DRIVE to a device name DEVICE. */ extern void assign_device_name (int drive, const char *device); #endif