device map file support.

This commit is contained in:
okuji 1999-10-13 23:02:06 +00:00
parent 4e769ee998
commit 8f83254679
8 changed files with 242 additions and 66 deletions

View file

@ -1,3 +1,26 @@
1999-10-13 OKUJI Yoshinori <okuji@kuicr.kyoto-u.ac.jp>
* grub/asmstub.c (assign_device_name): If DEVICE is NULL, set
DEVICE_MAP[DRIVE] to NULL.
(get_diskinfo): If open or read fails, call assign_device_name
to disable accessing the drive DRIVE.
(grub_stage2): The device mapping routine is moved to ...
(init_device_map): ... here. This new function also reads/writes
a device map file. If DEVICE_MAP_FILE already exists, then use
the data in it instead of probing devices. Otherwise, guess the
map between BIOS drives and OS devices, and write it to the file
DEVICE_MAP_FILE if it can be opened.
* grub/main.c (device_map_file): New variable.
(default_device_map_file): Likewise.
(OPT_DEVICE_MAP): New macro.
(longopts): Added an entry for "device-map".
(usage): Print the usage about --device-map as well.
(main): Set DEFAULT_DEVICE_MAP_FILE to DEVICE_MAP_FILE. If
OPT_DEVICE_MAP is found, set DEVICE_MAP_FILE to a duplicated
string of OPTARG.
* stage2/shared.h [GRUB_UTIL] (device_map_file): Declared.
* docs/grub.8: Regenerated.
1999-10-13 OKUJI Yoshinori <okuji@kuicr.kyoto-u.ac.jp> 1999-10-13 OKUJI Yoshinori <okuji@kuicr.kyoto-u.ac.jp>
* stage2/builtins.c (color_func): Do not set NORMAL_COLOR or * stage2/builtins.c (color_func): Do not set NORMAL_COLOR or

4
NEWS
View file

@ -7,6 +7,10 @@ New in 0.5.94:
* The command "embed" embeds a Stage 1.5 in the sectors after a MBR or * The command "embed" embeds a Stage 1.5 in the sectors after a MBR or
in the "bootloader" area in a FFS partition. in the "bootloader" area in a FFS partition.
* Support symbolic color name syntax in the command "color". * Support symbolic color name syntax in the command "color".
* The grub shell loads the BIOS drive mapping information from a device
map file (the default is "/boot/grub/device.map") if it already
exists. If not found, try to create it based on the guessed
information.
New in 0.5.93: New in 0.5.93:
* ELF format of FreeBSD kernel is supported. * ELF format of FreeBSD kernel is supported.

View file

@ -1,5 +1,5 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.013. .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.013.
.TH GRUB "8" "September 1999" "GNU GRUB 0.5.93" FSF .TH GRUB "8" "October 1999" "GNU GRUB 0.5.94" FSF
.SH NAME .SH NAME
GRUB \- the grub shell GRUB \- the grub shell
.SH SYNOPSIS .SH SYNOPSIS
@ -18,6 +18,9 @@ specify stage2 boot_drive [default=0x0]
\fB\-\-config\-file\fR=\fIFILE\fR \fB\-\-config\-file\fR=\fIFILE\fR
specify stage2 config_file [default=/boot/grub/menu.lst] specify stage2 config_file [default=/boot/grub/menu.lst]
.TP .TP
\fB\-\-device\-map\fR=\fIFILE\fR
specify the device map file [default=/boot/grub/device.map]
.TP
\fB\-\-help\fR \fB\-\-help\fR
display this message and exit display this message and exit
.TP .TP

View file

@ -1,3 +1,3 @@
@set UPDATED 10 September 1999 @set UPDATED 13 October 1999
@set EDITION 0.5.93 @set EDITION 0.5.94
@set VERSION 0.5.93 @set VERSION 0.5.94

View file

@ -1,3 +1,3 @@
@set UPDATED 10 September 1999 @set UPDATED 13 October 1999
@set EDITION 0.5.93 @set EDITION 0.5.94
@set VERSION 0.5.93 @set VERSION 0.5.94

View file

