add new options for the floppy probing into the grub shell. fix some bugs in the commands geometry and device.

This commit is contained in:
okuji 1999-09-11 07:05:29 +00:00
parent 95a60f61ce
commit 3c77f34cc1
6 changed files with 196 additions and 67 deletions

View file

@ -1,3 +1,31 @@
1999-09-11 OKUJI Yoshinori <okuji@kuicr.kyoto-u.ac.jp>
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 <okuji@kuicr.kyoto-u.ac.jp>
* stage2/builtins.c (device_func): New function.

6
NEWS
View file

@ -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).

View file

@ -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)

View file

@ -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);

View file

@ -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 */

View file

@ -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