add an extra option into the command install, and allow to mount extended partitions.

This commit is contained in:
okuji 1999-11-02 12:54:19 +00:00
parent 8fb66b3a69
commit c6ec01220b
8 changed files with 160 additions and 95 deletions

View file

@ -1,3 +1,26 @@
1999-11-02 OKUJI Yoshinori <okuji@kuicr.kyoto-u.ac.jp>
* stage2/disk_io.c (real_open_partition): Check for the right
partition for any extended partition as well. Set EXT to I after
the check is done. Reported by Jeff Scheinberg
<jeffsh@erols.com>.
* stage2/builtins.c (color_func): Use the function
nul_terminate.
(device_func) [GRUB_UTIL]: Likewise.
(help_func): Likewise.
(install_func): Save CURRENT_DRIVE, CURRENT_PARTITION and
BUG_GEOM in SRC_DRIVE, SRC_PARTITION and SRC_GEOM respectively,
and use them when patching the Stage 2.
NUL-terminate the configuration filename CONFIG_FILENAME.
If IS_STAGE1_5 is true, then check if the "real config file"
option is present, and, if so, patch the Stage 2 CONFIG_FILENAME
with the configuration filename REAL_CONFIG_FILENAME.
(setkey_func): Use nul_terminate instead of the local function
null_terminate.
* stage2/char_io.c [!STAGE1_5] (nul_terminate): New function.
* stage2/shared.h (nul_terminate): Declared.
1999-11-01 OKUJI Yoshinori <okuji@kuicr.kyoto-u.ac.jp>
* docs/grub.texi: Add "I/O ports detection" into the menu.

2
NEWS
View file

@ -24,6 +24,8 @@ New in 0.5.94:
* The command "ioprobe" detects what I/O ports are used for a BIOS
drive.
* OpenBSD support in the grub shell is improved.
* The command "install" can now patch a Stage 2 with a different
filename from "/boot/grub/menu.lst" even if a Stage 1.5 is used.
New in 0.5.93:
* ELF format of FreeBSD kernel is supported.

2
TODO
View file

@ -36,8 +36,6 @@ Priorities:
* Add ISA PnP support.
* Accept any extended partition when using it for chain-loading. !!!
* Fix the completion so that it works for BSD partitions as well. !!
* Add more filesystems support (XFS, NTFS, etc.)

View file

