reduce the size of Stage 1.5, improve the completion, fix some bugs.
This commit is contained in:
parent
55d36b7e2b
commit
3ccfc3bed1
19 changed files with 374 additions and 101 deletions
3
AUTHORS
3
AUTHORS
|
@ -15,3 +15,6 @@ OKUJI Yoshinori contributed many bugfixes and new features, such as
|
||||||
working LBA support, and /sbin/grub support for configuration files.
|
working LBA support, and /sbin/grub support for configuration files.
|
||||||
|
|
||||||
Peter Astrand added support for a color menu.
|
Peter Astrand added support for a color menu.
|
||||||
|
|
||||||
|
Pavel Roskin contributed many bugfixes and new features, such as FreeBSD
|
||||||
|
support in the grub shell, and configure process cleanups.
|
||||||
|
|
78
ChangeLog
78
ChangeLog
|
@ -1,3 +1,81 @@
|
||||||
|
1999-09-29 OKUJI Yoshinori <okuji@kuicr.kyoto-u.ac.jp>
|
||||||
|
|
||||||
|
* stage2/builtins.c (install_func): If the Stage 2 id in FILE is
|
||||||
|
not STAGE2_ID_STAGE2, set IS_STAGE1_5 to 1, otherwise to 0.
|
||||||
|
Use CONFIG_FILE_LOCATION to point to the location of the name of
|
||||||
|
a configuration file in Stage 2.
|
||||||
|
If the option `p' is present and IS_STAGE1_5 is non-zero, reset
|
||||||
|
the device information in CONFIG_FILE_LOCATION.
|
||||||
|
(cat_func): New function.
|
||||||
|
(builtin_cat): New variable.
|
||||||
|
(builtin_table): Added a pointer to BUILTIN_CAT.
|
||||||
|
(geometry_func): Call real_open_partition with the argument 1
|
||||||
|
after printing out the drive information.
|
||||||
|
* stage2/disk_io.c (real_open_partition): Made global.
|
||||||
|
[!STAGE1_5] (print_completions): In the command completion and
|
||||||
|
the filename completion, print a newline at the last if
|
||||||
|
IS_COMPLETION is zero.
|
||||||
|
* stage2/shared.h (real_open_partition): Declared.
|
||||||
|
* stage2/fsys_ext2fs.c (ext2fs_dir): Do not print a newline even
|
||||||
|
if PRINT_POSSIBILITIES is less than zero.
|
||||||
|
* stage2/fsys_ffs.c (ffs_dir): Likewise.
|
||||||
|
* stage2/fsys_fat.c (fat_dir): Likewise.
|
||||||
|
* stage2/fsys_minix.c (minix_dir): Likewise.
|
||||||
|
|
||||||
|
1999-09-29 OKUJI Yoshinori <okuji@kuicr.kyoto-u.ac.jp>
|
||||||
|
|
||||||
|
* stage1/stage1.S [!FFS_STAGE1_5] (blocklist_default_len): Do
|
||||||
|
not divide the size by 512, but shift the size to the right by
|
||||||
|
9 instead, because of a binutils-2.9.1.0.x bug.
|
||||||
|
* stage1/stage1_lba.S [!FFS_STAGE1_5] (blocklist_default_len):
|
||||||
|
Likewise.
|
||||||
|
* stage2/builtins.c (install_func): When installing Stage 1.5,
|
||||||
|
if set_device returns NULL, then set CURRENT_DRIVE to 0xFF and
|
||||||
|
CONFIG_FILE to PTR.
|
||||||
|
|
||||||
|
1999-09-26 OKUJI Yoshinori <okuji@kuicr.kyoto-u.ac.jp>
|
||||||
|
|
||||||
|
* stage2/char_io.c [!STAGE1_5] (get_cmdline): In cl_insert, call
|
||||||
|
cl_setcpos before printing BUF, even if LPOS is equal to LLEN.
|
||||||
|
In the completion, if RET is zero, do not call cl_init.
|
||||||
|
* stage2/disk_io.c [!STAGE1_5] (print_completions): In the
|
||||||
|
filename completion, if UNIQUE is 1, check if UNIQUE_STRING is a
|
||||||
|
directory or not. If so, append '/' to BUF.
|
||||||
|
In the partition completion, if IS_COMPLETION is non-zero and
|
||||||
|
*UNIQUE_STRING is not NUL, copy UNIQUE_STRING to PTR. Do not
|
||||||
|
append '/'.
|
||||||
|
(real_open_partition) [!STAGE1_5]: If DO_COMPRESSION is non-zero,
|
||||||
|
call print_a_completion.
|
||||||
|
(check_BSD_parts) [!STAGE1_5]: Likewise.
|
||||||
|
[!STAGE1_5] (print_a_completion): Ignore NAME if it is "." or
|
||||||
|
"..".
|
||||||
|
|
||||||
|
1999-09-25 OKUJI Yoshinori <okuji@kuicr.kyoto-u.ac.jp>
|
||||||
|
|
||||||
|
* acinclude.m4 (grub_CHECK_USCORE_END_SYMBOL): Do not call
|
||||||
|
AC_DEFINE within AC_CACHE_VAL. Call it after AC_CACHE_VAL.
|
||||||
|
* stage2/Makefile.am (STAGE1_5_COMPILE): Do not define
|
||||||
|
CONFIG_FILE_ASM.
|
||||||
|
* stage2/asm.S (config_file) [STAGE1_5]: Set the first 4 bytes
|
||||||
|
to 0xffffffff and the following to "/boot/grub/stage2".
|
||||||
|
(config_file) [!STAGE1_5]: Set to "/boot/grub/menu.lst".
|
||||||
|
* stage2/builtins.c (install_func): Read a Stage 2 before
|
||||||
|
handling the `p' option.
|
||||||
|
If the `configfile' option is present and FILE is a Stage 2,
|
||||||
|
translate the device name to the internal device representation
|
||||||
|
and copy the result to STR.
|
||||||
|
* stage2/disk_io.c [STAGE1_5] (sane_partition): Eliminated.
|
||||||
|
[STAGE1_5] (incomplete): Likewise.
|
||||||
|
[STAGE1_5] (disk_choice): Likewise.
|
||||||
|
[STAGE1_5] (part_choice): Likewise.
|
||||||
|
(set_device) [STAGE1_5]: Assume that the first 4 bytes of DEVICE
|
||||||
|
is a device number. Set DRIVE to the forth byte of DEV and
|
||||||
|
PARTITION to the first 3 bytes of DEV. If DRIVE is 0xFF, set
|
||||||
|
CURRENT_DRIVE and CURRENT_PARTITION to SAVED_DRIVE and
|
||||||
|
SAVED_PARTITION, respectively. Otherwise set to DRIVE and
|
||||||
|
PARTITION, respectively.
|
||||||
|
(setup_part) [STAGE1_5]: Always call set_device.
|
||||||
|
|
||||||
1999-09-24 OKUJI Yoshinori <okuji@kuicr.kyoto-u.ac.jp>
|
1999-09-24 OKUJI Yoshinori <okuji@kuicr.kyoto-u.ac.jp>
|
||||||
|
|
||||||
* acinclude.m4 (grub_CHECK_END_SYMBOL): Add a missing
|
* acinclude.m4 (grub_CHECK_END_SYMBOL): Add a missing
|
||||||
|
|
2
NEWS
2
NEWS
|
@ -27,6 +27,8 @@ New in 0.5.93:
|
||||||
* Killing (C-u and C-k), yanking (C-y) and manipulating the history
|
* Killing (C-u and C-k), yanking (C-y) and manipulating the history
|
||||||
(C-p and C-n) are supported.
|
(C-p and C-n) are supported.
|
||||||
* The address argument for the command "install" is now optional.
|
* The address argument for the command "install" is now optional.
|
||||||
|
* Better completion support.
|
||||||
|
* The command "cat" displays the contents of a file.
|
||||||
|
|
||||||
New in 0.5.92 - 1999-07-26:
|
New in 0.5.92 - 1999-07-26:
|
||||||
* Bug fixes (i.e. Stage 1.5 can work fine again).
|
* Bug fixes (i.e. Stage 1.5 can work fine again).
|
||||||
|
|
19
README
19
README
|
@ -18,8 +18,23 @@ you use the following utilities:
|
||||||
* binutils 2.9.1.0.23 and later (Do not use early 2.9.1.0.x!)
|
* binutils 2.9.1.0.23 and later (Do not use early 2.9.1.0.x!)
|
||||||
|
|
||||||
Binutils has changed the behavior of 16bit assembler between 2.9.1
|
Binutils has changed the behavior of 16bit assembler between 2.9.1
|
||||||
and 2.9.1.0.x, and we support only 2.9.1.0.x. It is available from
|
and 2.9.1.0.x, and we support only 2.9.1.0.x and higher. It is available
|
||||||
ftp.XX.kernel.org (XX is the country code, such as `jp').
|
from ftp.varesearch.com:/pub/support/hjl/binutils.
|
||||||
|
|
||||||
|
NOTE: you should check for the version of your binutils by the following
|
||||||
|
command:
|
||||||
|
|
||||||
|
$ gcc -Wl,-v 2>&1 | grep "GNU ld"
|
||||||
|
|
||||||
|
This will show two versions, like this:
|
||||||
|
|
||||||
|
GNU ld version 2.9.5 (with BFD 2.9.5.0.13)
|
||||||
|
|
||||||
|
The latter is what you should see. If you have installed a recent
|
||||||
|
version of binutils but this version number is not identical with it,
|
||||||
|
GCC uses a fixed path rather than the environment variable PATH to find
|
||||||
|
binutils. In this case, you need to install your binutils into the path
|
||||||
|
which GCC sees (typically, /usr/bin), or reinstall GCC.
|
||||||
|
|
||||||
|
|
||||||
These below are required when you develop GRUB or when you get it from
|
These below are required when you develop GRUB or when you get it from
|
||||||
|
|
|
@ -270,11 +270,11 @@ else
|
||||||
grub_cv_check_uscore_end_symbol=no
|
grub_cv_check_uscore_end_symbol=no
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
rm -f conftest*])
|
||||||
|
|
||||||
if test "x$grub_cv_check_uscore_end_symbol" = xyes; then
|
if test "x$grub_cv_check_uscore_end_symbol" = xyes; then
|
||||||
AC_DEFINE([HAVE_USCORE_END_SYMBOL])
|
AC_DEFINE([HAVE_USCORE_END_SYMBOL])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
rm -f conftest*])
|
|
||||||
|
|
||||||
AC_MSG_RESULT([$grub_cv_check_uscore_end_symbol])
|
AC_MSG_RESULT([$grub_cv_check_uscore_end_symbol])
|
||||||
])
|
])
|
||||||
|
|
4
aclocal.m4
vendored
4
aclocal.m4
vendored
|
@ -282,12 +282,12 @@ else
|
||||||
grub_cv_check_uscore_end_symbol=no
|
grub_cv_check_uscore_end_symbol=no
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
rm -f conftest*])
|
||||||
|
|
||||||
if test "x$grub_cv_check_uscore_end_symbol" = xyes; then
|
if test "x$grub_cv_check_uscore_end_symbol" = xyes; then
|
||||||
AC_DEFINE([HAVE_USCORE_END_SYMBOL])
|
AC_DEFINE([HAVE_USCORE_END_SYMBOL])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
rm -f conftest*])
|
|
||||||
|
|
||||||
AC_MSG_RESULT([$grub_cv_check_uscore_end_symbol])
|
AC_MSG_RESULT([$grub_cv_check_uscore_end_symbol])
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
8
configure
vendored
8
configure
vendored
|
@ -1765,6 +1765,10 @@ else
|
||||||
grub_cv_check_uscore_end_symbol=no
|
grub_cv_check_uscore_end_symbol=no
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
rm -f conftest*
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
if test "x$grub_cv_check_uscore_end_symbol" = xyes; then
|
if test "x$grub_cv_check_uscore_end_symbol" = xyes; then
|
||||||
cat >> confdefs.h <<\EOF
|
cat >> confdefs.h <<\EOF
|
||||||
#define HAVE_USCORE_END_SYMBOL 1
|
#define HAVE_USCORE_END_SYMBOL 1
|
||||||
|
@ -1772,10 +1776,6 @@ EOF
|
||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
rm -f conftest*
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
echo "$ac_t""$grub_cv_check_uscore_end_symbol" 1>&6
|
echo "$ac_t""$grub_cv_check_uscore_end_symbol" 1>&6
|
||||||
|
|
||||||
if test "x$grub_cv_check_end_symbol" != "xyes" \
|
if test "x$grub_cv_check_end_symbol" != "xyes" \
|
||||||
|
|
|
@ -405,7 +405,7 @@ blocklist_default_start:
|
||||||
sectors from the start of the disk, sector 0 */
|
sectors from the start of the disk, sector 0 */
|
||||||
blocklist_default_len:
|
blocklist_default_len:
|
||||||
/* this is the number of sectors to read */
|
/* this is the number of sectors to read */
|
||||||
.word (STAGE2_SIZE + 511) / 512
|
.word (STAGE2_SIZE + 511) >> 9
|
||||||
blocklist_default_seg:
|
blocklist_default_seg:
|
||||||
.word 0x0800 /* this is the segment of the starting address
|
.word 0x0800 /* this is the segment of the starting address
|
||||||
to load the data into */
|
to load the data into */
|
||||||
|
|
|
@ -352,7 +352,7 @@ blocklist_default_start:
|
||||||
sectors from the start of the disk, sector 0 */
|
sectors from the start of the disk, sector 0 */
|
||||||
blocklist_default_len:
|
blocklist_default_len:
|
||||||
/* this is the number of sectors to read */
|
/* this is the number of sectors to read */
|
||||||
.word (STAGE2_SIZE + 511) / 512
|
.word (STAGE2_SIZE + 511) >> 9
|
||||||
blocklist_default_seg:
|
blocklist_default_seg:
|
||||||
.word 0x0800 /* this is the segment of the starting address
|
.word 0x0800 /* this is the segment of the starting address
|
||||||
to load the data into */
|
to load the data into */
|
||||||
|
|
|
@ -32,8 +32,7 @@ STAGE2_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,8000
|
||||||
STAGE2_COMPILE = $(STAGE2_CFLAGS) -fno-builtin -nostdinc
|
STAGE2_COMPILE = $(STAGE2_CFLAGS) -fno-builtin -nostdinc
|
||||||
|
|
||||||
STAGE1_5_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,2000
|
STAGE1_5_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,2000
|
||||||
STAGE1_5_COMPILE = $(STAGE2_COMPILE) -DNO_DECOMPRESSION=1 -DSTAGE1_5=1 \
|
STAGE1_5_COMPILE = $(STAGE2_COMPILE) -DNO_DECOMPRESSION=1 -DSTAGE1_5=1
|
||||||
-DCONFIG_FILE_ASM='.string "/boot/grub/stage2"'
|
|
||||||
|
|
||||||
# asm.S absolutely needs to come first!
|
# asm.S absolutely needs to come first!
|
||||||
# For stage2 target.
|
# For stage2 target.
|
||||||
|
|
|
@ -66,11 +66,12 @@ VARIABLE(stage2_id)
|
||||||
VARIABLE(version_string)
|
VARIABLE(version_string)
|
||||||
.string VERSION
|
.string VERSION
|
||||||
VARIABLE(config_file)
|
VARIABLE(config_file)
|
||||||
#ifndef CONFIG_FILE_ASM
|
#ifndef STAGE1_5
|
||||||
.string "/boot/grub/menu.lst"
|
.string "/boot/grub/menu.lst"
|
||||||
#else /* CONFIG_FILE_ASM */
|
#else /* STAGE1_5 */
|
||||||
CONFIG_FILE_ASM
|
.long 0xffffffff
|
||||||
#endif /* CONFIG_FILE_ASM */
|
.string "/boot/grub/stage2"
|
||||||
|
#endif /* STAGE1_5 */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Leave some breathing room for the config file name.
|
* Leave some breathing room for the config file name.
|
||||||
|
|
|
@ -127,6 +127,37 @@ static struct builtin builtin_boot =
|
||||||
"Boot the OS/chain-loader which has been loaded."
|
"Boot the OS/chain-loader which has been loaded."
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
cat_func (char *arg, int flags)
|
||||||
|
{
|
||||||
|
int len;
|
||||||
|
char *ptr;
|
||||||
|
|
||||||
|
if (! grub_open (arg))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
len = grub_read ((char *) RAW_ADDR (0x100000), -1);
|
||||||
|
if (errnum)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
ptr = (char *) RAW_ADDR (0x100000);
|
||||||
|
|
||||||
|
while (len--)
|
||||||
|
grub_putchar (*ptr++);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct builtin builtin_cat =
|
||||||
|
{
|
||||||
|
"cat",
|
||||||
|
cat_func,
|
||||||
|
BUILTIN_CMDLINE,
|
||||||
|
"cat FILE",
|
||||||
|
"Print the contents of the file FILE."
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/* chainloader */
|
/* chainloader */
|
||||||
static int
|
static int
|
||||||
|
@ -502,6 +533,7 @@ geometry_func (char *arg, int flags)
|
||||||
current_drive,
|
current_drive,
|
||||||
geom.cylinders, geom.heads, geom.sectors,
|
geom.cylinders, geom.heads, geom.sectors,
|
||||||
geom.total_sectors, msg);
|
geom.total_sectors, msg);
|
||||||
|
real_open_partition (1);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -728,6 +760,10 @@ install_func (char *arg, int flags)
|
||||||
int stage2_sect;
|
int stage2_sect;
|
||||||
char *ptr;
|
char *ptr;
|
||||||
int installaddr, installlist;
|
int installaddr, installlist;
|
||||||
|
/* Point to the location of the name of a configuration file in Stage 2. */
|
||||||
|
char *config_file_location;
|
||||||
|
/* If FILE is a Stage 1.5? */
|
||||||
|
int is_stage1_5 = 0;
|
||||||
|
|
||||||
/* Save the first sector of Stage2 in STAGE2_SECT. */
|
/* Save the first sector of Stage2 in STAGE2_SECT. */
|
||||||
static void disk_read_savesect_func (int sector)
|
static void disk_read_savesect_func (int sector)
|
||||||
|
@ -926,33 +962,16 @@ install_func (char *arg, int flags)
|
||||||
/* Stage 2. */
|
/* Stage 2. */
|
||||||
installaddr = 0x8000;
|
installaddr = 0x8000;
|
||||||
else
|
else
|
||||||
/* Stage 1.5. */
|
{
|
||||||
installaddr = 0x2000;
|
/* Stage 1.5. */
|
||||||
|
installaddr = 0x2000;
|
||||||
|
is_stage1_5 = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*((unsigned short *) (BOOTSEC_LOCATION + STAGE1_INSTALLADDR))
|
*((unsigned short *) (BOOTSEC_LOCATION + STAGE1_INSTALLADDR))
|
||||||
= installaddr;
|
= installaddr;
|
||||||
|
|
||||||
if (*ptr == 'p')
|
|
||||||
{
|
|
||||||
write_stage2_sect = 1;
|
|
||||||
*((long *) (SCRATCHADDR + STAGE2_INSTALLPART)) = current_partition;
|
|
||||||
ptr = skip_to (0, ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*ptr)
|
|
||||||
{
|
|
||||||
char *str = ((char *) (SCRATCHADDR + STAGE2_VER_STR_OFFS));
|
|
||||||
|
|
||||||
write_stage2_sect = 1;
|
|
||||||
/* Find a string for the configuration filename. */
|
|
||||||
while (*(str++))
|
|
||||||
;
|
|
||||||
/* Copy the filename to Stage 2. */
|
|
||||||
while ((*(str++) = *(ptr++)) != 0)
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read the whole of Stage 2. */
|
/* Read the whole of Stage 2. */
|
||||||
filepos = 0;
|
filepos = 0;
|
||||||
disk_read_hook = disk_read_blocklist_func;
|
disk_read_hook = disk_read_blocklist_func;
|
||||||
|
@ -962,6 +981,55 @@ install_func (char *arg, int flags)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Find a string for the configuration filename. */
|
||||||
|
config_file_location = ((char *) (SCRATCHADDR + STAGE2_VER_STR_OFFS));
|
||||||
|
while (*(config_file_location++))
|
||||||
|
;
|
||||||
|
|
||||||
|
if (*ptr == 'p')
|
||||||
|
{
|
||||||
|
write_stage2_sect = 1;
|
||||||
|
*((long *) (SCRATCHADDR + STAGE2_INSTALLPART)) = current_partition;
|
||||||
|
if (is_stage1_5)
|
||||||
|
{
|
||||||
|
/* Reset the device information in FILE if it is a Stage 1.5. */
|
||||||
|
int device = 0xFFFFFFFF;
|
||||||
|
|
||||||
|
grub_memmove (config_file_location, (char *) &device, sizeof (int));
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr = skip_to (0, ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*ptr)
|
||||||
|
{
|
||||||
|
write_stage2_sect = 1;
|
||||||
|
|
||||||
|
if (! is_stage1_5)
|
||||||
|
/* If it is a Stage 2, just copy PTR to CONFIG_FILE_LOCATION. */
|
||||||
|
grub_strcpy (config_file_location, ptr);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char *config_file;
|
||||||
|
int device;
|
||||||
|
int tmp = current_drive;
|
||||||
|
|
||||||
|
/* Translate the external device syntax to the internal device
|
||||||
|
syntax. */
|
||||||
|
if (! (config_file = set_device (ptr)))
|
||||||
|
{
|
||||||
|
errnum = 0;
|
||||||
|
current_drive = 0xFF;
|
||||||
|
config_file = ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
device = current_drive << 24 | current_partition;
|
||||||
|
current_drive = tmp;
|
||||||
|
grub_memmove (config_file_location, (char *) &device, sizeof (int));
|
||||||
|
grub_strcpy (config_file_location + sizeof (int), config_file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Clear the cache. */
|
/* Clear the cache. */
|
||||||
buf_track = -1;
|
buf_track = -1;
|
||||||
|
|
||||||
|
@ -1507,6 +1575,7 @@ static struct builtin builtin_uppermem =
|
||||||
struct builtin *builtin_table[] =
|
struct builtin *builtin_table[] =
|
||||||
{
|
{
|
||||||
&builtin_boot,
|
&builtin_boot,
|
||||||
|
&builtin_cat,
|
||||||
&builtin_chainloader,
|
&builtin_chainloader,
|
||||||
&builtin_color,
|
&builtin_color,
|
||||||
&builtin_configfile,
|
&builtin_configfile,
|
||||||
|
|
|
@ -300,6 +300,7 @@ get_cmdline (char *prompt, char *cmdline, int maxlen,
|
||||||
if (lpos == llen)
|
if (lpos == llen)
|
||||||
{
|
{
|
||||||
grub_memmove (buf + lpos, str, l + 1);
|
grub_memmove (buf + lpos, str, l + 1);
|
||||||
|
cl_setcpos ();
|
||||||
cl_print (buf + lpos, echo_char);
|
cl_print (buf + lpos, echo_char);
|
||||||
lpos += l;
|
lpos += l;
|
||||||
cl_setcpos ();
|
cl_setcpos ();
|
||||||
|
@ -432,7 +433,9 @@ get_cmdline (char *prompt, char *cmdline, int maxlen,
|
||||||
/* Restore the command-line. */
|
/* Restore the command-line. */
|
||||||
if (equal_pos >= 0)
|
if (equal_pos >= 0)
|
||||||
buf[equal_pos] = '=';
|
buf[equal_pos] = '=';
|
||||||
cl_init ();
|
|
||||||
|
if (ret)
|
||||||
|
cl_init ();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 1: /* C-a go to beginning of line */
|
case 1: /* C-a go to beginning of line */
|
||||||
|
|
206
stage2/disk_io.c
206
stage2/disk_io.c
|
@ -242,14 +242,13 @@ devread (int sector, int byte_offset, int byte_len, char *buf)
|
||||||
byte_len, buf);
|
byte_len, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef STAGE1_5
|
||||||
static int
|
static int
|
||||||
sane_partition (void)
|
sane_partition (void)
|
||||||
{
|
{
|
||||||
#ifndef STAGE1_5
|
|
||||||
/* network drive */
|
/* network drive */
|
||||||
if (current_drive == 0x20)
|
if (current_drive == 0x20)
|
||||||
return 1;
|
return 1;
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!(current_partition & 0xFF000000uL)
|
if (!(current_partition & 0xFF000000uL)
|
||||||
&& (current_drive & 0xFFFFFF7F) < 8
|
&& (current_drive & 0xFFFFFF7F) < 8
|
||||||
|
@ -263,6 +262,7 @@ sane_partition (void)
|
||||||
errnum = ERR_DEV_VALUES;
|
errnum = ERR_DEV_VALUES;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif /* ! STAGE1_5 */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
attempt_mount (void)
|
attempt_mount (void)
|
||||||
|
@ -415,6 +415,16 @@ check_BSD_parts (int flags)
|
||||||
|
|
||||||
if (! do_completion)
|
if (! do_completion)
|
||||||
printf (" BSD Partition num: \'%c\', ", part_no + 'a');
|
printf (" BSD Partition num: \'%c\', ", part_no + 'a');
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char str[16];
|
||||||
|
|
||||||
|
grub_sprintf (str, "%d,%c)",
|
||||||
|
(current_partition >> 16) & 0xFF,
|
||||||
|
part_no + 'a');
|
||||||
|
print_a_completion (str);
|
||||||
|
}
|
||||||
|
|
||||||
check_and_print_mount ();
|
check_and_print_mount ();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -446,7 +456,7 @@ check_BSD_parts (int flags)
|
||||||
static char cur_part_desc[16];
|
static char cur_part_desc[16];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int
|
int
|
||||||
real_open_partition (int flags)
|
real_open_partition (int flags)
|
||||||
{
|
{
|
||||||
char mbr_buf[SECTOR_SIZE];
|
char mbr_buf[SECTOR_SIZE];
|
||||||
|
@ -543,14 +553,30 @@ real_open_partition (int flags)
|
||||||
{
|
{
|
||||||
current_partition |= 0xFFFF;
|
current_partition |= 0xFFFF;
|
||||||
if (! do_completion)
|
if (! do_completion)
|
||||||
printf (" Partition num: %d, ", slice_no);
|
{
|
||||||
if (! IS_PC_SLICE_TYPE_BSD (current_slice))
|
printf (" Partition num: %d, ", slice_no);
|
||||||
check_and_print_mount ();
|
|
||||||
|
if (! IS_PC_SLICE_TYPE_BSD (current_slice))
|
||||||
|
check_and_print_mount ();
|
||||||
|
else
|
||||||
|
check_BSD_parts (1);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
check_BSD_parts (1);
|
{
|
||||||
|
if (! IS_PC_SLICE_TYPE_BSD (current_slice))
|
||||||
|
{
|
||||||
|
char str[8];
|
||||||
|
|
||||||
|
grub_sprintf (str, "%d)", slice_no);
|
||||||
|
print_a_completion (str);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
check_BSD_parts (1);
|
||||||
|
}
|
||||||
|
|
||||||
errnum = ERR_NONE;
|
errnum = ERR_NONE;
|
||||||
}
|
}
|
||||||
# endif /* STAGE1_5 */
|
# endif /* ! STAGE1_5 */
|
||||||
/*
|
/*
|
||||||
* If we've found the right partition, we're done
|
* If we've found the right partition, we're done
|
||||||
*/
|
*/
|
||||||
|
@ -636,20 +662,42 @@ open_partition (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef STAGE1_5
|
||||||
/* XX used for device completion in 'set_device' and 'print_completions' */
|
/* XX used for device completion in 'set_device' and 'print_completions' */
|
||||||
static int incomplete, disk_choice;
|
static int incomplete, disk_choice;
|
||||||
static enum
|
static enum
|
||||||
{
|
{
|
||||||
PART_UNSPECIFIED = 0,
|
PART_UNSPECIFIED = 0,
|
||||||
PART_DISK,
|
PART_DISK,
|
||||||
PART_CHOSEN,
|
PART_CHOSEN,
|
||||||
}
|
}
|
||||||
part_choice;
|
part_choice;
|
||||||
|
#endif /* ! STAGE1_5 */
|
||||||
|
|
||||||
char *
|
char *
|
||||||
set_device (char *device)
|
set_device (char *device)
|
||||||
{
|
{
|
||||||
|
#ifdef STAGE1_5
|
||||||
|
/* In Stage 1.5, the first 4 bytes of FILENAME has a device number. */
|
||||||
|
int dev = *((int *) device);
|
||||||
|
int drive = dev >> 24;
|
||||||
|
int partition = dev & 0xFFFFFF;
|
||||||
|
|
||||||
|
if (drive == 0xFF)
|
||||||
|
{
|
||||||
|
current_drive = saved_drive;
|
||||||
|
current_partition = saved_partition;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
current_drive = drive;
|
||||||
|
current_partition = partition;
|
||||||
|
}
|
||||||
|
|
||||||
|
return device + sizeof (int);
|
||||||
|
|
||||||
|
#else /* ! STAGE1_5 */
|
||||||
|
|
||||||
/* The use of retval in this function is not really clean, but it works */
|
/* The use of retval in this function is not really clean, but it works */
|
||||||
char *retval = 0;
|
char *retval = 0;
|
||||||
|
|
||||||
|
@ -659,11 +707,9 @@ set_device (char *device)
|
||||||
current_drive = saved_drive;
|
current_drive = saved_drive;
|
||||||
current_partition = 0xFFFFFF;
|
current_partition = 0xFFFFFF;
|
||||||
|
|
||||||
#ifndef STAGE1_5
|
|
||||||
if (*device == '(' && !*(device + 1))
|
if (*device == '(' && !*(device + 1))
|
||||||
/* user has given '(' only, let disk_choice handle what disks we have */
|
/* user has given '(' only, let disk_choice handle what disks we have */
|
||||||
return device + 1;
|
return device + 1;
|
||||||
#endif
|
|
||||||
|
|
||||||
if (*device == '(' && *(++device))
|
if (*device == '(' && *(++device))
|
||||||
{
|
{
|
||||||
|
@ -671,7 +717,6 @@ set_device (char *device)
|
||||||
{
|
{
|
||||||
char ch = *device;
|
char ch = *device;
|
||||||
|
|
||||||
#ifndef STAGE1_5
|
|
||||||
if (*device == 'f' || *device == 'h')
|
if (*device == 'f' || *device == 'h')
|
||||||
{
|
{
|
||||||
/* user has given '([fh]', check for resp. add 'd' and
|
/* user has given '([fh]', check for resp. add 'd' and
|
||||||
|
@ -686,7 +731,6 @@ set_device (char *device)
|
||||||
else if (*(device + 1) == 'd' && !*(device + 2))
|
else if (*(device + 1) == 'd' && !*(device + 2))
|
||||||
return device + 2;
|
return device + 2;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
if ((*device == 'f' || *device == 'h' || *device == 'n')
|
if ((*device == 'f' || *device == 'h' || *device == 'n')
|
||||||
&& (device += 2, (*(device - 1) != 'd')))
|
&& (device += 2, (*(device - 1) != 'd')))
|
||||||
|
@ -846,6 +890,8 @@ set_device (char *device)
|
||||||
}
|
}
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
|
|
||||||
|
#endif /* ! STAGE1_5 */
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -901,6 +947,23 @@ set_bootdev (int hdbias)
|
||||||
static char *
|
static char *
|
||||||
setup_part (char *filename)
|
setup_part (char *filename)
|
||||||
{
|
{
|
||||||
|
#ifdef STAGE1_5
|
||||||
|
|
||||||
|
if (! (filename = set_device (filename)))
|
||||||
|
{
|
||||||
|
current_drive = 0xFF;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
# ifndef NO_BLOCK_FILES
|
||||||
|
if (*filename != '/')
|
||||||
|
open_partition ();
|
||||||
|
else
|
||||||
|
# endif /* ! NO_BLOCK_FILES */
|
||||||
|
open_device ();
|
||||||
|
|
||||||
|
#else /* ! STAGE1_5 */
|
||||||
|
|
||||||
/* FIXME: decide on syntax for blocklist vs. old-style vs. /dev/hd0s1 */
|
/* FIXME: decide on syntax for blocklist vs. old-style vs. /dev/hd0s1 */
|
||||||
/* Strip any leading /dev. */
|
/* Strip any leading /dev. */
|
||||||
if (substring ("/dev/", filename) < 1)
|
if (substring ("/dev/", filename) < 1)
|
||||||
|
@ -913,11 +976,11 @@ setup_part (char *filename)
|
||||||
current_drive = 0xFF;
|
current_drive = 0xFF;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#ifndef NO_BLOCK_FILES
|
# ifndef NO_BLOCK_FILES
|
||||||
if (*filename != '/')
|
if (*filename != '/')
|
||||||
open_partition ();
|
open_partition ();
|
||||||
else
|
else
|
||||||
#endif /* NO_BLOCK_FILES */
|
# endif /* ! NO_BLOCK_FILES */
|
||||||
open_device ();
|
open_device ();
|
||||||
}
|
}
|
||||||
else if (saved_drive != current_drive
|
else if (saved_drive != current_drive
|
||||||
|
@ -929,14 +992,16 @@ setup_part (char *filename)
|
||||||
current_partition = saved_partition;
|
current_partition = saved_partition;
|
||||||
/* allow for the error case of "no filesystem" after the partition
|
/* allow for the error case of "no filesystem" after the partition
|
||||||
is found. This makes block files work fine on no filesystem */
|
is found. This makes block files work fine on no filesystem */
|
||||||
#ifndef NO_BLOCK_FILES
|
# ifndef NO_BLOCK_FILES
|
||||||
if (*filename != '/')
|
if (*filename != '/')
|
||||||
open_partition ();
|
open_partition ();
|
||||||
else
|
else
|
||||||
#endif /* NO_BLOCK_FILES */
|
# endif /* ! NO_BLOCK_FILES */
|
||||||
open_device ();
|
open_device ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* ! STAGE1_5 */
|
||||||
|
|
||||||
if (errnum && (*filename == '/' || errnum != ERR_FSYS_MOUNT))
|
if (errnum && (*filename == '/' || errnum != ERR_FSYS_MOUNT))
|
||||||
return 0;
|
return 0;
|
||||||
else
|
else
|
||||||
|
@ -982,6 +1047,10 @@ print_fsys_type (void)
|
||||||
void
|
void
|
||||||
print_a_completion (char *name)
|
print_a_completion (char *name)
|
||||||
{
|
{
|
||||||
|
/* If NAME is "." or "..", do not count it. */
|
||||||
|
if (grub_strcmp (name, ".") == 0 || grub_strcmp (name, "..") == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
if (do_completion)
|
if (do_completion)
|
||||||
{
|
{
|
||||||
char *buf = unique_string;
|
char *buf = unique_string;
|
||||||
|
@ -1053,6 +1122,9 @@ print_completions (int is_filename, int is_completion)
|
||||||
grub_strcpy (buf, unique_string);
|
grub_strcpy (buf, unique_string);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (! is_completion)
|
||||||
|
grub_putchar ('\n');
|
||||||
|
|
||||||
do_completion = 0;
|
do_completion = 0;
|
||||||
return unique - 1;
|
return unique - 1;
|
||||||
}
|
}
|
||||||
|
@ -1082,12 +1154,9 @@ print_completions (int is_filename, int is_completion)
|
||||||
if ((disk_choice || disk_no == current_drive)
|
if ((disk_choice || disk_no == current_drive)
|
||||||
&& ! get_diskinfo (disk_no, &geom))
|
&& ! get_diskinfo (disk_no, &geom))
|
||||||
{
|
{
|
||||||
char dev_name[4];
|
char dev_name[8];
|
||||||
|
|
||||||
dev_name[0] = (i ? 'h' : 'f');
|
grub_sprintf (dev_name, "%cd%d", i ? 'h' : 'f', j);
|
||||||
dev_name[1] = 'd';
|
|
||||||
dev_name[2] = '0' + j;
|
|
||||||
dev_name[3] = '\0';
|
|
||||||
print_a_completion (dev_name);
|
print_a_completion (dev_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1099,22 +1168,25 @@ print_completions (int is_filename, int is_completion)
|
||||||
while (*ptr != '(')
|
while (*ptr != '(')
|
||||||
ptr--;
|
ptr--;
|
||||||
ptr++;
|
ptr++;
|
||||||
{
|
grub_strcpy (ptr, unique_string);
|
||||||
char *u = unique_string;
|
if (unique == 1)
|
||||||
while ((*ptr++ = *u++))
|
{
|
||||||
;
|
ptr += grub_strlen (ptr);
|
||||||
ptr--;
|
if (*unique_string == 'h')
|
||||||
}
|
{
|
||||||
ptr--;
|
*ptr++ = ',';
|
||||||
if ((*(ptr - 2) == 'h') && (*(ptr - 1) == 'd')
|
*ptr = 0;
|
||||||
&& ('0' <= *ptr && *ptr <= '8'))
|
}
|
||||||
*(ptr + 1) = ',', *(ptr + 2) = '\0';
|
else
|
||||||
if ((*(ptr - 2) == 'f') && (*(ptr - 1) == 'd')
|
{
|
||||||
&& ('0' <= *ptr && *ptr <= '8'))
|
*ptr++ = ')';
|
||||||
*(ptr + 1) = ')', *(ptr + 2) = '\0';
|
*ptr = 0;
|
||||||
|
}
|
||||||
grub_putchar ('\n');
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (! is_completion)
|
||||||
|
grub_putchar ('\n');
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1124,21 +1196,26 @@ print_completions (int is_filename, int is_completion)
|
||||||
if (! is_completion)
|
if (! is_completion)
|
||||||
grub_printf (" Possible partitions are:\n");
|
grub_printf (" Possible partitions are:\n");
|
||||||
real_open_partition (1);
|
real_open_partition (1);
|
||||||
|
|
||||||
|
if (is_completion && *unique_string)
|
||||||
|
{
|
||||||
|
ptr = buf;
|
||||||
|
while (*ptr++ != ',')
|
||||||
|
;
|
||||||
|
grub_strcpy (ptr, unique_string);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (open_partition ())
|
if (open_partition ())
|
||||||
{
|
{
|
||||||
check_and_print_mount ();
|
unique = 1;
|
||||||
/* FIXME: Can talk about linux only, do we need
|
ptr = buf + grub_strlen (buf);
|
||||||
to know about syntax here? */
|
|
||||||
ptr = buf;
|
|
||||||
while (*ptr)
|
|
||||||
ptr++;
|
|
||||||
if (*(ptr - 1) != ')')
|
if (*(ptr - 1) != ')')
|
||||||
*ptr++ = ')';
|
{
|
||||||
*ptr++ = '/';
|
*ptr++ = ')';
|
||||||
*ptr = '\0';
|
*ptr = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1158,16 +1235,33 @@ print_completions (int is_filename, int is_completion)
|
||||||
ptr--;
|
ptr--;
|
||||||
ptr++;
|
ptr++;
|
||||||
|
|
||||||
|
grub_strcpy (ptr, unique_string);
|
||||||
|
|
||||||
if (unique == 1)
|
if (unique == 1)
|
||||||
{
|
{
|
||||||
char *u = unique_string + grub_strlen (unique_string);
|
ptr += grub_strlen (unique_string);
|
||||||
|
|
||||||
*u++ = ' ';
|
/* Check if the file UNIQUE_STRING is a directory. */
|
||||||
*u = 0;
|
*ptr = '/';
|
||||||
|
*(ptr + 1) = 0;
|
||||||
|
|
||||||
|
dir (buf);
|
||||||
|
|
||||||
|
/* Restore the original unique value. */
|
||||||
|
unique = 1;
|
||||||
|
|
||||||
|
if (errnum)
|
||||||
|
{
|
||||||
|
/* Regular file */
|
||||||
|
errnum = 0;
|
||||||
|
*ptr = ' ';
|
||||||
|
*(ptr + 1) = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
grub_strcpy (ptr, unique_string);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (! is_completion)
|
||||||
|
grub_putchar ('\n');
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
errnum = ERR_BAD_FILENAME;
|
errnum = ERR_BAD_FILENAME;
|
||||||
|
|
|
@ -705,7 +705,9 @@ ext2fs_dir (char *dirname)
|
||||||
{
|
{
|
||||||
if (print_possibilities < 0)
|
if (print_possibilities < 0)
|
||||||
{
|
{
|
||||||
|
# if 0
|
||||||
putchar ('\n');
|
putchar ('\n');
|
||||||
|
# endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -211,7 +211,9 @@ loop:
|
||||||
{
|
{
|
||||||
if (print_possibilities < 0)
|
if (print_possibilities < 0)
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
putchar ('\n');
|
putchar ('\n');
|
||||||
|
#endif
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -240,7 +240,9 @@ loop:
|
||||||
{
|
{
|
||||||
if (loc >= INODE->i_size)
|
if (loc >= INODE->i_size)
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
putchar ('\n');
|
putchar ('\n');
|
||||||
|
#endif
|
||||||
|
|
||||||
if (print_possibilities < 0)
|
if (print_possibilities < 0)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
@ -463,7 +463,9 @@ minix_dir (char *dirname)
|
||||||
{
|
{
|
||||||
if (print_possibilities < 0)
|
if (print_possibilities < 0)
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
putchar ('\n');
|
putchar ('\n');
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -640,6 +640,7 @@ int devread (int sector, int byte_offset, int byte_len, char *buf);
|
||||||
/* Parse a device string and initialize the global parameters. */
|
/* Parse a device string and initialize the global parameters. */
|
||||||
char *set_device (char *device);
|
char *set_device (char *device);
|
||||||
int open_device (void);
|
int open_device (void);
|
||||||
|
int real_open_partition (int flags);
|
||||||
int open_partition (void);
|
int open_partition (void);
|
||||||
|
|
||||||
/* Sets device to the one represented by the SAVED_* parameters. */
|
/* Sets device to the one represented by the SAVED_* parameters. */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue