call embed from setup.

This commit is contained in:
okuji 1999-10-15 10:01:17 +00:00
parent 8f83254679
commit f0932cbf46
7 changed files with 216 additions and 57 deletions

View file

@ -1,3 +1,27 @@
1999-10-15 OKUJI Yoshinori <okuji@kuicr.kyoto-u.ac.jp>
* stage2/builtins.c (setup_func): Save CURRENT_DRIVE and
CURRENT_PARTITION into IMAGE_DRIVE and IMAGE_PARTITION
respectively, and restore them before running install_func.
Use DEVICE instead of BUFFER to store the device name.
Change each type of STAGE1, STAGE2 and CONFIG_FILE to an array
of char.
If installing the Stage 1 into a MBR, embed the Stage 1.5 in the
sectors right after it.
Return the result of install_func instead of zero.
1999-10-14 Pavel Roskin <pavel_roskin@geocities.com>
* configure.in: Check for opendisk in libutil.
* grub/asmstub.c [__FreeBSD__ || __NetBSD__]: Include
<sys/ioctl.h>.
[HAVE_OPENDISK]: Include <util.h>.
[__NetBSD__] (get_floppy_disk_name): Added support for NetBSD.
[__NetBSD__ && HAVE_OPENDISK] (get_ide_disk_name): Likewise.
[__NetBSD__ && HAVE_OPENDISK] (get_scsi_disk_name): Likewise.
(get_drive_geometry) [__NetBSD__]: Use for NetBSD the same ioctl
as for FreeBSD.
1999-10-13 OKUJI Yoshinori <okuji@kuicr.kyoto-u.ac.jp>
* grub/asmstub.c (assign_device_name): If DEVICE is NULL, set

1
NEWS
View file

@ -11,6 +11,7 @@ New in 0.5.94:
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.
* NetBSD support in the grub shell is improved.
New in 0.5.93:
* ELF format of FreeBSD kernel is supported.

View file

@ -45,3 +45,6 @@
/* Define it to "data32" or "data32;" to make GAS happy */
#undef DATA32
/* Define if opendisk() in -lutil can be used */
#undef HAVE_OPENDISK

79
configure vendored
View file