@ -830,7 +830,7 @@ Load an initial ramdisk for a Linux format boot image and set the
appropriate parameters in the Linux setup area in memory.
@end deffn
@deffn Command install stage1_file [@option{d}] dest_dev file [addr] [@option{p}] [config_file]
@deffn Command install stage1_file [@option{d}] dest_dev stage2_file [addr] [@option{p}] [config_file] [real_config_file]
This command is fairly complex, and you should not use this command
unless you are familiar with GRUB. In short, it will perform a full
install presuming the Stage 2 or Stage 1.5@footnote{They're loaded the
@ -839,19 +839,23 @@ is in its final install location.
In slightly more detail, it will load @var{stage1_file}, validate that
it is a GRUB Stage 1 of the right version number, install a blocklist for
loading @var{file} as a Stage 2. If the option @option{d} is present, the
Stage 1 will always look for the actual disk @var{file} was installed on,
rather than using the booting drive. The Stage 2 will be loaded at
address @var{addr}, which must be @samp{0x8000} for a true Stage 2, and
@samp{0x2000} for a Stage 1.5. If @var{addr} is not present, GRUB will
determine the address automatically. It then writes the completed Stage 1
to the first block of the device @var{dest_dev}. If the options @option{p}
or @var{config_file} are present, then it reads the first block of
stage2, modifies it with the values of the partition @var{file} was
found on (for @option{p}) or places the string @var{config_file} into the
area telling the stage2 where to look for a configuration file at boot
time. This command preserves the DOS BPB (and for hard disks, the
partition table) of the sector the Stage 1 is to be installed into.
loading @var{stage2_file} as a Stage 2. If the option @option{d} is
present, the Stage 1 will always look for the actual disk
@var{stage2_file} was installed on, rather than using the booting
drive. The Stage 2 will be loaded at address @var{addr}, which must be
@samp{0x8000} for a true Stage 2, and @samp{0x2000} for a Stage 1.5. If
@var{addr} is not present, GRUB will determine the address
automatically. It then writes the completed Stage 1 to the first block
of the device @var{dest_dev}. If the options @option{p} or
@var{config_file} are present, then it reads the first block of stage2,
modifies it with the values of the partition @var{stage2_file} was found
on (for @option{p}) or places the string @var{config_file} into the area
telling the stage2 where to look for a configuration file at boot
time. Likewise, if @var{real_config_file} is present and
@var{stage2_file} is a Stage 1.5, then the Stage 2 @var{config_file} is
patched with the configuration filename @var{real_config_file}. This
command preserves the DOS BPB (and for hard disks, the partition table)
of the sector the Stage 1 is to be installed into.
@end deffn
@deffn Command ioprobe drive

View file

@ -290,12 +290,7 @@ color_func (char *arg, int flags)
return -1;
str = ptr;
/* Find a space. */
for (; *ptr && ! grub_isspace (*ptr); ptr++)
;
/* Terminate the string STR. */
*ptr = 0;
nul_terminate (str);
/* Search for the color name. */
for (i = 0; i < 8; i++)
@ -451,7 +446,6 @@ device_func (char *arg, int flags)
#ifdef GRUB_UTIL
char *drive = arg;
char *device;
char *ptr;
/* Get the drive number from DRIVE. */
if (! set_device (drive))
@ -466,10 +460,7 @@ device_func (char *arg, int flags)
}
/* Terminate DEVICE. */
ptr = device;
while (*ptr && *ptr != ' ')
ptr++;
*ptr = 0;
nul_terminate (device);
assign_device_name (current_drive, device);
@ -951,16 +942,13 @@ help_func (char *arg, int flags)
do
{
struct builtin **builtin;
char *ptr = arg;
char *next_arg;
/* Get the next argument. */
next_arg = skip_to (0, arg);
/* Terminate ARG. */
while (*ptr && *ptr != ' ')
ptr++;
*ptr = 0;
nul_terminate (arg);
for (builtin = builtin_table; *builtin; builtin++)
{
@ -1120,11 +1108,14 @@ install_func (char *arg, int flags)
char *old_sect = stage1_buffer + SECTOR_SIZE;
char *stage2_first_buffer = old_sect + SECTOR_SIZE;
char *stage2_second_buffer = stage2_first_buffer + SECTOR_SIZE;
char *dummy = stage2_second_buffer + SECTOR_SIZE;
/* XXX: Probably SECTOR_SIZE is reasonable. */
char *config_filename = stage2_second_buffer + SECTOR_SIZE;
char *dummy = config_filename + SECTOR_SIZE;
int new_drive = 0xFF;
int dest_drive, dest_sector;
int src_drive, src_partition;
int i;
struct geometry dest_geom;
struct geometry dest_geom, src_geom;
int saved_sector;
int stage2_first_sector, stage2_second_sector;
char *ptr;
@ -1251,9 +1242,13 @@ install_func (char *arg, int flags)
if (! is_open)
goto fail;
src_drive = current_drive;
src_partition = current_partition;
src_geom = buf_geom;
if (! new_drive)
new_drive = current_drive;
else if (current_drive != dest_drive)
new_drive = src_drive;
else if (src_drive != dest_drive)
grub_printf ("Warning: the option `d' was not used, but the Stage 1 will"
" be installed on a\ndifferent drive than the drive where"
" the Stage 2 resides.\n");
@ -1340,7 +1335,7 @@ install_func (char *arg, int flags)
if (*ptr == 'p')
{
*((long *) (stage2_second_buffer + STAGE2_INSTALLPART))
= current_partition;
= src_partition;
if (is_stage1_5)
{
/* Reset the device information in FILE if it is a Stage 1.5. */
@ -1355,6 +1350,9 @@ install_func (char *arg, int flags)
if (*ptr)
{
grub_strcpy (config_filename, ptr);
nul_terminate (config_filename);
if (! is_stage1_5)
/* If it is a Stage 2, just copy PTR to CONFIG_FILE_LOCATION. */
grub_strcpy (config_file_location, ptr);
@ -1362,7 +1360,6 @@ install_func (char *arg, int flags)
{
char *config_file;
unsigned long device;
int tmp = current_drive;
/* Translate the external device syntax to the internal device
syntax. */
@ -1374,11 +1371,63 @@ install_func (char *arg, int flags)
}
device = current_drive << 24 | current_partition;
current_drive = tmp;
grub_memmove (config_file_location, (char *) &device,
sizeof (device));
grub_strcpy (config_file_location + sizeof (device), config_file);
}
/* Check if the configuration filename is specified, if a Stage 1.5
is used. */
if (is_stage1_5)
{
char *real_config_filename = skip_to (0, ptr);
if (*real_config_filename)
{
/* Specified */
char *location;
is_open = grub_open (config_filename);
if (! is_open)
goto fail;
/* Skip the first sector. */
filepos = SECTOR_SIZE;
disk_read_hook = disk_read_savesect_func;
if (grub_read ((char *) SCRATCHADDR, SECTOR_SIZE) != SECTOR_SIZE)
goto fail;
disk_read_hook = 0;
grub_close ();
is_open = 0;
/* Sanity check. */
if (*((unsigned char *) SCRATCHADDR + STAGE2_STAGE2_ID)
!= STAGE2_ID_STAGE2)
{
errnum = ERR_BAD_VERSION;
goto fail;
}
/* Find a string for the configuration filename. */
location = (char *) SCRATCHADDR + STAGE2_VER_STR_OFFS;
while (*(location++))
;
/* Copy the name. */
grub_strcpy (location, real_config_filename);
/* Write it to the disk. */
buf_track = -1;
if (biosdisk (BIOSDISK_WRITE, current_drive, &buf_geom,
saved_sector, 1, SCRATCHSEG))
{
errnum = ERR_WRITE;
goto fail;
}
}
}
}
/* Clear the cache. */
@ -1386,7 +1435,7 @@ install_func (char *arg, int flags)
/* Write the modified first sector of Stage2 to the disk. */
grub_memmove ((char *) SCRATCHADDR, stage2_first_buffer, SECTOR_SIZE);
if (biosdisk (BIOSDISK_WRITE, current_drive, &buf_geom,
if (biosdisk (BIOSDISK_WRITE, src_drive, &src_geom,
stage2_first_sector, 1, SCRATCHSEG))
{
errnum = ERR_WRITE;
@ -1395,7 +1444,7 @@ install_func (char *arg, int flags)
/* Write the modified second sector of Stage2 to the disk. */
grub_memmove ((char *) SCRATCHADDR, stage2_second_buffer, SECTOR_SIZE);
if (biosdisk (BIOSDISK_WRITE, current_drive, &buf_geom,
if (biosdisk (BIOSDISK_WRITE, src_drive, &src_geom,
stage2_second_sector, 1, SCRATCHSEG))
{
errnum = ERR_WRITE;
@ -1429,7 +1478,7 @@ static struct builtin builtin_install =
"install",
install_func,
BUILTIN_CMDLINE,
"install STAGE1 [d] DEVICE STAGE2 [ADDR] [p] [CONFIG_FILE]",
"install STAGE1 [d] DEVICE STAGE2 [ADDR] [p] [CONFIG_FILE] [REAL_CONFIG_FILE]",
"Install STAGE1 on DEVICE, and install a blocklist for loading STAGE2"
" as a Stage 2. If the option `d' is present, the Stage 1 will always"
" look for the disk where STAGE2 was installed, rather than using"
@ -1438,7 +1487,9 @@ static struct builtin builtin_install =
" the option `p' or CONFIG_FILE is present, then the first block"
" of Stage 2 is patched with new values of the partition and name"
" of the configuration file used by the true Stage 2 (for a Stage 1.5,"
" this is the name of the true Stage 2) at boot time."
" this is the name of the true Stage 2) at boot time. If STAGE2 is a Stage"
" 1.5 and REAL_CONFIG_FILE is present, then the Stage 2 CONFIG_FILE is"
" patched with the configuration filename REAL_CONFIG_FILE."
};
@ -1875,7 +1926,7 @@ struct keysym
unsigned char keycode; /* keyboard scancode */
};
/* The table for key symbols. If the "unshifted" member of an entry is
/* The table for key symbols. If the "shifted" member of an entry is
NULL, the entry does not have shifted state. */
static struct keysym keysym_table[] =
{
@ -1956,13 +2007,6 @@ setkey_func (char *arg, int flags)
int to_code, from_code;
int map_in_interrupt = 0;
static void null_terminate (char *str)
{
while (*str && ! grub_isspace (*str))
str++;
*str = 0;
}
static int find_key_code (char *key)
{
int i;
@ -1996,8 +2040,8 @@ setkey_func (char *arg, int flags)
to_key = arg;
from_key = skip_to (0, to_key);
null_terminate (to_key);
null_terminate (from_key);
nul_terminate (to_key);
nul_terminate (from_key);
to_code = find_ascii_code (to_key);
from_code = find_ascii_code (from_key);

View file

@ -19,10 +19,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "shared.h"
void
print_error (void)
{
@ -35,7 +33,6 @@ print_error (void)
#endif /* STAGE1_5 */
}
char *
convert_to_ascii (char *buf, int c,...)
{
@ -78,7 +75,6 @@ convert_to_ascii (char *buf, int c,...)
return ptr;
}
void
grub_printf (const char *format,...)
{
@ -123,7 +119,6 @@ grub_printf (const char *format,...)
}
}
#ifndef STAGE1_5
int
grub_sprintf (char *buffer, const char *format, ...)
@ -168,10 +163,6 @@ grub_sprintf (char *buffer, const char *format, ...)
*bp = 0;
return bp - buffer;
}
#endif /* ! STAGE1_5 */
#ifndef STAGE1_5
void
init_page (void)
@ -611,10 +602,8 @@ get_cmdline (char *prompt, char *cmdline, int maxlen,
return 0;
}
#endif /* STAGE1_5 */
int
safe_parse_maxint (char **str_ptr, int *myint_ptr)
{
@ -669,7 +658,6 @@ safe_parse_maxint (char **str_ptr, int *myint_ptr)
return 1;
}
int
grub_tolower (int c)
{
@ -679,7 +667,6 @@ grub_tolower (int c)
return c;
}
int
grub_isspace (int c)
{
@ -706,9 +693,7 @@ grub_memcmp (const char *s1, const char *s2, int n)
return 0;
}
#endif /* ! STAGE1_5 */
#ifndef STAGE1_5
int
grub_strncat (char *s1, const char *s2, int n)
{
@ -727,9 +712,7 @@ grub_strncat (char *s1, const char *s2, int n)
return 1;
}
#endif /* ! STAGE1_5 */
#ifndef STAGE1_5
int
grub_strcmp (const char *s1, const char *s2)
{
@ -766,8 +749,18 @@ substring (char *s1, char *s2)
return 1;
}
#ifndef STAGE1_5
/* Terminate the string STR with NUL. */
char *
nul_terminate (char *str)
{
while (*str && ! grub_isspace (*str))
str++;
*str++ = 0;
return str;
}
char *
grub_strstr (const char *s1, const char *s2)
{
@ -799,7 +792,6 @@ grub_strlen (const char *str)
}
#endif /* ! STAGE1_5 */
int
memcheck (int addr, int len)
{
@ -840,7 +832,6 @@ memcheck (int addr, int len)
return ! errnum;
}
char *
grub_memmove (char *to, const char *from, int len)
{
@ -877,7 +868,6 @@ grub_memmove (char *to, const char *from, int len)
return errnum ? NULL : to;
}
#ifndef STAGE1_5
void *
grub_memset (void *start, int c, int len)

View file

@ -494,7 +494,7 @@ real_open_partition (int flags)
slice_no = 0;
/* if this is the whole disk, return here */
if (!flags && current_partition == 0xFFFFFFuL)
if (! flags && current_partition == 0xFFFFFFuL)
return 1;
/*
@ -508,7 +508,7 @@ real_open_partition (int flags)
/*
* If the table isn't valid, we can't continue
*/
if (!PC_MBR_CHECK_SIG (mbr_buf))
if (! PC_MBR_CHECK_SIG (mbr_buf))
{
errnum = ERR_BAD_PART_TABLE;
return 0;
@ -527,7 +527,9 @@ real_open_partition (int flags)
part_start = part_offset + PC_SLICE_START (mbr_buf, i);
part_length = PC_SLICE_LENGTH (mbr_buf, i);
#ifndef STAGE1_5
memmove (cur_part_desc, mbr_buf + PC_SLICE_OFFSET + (i << 4), 16);
grub_memmove (cur_part_desc,
mbr_buf + PC_SLICE_OFFSET + (i << 4),
16);
#endif
/*
@ -535,21 +537,11 @@ real_open_partition (int flags)
*/
if (current_slice)
{
/*
* Is this an extended partition?
*/
if (IS_PC_SLICE_TYPE_EXTENDED (current_slice))
{
if (ext == -1)
{
ext = i;
}
}
# ifndef STAGE1_5
#ifndef STAGE1_5
/*
* Display partition information
*/
else if (flags)
if (flags && ! IS_PC_SLICE_TYPE_EXTENDED (current_slice))
{
current_partition |= 0xFFFF;
if (! do_completion)
@ -576,13 +568,15 @@ real_open_partition (int flags)
errnum = ERR_NONE;
}
# endif /* ! STAGE1_5 */
#endif /* ! STAGE1_5 */
/*
* If we've found the right partition, we're done
*/
else if (part_no == slice_no
|| (part_no == 0xFF
&& IS_PC_SLICE_TYPE_BSD (current_slice)))
if (! flags
&& (part_no == slice_no
|| (part_no == 0xFF
&& IS_PC_SLICE_TYPE_BSD (current_slice))))
{
if ((current_partition & 0xFF00) != 0xFF00)
{
@ -595,6 +589,15 @@ real_open_partition (int flags)
ext = -2;
break;
}
/*
* Is this an extended partition?
*/
if (IS_PC_SLICE_TYPE_EXTENDED (current_slice))
{
if (ext == -1)
ext = i;
}
}
/*
@ -609,7 +612,7 @@ real_open_partition (int flags)
}
part_offset = ext_offset + PC_SLICE_START (mbr_buf, ext);
if (!ext_offset)
if (! ext_offset)
ext_offset = part_offset;
}
}
@ -634,14 +637,14 @@ real_open_partition (int flags)
ext = -2;
}
}
# ifndef STAGE1_5
#ifndef STAGE1_5
else
{
current_partition = 0xFFFFFF;
check_and_print_mount ();
errnum = 0;
}
# endif /* STAGE1_5 */
#endif /* STAGE1_5 */
}
}

View file

@ -695,6 +695,7 @@ char *convert_to_ascii (char *buf, int c, ...);
int get_cmdline (char *prompt, char *cmdline, int maxlen,
int echo_char, int history);
int substring (char *s1, char *s2);
char *nul_terminate (char *str);
int get_based_digit (int c, int base);
int safe_parse_maxint (char **str_ptr, int *myint_ptr);
int memcheck (int start, int len);