diff --git a/ChangeLog b/ChangeLog index 051356215..9da16af89 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,27 @@ +1999-10-15 OKUJI Yoshinori + + * 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 + + * configure.in: Check for opendisk in libutil. + * grub/asmstub.c [__FreeBSD__ || __NetBSD__]: Include + . + [HAVE_OPENDISK]: Include . + [__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 * grub/asmstub.c (assign_device_name): If DEVICE is NULL, set diff --git a/NEWS b/NEWS index b238bfc35..346c4ae05 100644 --- a/NEWS +++ b/NEWS @@ -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. diff --git a/config.h.in b/config.h.in index 1f1bd0753..9ac1a8558 100644 --- a/config.h.in +++ b/config.h.in @@ -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 + diff --git a/configure b/configure index d17074811..663e9bfa8 100644 --- a/configure +++ b/configure @@ -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 <&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 <&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 <&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 < 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 < 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 < 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 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* diff --git a/configure.in b/configure.in index df3903b0d..afea6d9d7 100644 --- a/configure.in +++ b/configure.in @@ -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" diff --git a/grub/asmstub.c b/grub/asmstub.c index 20ecc7852..62cd8bf8f 100644 --- a/grub/asmstub.c +++ b/grub/asmstub.c @@ -58,9 +58,14 @@ int grub_stage2 (void); # endif /* ! BLKFLSBUF */ #endif /* __linux__ */ -#ifdef __FreeBSD__ +#if defined(__FreeBSD__) || defined(__NetBSD__) +# include /* ioctl */ # include -#endif /* __FreeBSD__ */ +#endif /* __FreeBSD__ || __NetBSD__ */ + +#ifdef HAVE_OPENDISK +# include +#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)) diff --git a/stage2/builtins.c b/stage2/builtins.c index 11bf539e3..dde6e7002 100644 --- a/stage2/builtins.c +++ b/stage2/builtins.c @@ -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 =