@ -1860,10 +1860,57 @@ if test "${with_curses+set}" = set; then
fi
# Get the filename or the whole disk and open it.
# Known to work on NetBSD.
echo $ac_n "checking for opendisk in -lutil""... $ac_c" 1>&6
echo "configure:1867: checking for opendisk in -lutil" >&5
ac_lib_var=`echo util'_'opendisk | sed 'y%./+-:%__p__%'`
if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
ac_save_LIBS="$LIBS"
LIBS="-lutil $LIBS"
cat > conftest.$ac_ext <<EOF
#line 1875 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char opendisk();
int main() {
opendisk()
; return 0; }
EOF
if { (eval echo configure:1886: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=no"
fi
rm -f conftest*
LIBS="$ac_save_LIBS"
fi
if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
echo "$ac_t""yes" 1>&6
GRUB_LIBS="$GRUB_LIBS -lutil"
cat >> confdefs.h <<\EOF
#define HAVE_OPENDISK 1
EOF
else
echo "$ac_t""no" 1>&6
fi
# Unless the user specify --without-curses, check for curses.
if test "x$with_curses" != "xno"; then
echo $ac_n "checking for wgetch in -lncurses""... $ac_c" 1>&6
echo "configure:1867: checking for wgetch in -lncurses" >&5
echo "configure:1914: checking for wgetch in -lncurses" >&5
ac_lib_var=`echo ncurses'_'wgetch | sed 'y%./+-:%__p__%'`
if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@ -1871,7 +1918,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lncurses $LIBS"
cat > conftest.$ac_ext <<EOF
#line 1875 "configure"
#line 1922 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@ -1882,7 +1929,7 @@ int main() {
wgetch()
; return 0; }
EOF
if { (eval echo configure:1886: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
if { (eval echo configure:1933: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@ -1905,7 +1952,7 @@ EOF
else
echo "$ac_t""no" 1>&6
echo $ac_n "checking for wgetch in -lcurses""... $ac_c" 1>&6
echo "configure:1909: checking for wgetch in -lcurses" >&5
echo "configure:1956: checking for wgetch in -lcurses" >&5
ac_lib_var=`echo curses'_'wgetch | sed 'y%./+-:%__p__%'`
if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@ -1913,7 +1960,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lcurses $LIBS"
cat > conftest.$ac_ext <<EOF
#line 1917 "configure"
#line 1964 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@ -1924,7 +1971,7 @@ int main() {
wgetch()
; return 0; }
EOF
if { (eval echo configure:1928: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
if { (eval echo configure:1975: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@ -1956,7 +2003,7 @@ fi
# Check for headers.
echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
echo "configure:1960: checking how to run the C preprocessor" >&5
echo "configure:2007: checking how to run the C preprocessor" >&5
# On Suns, sometimes $CPP names a directory.
if test -n "$CPP" && test -d "$CPP"; then
CPP=
@ -1971,13 +2018,13 @@ else
# On the NeXT, cc -E runs the code through the compiler's parser,
# not just through cpp.
cat > conftest.$ac_ext <<EOF
#line 1975 "configure"
#line 2022 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:1981: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
{ (eval echo configure:2028: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
:
@ -1988,13 +2035,13 @@ else
rm -rf conftest*
CPP="${CC-cc} -E -traditional-cpp"
cat > conftest.$ac_ext <<EOF
#line 1992 "configure"
#line 2039 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:1998: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
{ (eval echo configure:2045: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
:
@ -2005,13 +2052,13 @@ else
rm -rf conftest*
CPP="${CC-cc} -nologo -E"
cat > conftest.$ac_ext <<EOF
#line 2009 "configure"
#line 2056 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:2015: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
{ (eval echo configure:2062: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
:
@ -2039,17 +2086,17 @@ for ac_hdr in string.h strings.h ncurses/curses.h ncurses.h curses.h
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
echo "configure:2043: checking for $ac_hdr" >&5
echo "configure:2090: checking for $ac_hdr" >&5
if eval "test \"\${ac_cv_header_$ac_safe+set}\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 2048 "configure"
#line 2095 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:2053: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
{ (eval echo configure:2100: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*

View file

@ -132,6 +132,11 @@ fi
AC_ARG_WITH(curses,
[ --without-curses do not use curses])
# Get the filename or the whole disk and open it.
# Known to work on NetBSD.
AC_CHECK_LIB(util, opendisk, [GRUB_LIBS="$GRUB_LIBS -lutil"
AC_DEFINE(HAVE_OPENDISK, 1, [Define if opendisk() in -lutil can be used])])
# Unless the user specify --without-curses, check for curses.
if test "x$with_curses" != "xno"; then
AC_CHECK_LIB(ncurses, wgetch, [GRUB_LIBS="$GRUB_LIBS -lncurses"

View file

@ -58,9 +58,14 @@ int grub_stage2 (void);
# endif /* ! BLKFLSBUF */
#endif /* __linux__ */
#ifdef __FreeBSD__
#if defined(__FreeBSD__) || defined(__NetBSD__)
# include <sys/ioctl.h> /* ioctl */
# include <sys/disklabel.h>
#endif /* __FreeBSD__ */
#endif /* __FreeBSD__ || __NetBSD__ */
#ifdef HAVE_OPENDISK
# include <util.h>
#endif /* HAVE_OPENDISK */
/* Simulated memory sizes. */
#define EXTENDED_MEMSIZE (4 * 1024 * 1024) /* 4MB */
@ -397,8 +402,12 @@ get_floppy_disk_name (char *name, int unit)
#elif defined(__FreeBSD__)
/* FreeBSD */
sprintf (name, "/dev/rfd%d", unit);
#elif defined(__NetBSD__)
/* NetBSD */
/* opendisk() doesn't work for floppies. */
sprintf (name, "/dev/rfd%da", unit);
#else
# warning "BIOS drives cannot be guessed in your operating system."
# warning "BIOS floppy drives cannot be guessed in your operating system."
/* Set NAME to a bogus string. */
*name = 0;
#endif
@ -416,8 +425,19 @@ get_ide_disk_name (char *name, int unit)
#elif defined(__FreeBSD__)
/* FreeBSD */
sprintf (name, "/dev/rwd%d", unit);
#elif defined(__NetBSD__) && defined(HAVE_OPENDISK)
/* NetBSD */
char shortname[16];
int fd;
sprintf (shortname, "wd%d", unit);
fd = opendisk (shortname, O_RDONLY, name,
16, /* length of NAME */
0 /* char device */
);
close (fd);
#else
# warning "BIOS drives cannot be guessed in your operating system."
# warning "BIOS IDE drives cannot be guessed in your operating system."
/* Set NAME to a bogus string. */
*name = 0;
#endif
@ -435,8 +455,19 @@ get_scsi_disk_name (char *name, int unit)
#elif defined(__FreeBSD__)
/* FreeBSD */
sprintf (name, "/dev/rda%d", unit);
#elif defined(__NetBSD__) && defined(HAVE_OPENDISK)
/* NetBSD */
char shortname[16];
int fd;
sprintf (shortname, "sd%d", unit);
fd = opendisk (shortname, O_RDONLY, name,
16, /* length of NAME */
0 /* char device */
);
close (fd);
#else
# warning "BIOS drives cannot be guessed in your operating system."
# warning "BIOS SCSI drives cannot be guessed in your operating system."
/* Set NAME to a bogus string. */
*name = 0;
#endif
@ -787,7 +818,7 @@ get_drive_geometry (int drive)
geom->total_sectors = hdg.cylinders * hdg.heads * hdg.sectors;
return 1;
#elif defined(__FreeBSD__)
#elif defined(__FreeBSD__) || defined(__NetBSD__)
/* FreeBSD */
struct disklabel hdg;
if (ioctl (disks[drive].flags, DIOCGDINFO, &hdg))

View file

@ -1607,36 +1607,37 @@ setup_func (char *arg, int flags)
reside. */
char *image_ptr;
int install_drive, install_partition;
char *stage1 = "/boot/grub/stage1";
char *stage2 = "/boot/grub/stage2";
char *config_file = "/boot/grub/menu.lst";
char install_arg[256];
char buffer[32];
int image_drive, image_partition;
char stage1[64];
char stage2[64];
char config_file[64];
char cmd_arg[256];
char device[16];
char *buffer = (char *) RAW_ADDR (0x100000);
static void sprint_device (int drive, int partition)
{
grub_sprintf (buffer, "(%cd%d",
grub_sprintf (device, "(%cd%d",
(drive & 0x80) ? 'h' : 'f',
drive & ~0x80);
if ((partition & 0xFF0000) != 0xFF0000)
{
char tmp[16];
grub_sprintf (tmp, ",%d", (partition >> 16) & 0xFF);
grub_strncat (buffer, tmp, sizeof (buffer));
grub_strncat (device, tmp, 256);
}
if ((partition & 0x00FF00) != 0x00FF00)
{
char tmp[16];
grub_sprintf (tmp, ",%c", 'a' + ((partition >> 8) & 0xFF));
grub_strncat (buffer, tmp, sizeof (buffer));
grub_strncat (device, tmp, 256);
}
grub_strncat (buffer, ")", sizeof (buffer));
grub_strncat (device, ")", 256);
}
struct stage1_5_map {
char *fsys;
char *name;
};
struct stage1_5_map stage1_5_map[] =
{
{"ext2fs", "/boot/grub/e2fs_stage1_5"},
@ -1644,7 +1645,12 @@ setup_func (char *arg, int flags)
{"fat", "/boot/grub/fat_stage1_5"},
{"minix", "/boot/grub/minix_stage1_5"}
};
/* Initialize some strings. */
grub_strcpy (stage1, "/boot/grub/stage1");
grub_strcpy (stage2, "/boot/grub/stage2");
grub_strcpy (config_file, "/boot/grub/menu.lst");
install_ptr = arg;
image_ptr = skip_to (0, install_ptr);
@ -1668,10 +1674,13 @@ setup_func (char *arg, int flags)
else
{
/* If omitted, use SAVED_PARTITION and SAVED_DRIVE. */
current_partition = saved_partition;
current_drive = saved_drive;
current_partition = saved_partition;
}
image_drive = current_drive;
image_partition = current_partition;
/* Open it. */
if (! open_device ())
return 1;
@ -1684,7 +1693,7 @@ setup_func (char *arg, int flags)
/* If the drive where stage2 resides is a hard disk, try to use a
Stage 1.5. */
if (current_drive & 0x80)
if (image_drive & 0x80)
{
char *fsys = fsys_table[fsys_type].name;
int i;
@ -1692,38 +1701,77 @@ setup_func (char *arg, int flags)
/* Iterate finding the same filesystem name as FSYS. */
for (i = 0; i < size; i++)
{
if (grub_strcmp (fsys, stage1_5_map[i].fsys) == 0)
{
/* OK, check if the Stage 1.5 exists. */
if (grub_open (stage1_5_map[i].name))
{
stage2 = stage1_5_map[i].name;
config_file = stage2;
}
break;
}
}
if (grub_strcmp (fsys, stage1_5_map[i].fsys) == 0)
{
/* OK, check if the Stage 1.5 exists. */
if (grub_open (stage1_5_map[i].name))
{
grub_strcpy (config_file, stage2);
grub_strcpy (stage2, stage1_5_map[i].name);
if (install_partition == 0xFFFFFF)
{
/* We install GRUB into the MBR, so try to embed the
Stage 1.5 in the sectors right after the MBR. */
sprint_device (install_drive, install_partition);
grub_sprintf (cmd_arg, "%s %s", stage2, device);
/* Notify what will be run. */
grub_printf (" Run \"embed %s\"\n", cmd_arg);
embed_func (cmd_arg, flags);
if (! errnum)
{
int len;
/* Need to know the size of the Stage 1.5. */
filepos = 0;
len = grub_read (buffer, -1);
/* Construct the blocklist representation. */
grub_sprintf (stage2, "%s1+%d",
device,
(len + SECTOR_SIZE - 1) / SECTOR_SIZE);
/* Need to prepend the device name to the
configuration filename. */
sprint_device (image_drive, image_partition);
grub_sprintf (buffer, "%s%s", device, config_file);
grub_strcpy (config_file, buffer);
}
}
else if (grub_strcmp (fsys, "ffs") == 0)
{
/* We can embed the Stage 1.5 into the "bootloader"
area in the FFS partition. */
/* FIXME */
}
}
errnum = 0;
break;
}
}
/* Construct a string that is used by the command "install" as its
arguments. */
sprint_device (install_drive, install_partition);
grub_sprintf (install_arg, "%s %s%s %s p",
grub_sprintf (cmd_arg, "%s %s%s %s p %s",
stage1,
(install_drive != current_drive) ? "d " : "",
buffer,
stage2);
(install_drive != image_drive) ? "d " : "",
device,
stage2,
config_file);
/* Notify what will be run. */
grub_printf (" Run \"install %s\"\n", install_arg);
grub_printf (" Run \"install %s\"\n", cmd_arg);
/* Make sure that CURRENT_DRIVE and CURRENT_PARTITION are identical
with IMAGE_DRIVE and IMAGE_PARTITION, respectively. */
current_drive = image_drive;
current_partition = image_partition;
/* Run the command. */
#if 0
return install_func (install_arg, flags);
#else
return 0;
#endif
return install_func (cmd_arg, flags);
}
static struct builtin builtin_setup =