@ -33,6 +33,7 @@ int grub_stage2 (void);
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <ctype.h>
#include <assert.h> #include <assert.h>
#include <stdio.h> #include <stdio.h>
#include <sys/types.h> #include <sys/types.h>
@ -94,6 +95,7 @@ static jmp_buf env_for_exit;
static void get_floppy_disk_name (char *name, int unit); static void get_floppy_disk_name (char *name, int unit);
static void get_ide_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); static void get_scsi_disk_name (char *name, int unit);
static void init_device_map (void);
/* The main entry point into this mess. */ /* The main entry point into this mess. */
int int
@ -102,8 +104,8 @@ grub_stage2 (void)
/* These need to be static, because they survive our stack transitions. */ /* These need to be static, because they survive our stack transitions. */
static int status = 0; static int status = 0;
static char *realstack; static char *realstack;
int i, num_hd = 0;
char *scratch, *simstack; char *scratch, *simstack;
int i;
/* We need a nested function so that we get a clean stack frame, /* We need a nested function so that we get a clean stack frame,
regardless of how the code is optimized. */ regardless of how the code is optimized. */
@ -145,59 +147,7 @@ grub_stage2 (void)
for (i = 0; i < NUM_DISKS; i++) for (i = 0; i < NUM_DISKS; i++)
disks[i].flags = -1; disks[i].flags = -1;
assert (device_map == 0); init_device_map ();
device_map = malloc (NUM_DISKS * sizeof (char *));
assert (device_map);
/* Probe devices for creating the device map. */
/* Initialize DEVICE_MAP. */
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. */
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[16];
get_ide_disk_name (name, i);
if (check_device (name))
{
assign_device_name (num_hd + 0x80, name);
num_hd++;
}
}
/* The rest is SCSI disks. */
for (i = 0; i < 8; i++)
{
char name[16];
get_scsi_disk_name (name, i);
if (check_device (name))
{
assign_device_name (num_hd + 0x80, name);
num_hd++;
}
}
/* Check some invariants. */ /* Check some invariants. */
assert ((SCRATCHSEG << 4) == SCRATCHADDR); assert ((SCRATCHSEG << 4) == SCRATCHADDR);
@ -263,6 +213,180 @@ grub_stage2 (void)
return status; return status;
} }
static void
init_device_map (void)
{
int i;
int num_hd = 0;
FILE *fp;
static void print_error (int no, const char *msg)
{
fprintf (stderr, "%s:%d: error: %s\n", device_map_file, no, msg);
}
assert (device_map == 0);
device_map = malloc (NUM_DISKS * sizeof (char *));
assert (device_map);
/* Probe devices for creating the device map. */
/* Initialize DEVICE_MAP. */
for (i = 0; i < NUM_DISKS; i++)
device_map[i] = 0;
/* Open the device map file. */
fp = fopen (device_map_file, "r");
if (fp)
{
/* If there is the device map file, use the data in it instead of
probing devices. */
char buf[1024]; /* XXX */
int line_number = 0;
while (fgets (buf, sizeof (buf), fp))
{
char *ptr, *eptr;
int drive;
int is_floppy = 0;
/* Increase the number of lines. */
line_number++;
/* If the first character is '#', skip it. */
if (buf[0] == '#')
continue;
ptr = buf;
/* Skip leading spaces. */
while (*ptr && isspace (*ptr))
ptr++;
if (*ptr != '(')
{
print_error (line_number, "No open parenthesis found");
stop ();
}
ptr++;
if ((*ptr != 'f' && *ptr != 'h') || *(ptr + 1) != 'd')
{
print_error (line_number, "Bad drive name");
stop ();
}
if (*ptr == 'f')
is_floppy = 1;
ptr += 2;
drive = strtoul (ptr, &ptr, 10);
if (drive < 0 || drive > 8)
{
print_error (line_number, "Bad device number");
stop ();
}
if (! is_floppy)
drive += 0x80;
if (*ptr != ')')
{
print_error (line_number, "No close parenthesis found");
stop ();
}
ptr++;
/* Skip spaces. */
while (*ptr && isspace (*ptr))
ptr++;
if (! *ptr)
{
print_error (line_number, "No filename found");
stop ();
}
/* Terminate the filename. */
eptr = ptr;
while (*eptr && ! isspace (*eptr))
eptr++;
*eptr = 0;
assign_device_name (drive, ptr);
}
fclose (fp);
return;
}
/* 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");
/* Try to open the device map file to write the probed data. */
fp = fopen (device_map_file, "w");
/* Floppies. */
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);
/* If the device map file is opened, write the map. */
if (fp)
fprintf (fp, "(fd%d)\t%s\n", i, name);
}
}
/* IDE disks. */
for (i = 0; i < 4; i++)
{
char name[16];
get_ide_disk_name (name, i);
if (check_device (name))
{
assign_device_name (num_hd + 0x80, name);
/* If the device map file is opened, write the map. */
if (fp)
fprintf (fp, "(hd%d)\t%s\n", num_hd, name);
num_hd++;
}
}
/* The rest is SCSI disks. */
for (i = 0; i < 8; i++)
{
char name[16];
get_scsi_disk_name (name, i);
if (check_device (name))
{
assign_device_name (num_hd + 0x80, name);
/* If the device map file is opened, write the map. */
if (fp)
fprintf (fp, "(hd%d)\t%s\n", num_hd, name);
num_hd++;
}
}
/* OK, close the device map file if opened. */
if (fp)
fclose (fp);
}
/* These three functions are quite different among OSes. */ /* These three functions are quite different among OSes. */
static void static void
get_floppy_disk_name (char *name, int unit) get_floppy_disk_name (char *name, int unit)
@ -378,7 +502,10 @@ assign_device_name (int drive, const char *device)
} }
/* Assign DRIVE to DEVICE. */ /* Assign DRIVE to DEVICE. */
device_map[drive] = strdup (device); if (! device)
device_map[drive] = 0;
else
device_map[drive] = strdup (device);
} }
void void
@ -714,10 +841,16 @@ get_diskinfo (int drive, struct geometry *geometry)
{ {
disks[drive].flags = open (devname, O_RDONLY); disks[drive].flags = open (devname, O_RDONLY);
if (disks[drive].flags == -1) if (disks[drive].flags == -1)
return -1; {
assign_device_name (drive, 0);
return -1;
}
} }
else else
return -1; {
assign_device_name (drive, 0);
return -1;
}
} }
/* Attempt to read the first sector. */ /* Attempt to read the first sector. */
@ -725,6 +858,7 @@ get_diskinfo (int drive, struct geometry *geometry)
{ {
close (disks[drive].flags); close (disks[drive].flags);
disks[drive].flags = -1; disks[drive].flags = -1;
assign_device_name (drive, 0);
return -1; return -1;
} }

View file

@ -38,9 +38,11 @@ int verbose = 0;
int read_only = 0; int read_only = 0;
int no_floppy = 0; int no_floppy = 0;
int probe_second_floppy = 0; int probe_second_floppy = 0;
char *device_map_file = "/boot/grub/device.map";
static int default_boot_drive; static int default_boot_drive;
static int default_install_partition; static int default_install_partition;
static char *default_config_file; static char *default_config_file;
static char *default_device_map_file;
#define OPT_HELP -2 #define OPT_HELP -2
#define OPT_VERSION -3 #define OPT_VERSION -3
@ -55,6 +57,7 @@ static char *default_config_file;
#define OPT_READ_ONLY -12 #define OPT_READ_ONLY -12
#define OPT_PROBE_SECOND_FLOPPY -13 #define OPT_PROBE_SECOND_FLOPPY -13
#define OPT_NO_FLOPPY -14 #define OPT_NO_FLOPPY -14
#define OPT_DEVICE_MAP -15
#define OPTSTRING "" #define OPTSTRING ""
static struct option longopts[] = static struct option longopts[] =
@ -62,6 +65,7 @@ static struct option longopts[] =
{"batch", no_argument, 0, OPT_BATCH}, {"batch", no_argument, 0, OPT_BATCH},
{"boot-drive", required_argument, 0, OPT_BOOT_DRIVE}, {"boot-drive", required_argument, 0, OPT_BOOT_DRIVE},
{"config-file", required_argument, 0, OPT_CONFIG_FILE}, {"config-file", required_argument, 0, OPT_CONFIG_FILE},
{"device-map", required_argument, 0, OPT_DEVICE_MAP},
{"help", no_argument, 0, OPT_HELP}, {"help", no_argument, 0, OPT_HELP},
{"hold", no_argument, 0, OPT_HOLD}, {"hold", no_argument, 0, OPT_HOLD},
{"install-partition", required_argument, 0, OPT_INSTALL_PARTITION}, {"install-partition", required_argument, 0, OPT_INSTALL_PARTITION},
@ -90,6 +94,7 @@ Enter the GRand Unified Bootloader command shell.\n\
--batch turn on batch mode for non-interactive use\n\ --batch turn on batch mode for non-interactive use\n\
--boot-drive=DRIVE specify stage2 boot_drive [default=0x%x]\n\ --boot-drive=DRIVE specify stage2 boot_drive [default=0x%x]\n\
--config-file=FILE specify stage2 config_file [default=%s]\n\ --config-file=FILE specify stage2 config_file [default=%s]\n\
--device-map=FILE specify the device map file [default=%s]\n\
--help display this message and exit\n\ --help display this message and exit\n\
--hold wait until a debugger will attach\n\ --hold wait until a debugger will attach\n\
--install-partition=PAR specify stage2 install_partition [default=0x%x]\n\ --install-partition=PAR specify stage2 install_partition [default=0x%x]\n\
@ -104,7 +109,7 @@ Enter the GRand Unified Bootloader command shell.\n\
Report bugs to bug-grub@gnu.org\n\ Report bugs to bug-grub@gnu.org\n\
", ",
default_boot_drive, default_config_file, default_boot_drive, default_config_file,
default_install_partition); default_device_map_file, default_install_partition);
exit (status); exit (status);
} }
@ -128,6 +133,7 @@ main (int argc, char **argv)
default_config_file = config_file; default_config_file = config_file;
else else
default_config_file = "NONE"; default_config_file = "NONE";
default_device_map_file = device_map_file;
/* Parse command-line options. */ /* Parse command-line options. */
do do
@ -205,6 +211,10 @@ main (int argc, char **argv)
probe_second_floppy = 1; probe_second_floppy = 1;
break; break;
case OPT_DEVICE_MAP:
device_map_file = strdup (optarg);
break;
default: default:
usage (1); usage (1);
} }

View file

@ -391,6 +391,8 @@ extern int no_floppy;
extern int probe_second_floppy; extern int probe_second_floppy;
/* The map between BIOS drives and UNIX device file names. */ /* The map between BIOS drives and UNIX device file names. */
extern char **device_map; extern char **device_map;
/* The filename which stores the information about a device map. */
extern char *device_map_file;
/* The array of geometries. */ /* The array of geometries. */
extern struct geometry *disks; extern struct geometry *disks;
/* Check if DEVICE can be read. If an error occurs, return zero, /* Check if DEVICE can be read. If an error occurs, return zero,