From 92fca67cf55010923fb5d45a1aae7b3b726be5bd Mon Sep 17 00:00:00 2001 From: okuji Date: Tue, 18 Apr 2000 11:22:07 +0000 Subject: [PATCH] make the LBA support bitmap checks configurable at the installation time. --- ChangeLog | 55 ++++++++++++++ INSTALL | 8 -- NEWS | 6 ++ acconfig.h | 3 - config.h.in | 57 ++++++-------- configure | 174 +++++++++++++++++++------------------------ configure.in | 9 --- docs/grub-install.8 | 4 + stage1/stage1.S | 17 +++-- stage1/stage1.h | 23 +++--- stage2/asm.S | 2 + stage2/bios.c | 7 +- stage2/builtins.c | 117 +++++++++++++++++++---------- stage2/shared.h | 10 ++- util/grub-install.in | 7 +- 15 files changed, 283 insertions(+), 216 deletions(-) diff --git a/ChangeLog b/ChangeLog index fd587de80..97d6e30c3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,58 @@ +2000-04-17 OKUJI Yoshinori + + The user doesn't have to recompile GRUB for his/her buggy BIOS + any longer. It is configurable to ignore the LBA support bitmap + at the installation time. + + * stage1/stage1.S (force_lba): New variable. + (stage2_address): Moved forwards, to align some variables in + natural boundaries. + (real_start): Check if FORCE_LBA is non-zero, if so, jump to + skip_lba_bitmap_check, otherwise, check if bit 0 of the support + bitmap is non-zero. + Don't use #ifdef for CHECK_LBA_SUPPORT_BITMAP. + (skip_lba_bitmap_check): New label. + * stage1/stage1.h (COMPAT_VERSION_MINOR): Set to 1. + (STAGE1_FORCE_LBA): New macro. + (STAGE1_STAGE2_ADDRESS): Set to 0x42. + (STAGE1_STAGE2_SECTOR): Set to 0x44. + (STAGE1_STAGE2_SEGMENT): Set to 0x48. + * stage2/asm.S (force_lba): New variable. + * stage2/bios.c (get_diskinfo): Don't use #ifdef for + CHECK_LBA_SUPPORT_BITMAP. Instead, check if FORCE_LBA is + non-zero. If so, don't check the bit 0 of DRP.FLAG. + * stage2/builtins.c (install_func): Check if a new option + `--force-lba' is specified. If specified, set IS_FORCE_LBA to 1 + and set ARG to a value returned by skip_to. Otherwise, + IS_FORCE_LBA is zero. + Set the "force LBA" flag in STAGE1_BUFFER (the offset is + STAGE1_FORCE_LBA) to IS_FORCE_LBA. + Likewise, set the "force LBA" flag in STAGE2_SECOND_BUFFER + (the offset is STAGE2_FORCE_LBA) to IS_FORCE_LBA. + If IS_STAGE1_5 is true, then modify the Stage2, regardless of + the presence of the option REAL_CONFIG_FILE. Set the "force LBA" + flag in SCRATCHADDR (the offset is STAGE2_FORCE_LBA) to + IS_FORCE_LBA. + (builtin_install): Added description about `--force-lba' into + the docs. + (setup_func): Check if `--force-lba' is specified in ARG. If + specified, set IS_FORCE_LBA to 1 and set ARG to a value returned + by skip_to. Otherwise, IS_FORCE_LBA is zero. + If IS_FORCE_LBA is true, prepend "--force-lba " to CMD_ARG. + (builtin_setup): Added descriptions about `--force-lba' into the + docs. + * stage2/shared.h (STAGE2_FORCE_LBA): New macro. + (STAGE2_VER_STR_OFFS): Set to 0xe. + (force_lba): Declared. + * util/grub-install.in (force_lba): New variable. Set to an + empty sting by default. + (usage): Added a description about `--force-lba'. + (--force-lba): Checked in the option handling code. If + specified, set FORCE_LBA to "--force-lba". + Run the command "setup" with $force_lba added before + $install_drive. + * configure.in (--disable-lba-support-bitmap): Removed. + 2000-04-15 OKUJI Yoshinori * util/grub-install.in (root_device): Append `/' to ${rootdir}, diff --git a/INSTALL b/INSTALL index f2ad40eed..764eb262a 100644 --- a/INSTALL +++ b/INSTALL @@ -188,14 +188,6 @@ operates. confusing) to the casual installer. If you are a GRUB developer, it is a good idea to specify this option. -`--disable-lba-support-bitmap-check' - Disable the check for LBA support bitmap. Specify this option - if you are sure that your BIOS has the INT 13 extension support, - but GRUB doesn't access your drives in LBA mode. This is - necessary because an incorrect LBA support bitmap is returned in - several buggy BIOSes. You can check if GRUB recognizes the INT 13 - extension support by the command `geometry'. - `--disable-ext2fs' Omit the ext2fs support in Stage 2. diff --git a/NEWS b/NEWS index fa122233c..f48f0a126 100644 --- a/NEWS +++ b/NEWS @@ -10,6 +10,12 @@ New in 0.5.95 - XXXX-XX-XX: to load a NetBSD ELF kernel, because GRUB can automatically determine a kernel type in the other cases. * ReiserFS support is added. +* Added a new option `--force-lba' into the command "install". This + option disables some sanity checks for LBA mode (but not all). If you + are sure that your machine supports LBA mode but GRUB doesn't work in + LBA mode, you should specify it. It is necessary if your BIOS is too + buggy. In the previous version, it was a compile-time option, but you + don't have to recompile GRUB any longer. New in 0.5.94 - 2000-03-06: * Stage 1 supports both the LBA mode and the CHS mode. diff --git a/acconfig.h b/acconfig.h index da4d4c9b7..218aa62e5 100644 --- a/acconfig.h +++ b/acconfig.h @@ -24,6 +24,3 @@ /* Defined if _end is defined. */ #undef HAVE_USCORE_END_SYMBOL - -/* Defined if --disable-lba-support-bitmap is specified. */ -#undef CHECK_LBA_SUPPORT_BITMAP diff --git a/config.h.in b/config.h.in index 230b7fab2..7bd4b3e9b 100644 --- a/config.h.in +++ b/config.h.in @@ -24,8 +24,29 @@ /* Defined if _end is defined. */ #undef HAVE_USCORE_END_SYMBOL -/* Defined if --disable-lba-support-bitmap is specified. */ -#undef CHECK_LBA_SUPPORT_BITMAP +/* Define if you have the header file. */ +#undef HAVE_CURSES_H + +/* Define if you have the header file. */ +#undef HAVE_NCURSES_H + +/* Define if you have the header file. */ +#undef HAVE_NCURSES_CURSES_H + +/* Define if you have the header file. */ +#undef HAVE_STRING_H + +/* Define if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Name of package */ +#undef PACKAGE + +/* Version number of package */ +#undef VERSION + +/* Define if C symbols get an underscore after compilation */ +#undef HAVE_ASM_USCORE /* Define it to "addr32" or "addr32;" to make GAS happy */ #undef ADDR32 @@ -33,38 +54,6 @@ /* Define it to "data32" or "data32;" to make GAS happy */ #undef DATA32 -/* Define if C symbols get an underscore after compilation */ -#undef HAVE_ASM_USCORE - -/* Define if you have the header file. */ -#undef HAVE_CURSES_H - -/* Define if you have the `curses' library (-lcurses). */ -#undef HAVE_LIBCURSES - -/* Define if you have the `ncurses' library (-lncurses). */ -#undef HAVE_LIBNCURSES - -/* Define if you have the `util' library (-lutil). */ -#undef HAVE_LIBUTIL - -/* Define if you have the header file. */ -#undef HAVE_NCURSES_CURSES_H - -/* Define if you have the header file. */ -#undef HAVE_NCURSES_H - /* Define if opendisk() in -lutil can be used */ #undef HAVE_OPENDISK -/* Define if you have the header file. */ -#undef HAVE_STRINGS_H - -/* Define if you have the header file. */ -#undef HAVE_STRING_H - -/* Name of package */ -#undef PACKAGE - -/* Version number of package */ -#undef VERSION diff --git a/configure b/configure index bce781531..472687476 100644 --- a/configure +++ b/configure @@ -21,9 +21,6 @@ ac_help="$ac_help --with-binutils=DIR search the directory DIR to find binutils" ac_help="$ac_help --without-curses do not use curses" -ac_help="$ac_help - --disable-lba-support-bitmap-check - disable a check for LBA support bitmap" ac_help="$ac_help --disable-ext2fs disable ext2fs support in Stage 2" ac_help="$ac_help @@ -647,7 +644,7 @@ ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # ./install, which can be erroneously created by make from ./install.sh. echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 -echo "configure:651: checking for a BSD compatible install" >&5 +echo "configure:648: checking for a BSD compatible install" >&5 if test -z "$INSTALL"; then if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -700,7 +697,7 @@ test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6 -echo "configure:704: checking whether build environment is sane" >&5 +echo "configure:701: checking whether build environment is sane" >&5 # Just in case sleep 1 echo timestamp > conftestfile @@ -772,7 +769,7 @@ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:776: checking for $ac_word" >&5 +echo "configure:773: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_AWK'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -802,7 +799,7 @@ test -n "$AWK" && break done echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 -echo "configure:806: checking whether ${MAKE-make} sets \${MAKE}" >&5 +echo "configure:803: checking whether ${MAKE-make} sets \${MAKE}" >&5 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -937,7 +934,7 @@ else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } fi echo $ac_n "checking host system type""... $ac_c" 1>&6 -echo "configure:941: checking host system type" >&5 +echo "configure:938: checking host system type" >&5 host_alias=$host case "$host_alias" in @@ -971,7 +968,7 @@ esac # echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6 -echo "configure:975: checking whether to enable maintainer-specific portions of Makefiles" >&5 +echo "configure:972: checking whether to enable maintainer-specific portions of Makefiles" >&5 # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given. if test "${enable_maintainer_mode+set}" = set; then enableval="$enable_maintainer_mode" @@ -997,7 +994,7 @@ if test "x$enable_maintainer_mode" = xyes; then # Extract the first word of "perl", so it can be a program name with args. set dummy perl; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1001: checking for $ac_word" >&5 +echo "configure:998: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_PERL'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1044,7 +1041,7 @@ fi # echo $ac_n "checking build system type""... $ac_c" 1>&6 -echo "configure:1048: checking build system type" >&5 +echo "configure:1045: checking build system type" >&5 build_alias=$build case "$build_alias" in @@ -1070,7 +1067,7 @@ fi # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1074: checking for $ac_word" >&5 +echo "configure:1071: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1102,7 +1099,7 @@ fi # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1106: checking for $ac_word" >&5 +echo "configure:1103: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1132,7 +1129,7 @@ if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1136: checking for $ac_word" >&5 +echo "configure:1133: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1183,7 +1180,7 @@ fi # Extract the first word of "cl", so it can be a program name with args. set dummy cl; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1187: checking for $ac_word" >&5 +echo "configure:1184: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1215,7 +1212,7 @@ fi fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 -echo "configure:1219: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 +echo "configure:1216: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. @@ -1226,12 +1223,12 @@ cross_compiling=$ac_cv_prog_cc_cross cat > conftest.$ac_ext << EOF -#line 1230 "configure" +#line 1227 "configure" #include "confdefs.h" main(){return(0);} EOF -if { (eval echo configure:1235: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:1232: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ac_cv_prog_cc_works=yes # If we can't run a trivial program, we are probably using a cross compiler. if (./conftest; exit) 2>/dev/null; then @@ -1257,12 +1254,12 @@ if test $ac_cv_prog_cc_works = no; then { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 -echo "configure:1261: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "configure:1258: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 cross_compiling=$ac_cv_prog_cc_cross echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 -echo "configure:1266: checking whether we are using GNU C" >&5 +echo "configure:1263: checking whether we are using GNU C" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1271,7 +1268,7 @@ else yes; #endif EOF -if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1275: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then +if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1272: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gcc=yes else ac_cv_prog_gcc=no @@ -1290,7 +1287,7 @@ ac_test_CFLAGS="${CFLAGS+set}" ac_save_CFLAGS="$CFLAGS" CFLAGS= echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 -echo "configure:1294: checking whether ${CC-cc} accepts -g" >&5 +echo "configure:1291: checking whether ${CC-cc} accepts -g" >&5 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1323,7 +1320,7 @@ fi echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 -echo "configure:1327: checking how to run the C preprocessor" >&5 +echo "configure:1324: checking how to run the C preprocessor" >&5 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= @@ -1338,13 +1335,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:1348: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1345: \"$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 : @@ -1355,13 +1352,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:1365: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1362: \"$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 : @@ -1372,13 +1369,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:1382: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1379: \"$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 : @@ -1411,7 +1408,7 @@ echo "$ac_t""$CPP" 1>&6 depcc="$CC" depcpp="$CPP" echo $ac_n "checking dependency style of $depcc""... $ac_c" 1>&6 -echo "configure:1415: checking dependency style of $depcc" >&5 +echo "configure:1412: checking dependency style of $depcc" >&5 if eval "test \"`echo '$''{'am_cv_CC_dependencies_compiler_type'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1467,7 +1464,7 @@ if test "x$with_binutils" != x; then # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1471: checking for $ac_word" >&5 +echo "configure:1468: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_RANLIB'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1504,7 +1501,7 @@ else # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1508: checking for $ac_word" >&5 +echo "configure:1505: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1544,7 +1541,7 @@ if test "x$ac_cv_prog_gcc" = xyes; then STAGE1_CFLAGS="-O2" GRUB_CFLAGS="-O2" echo $ac_n "checking whether optimization for size works""... $ac_c" 1>&6 -echo "configure:1548: checking whether optimization for size works" >&5 +echo "configure:1545: checking whether optimization for size works" >&5 if eval "test \"`echo '$''{'size_flag'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1552,14 +1549,14 @@ else saved_CFLAGS=$CFLAGS CFLAGS="-Os -g" cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:1560: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* size_flag=yes else @@ -1593,7 +1590,7 @@ if test "x$with_binutils" != x; then # Extract the first word of "objcopy", so it can be a program name with args. set dummy objcopy; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1597: checking for $ac_word" >&5 +echo "configure:1594: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_OBJCOPY'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1629,7 +1626,7 @@ else # Extract the first word of "${ac_tool_prefix}objcopy", so it can be a program name with args. set dummy ${ac_tool_prefix}objcopy; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1633: checking for $ac_word" >&5 +echo "configure:1630: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_OBJCOPY'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1663,7 +1660,7 @@ fi # Defined in acinclude.m4. echo $ac_n "checking if C symbols get an underscore after compilation""... $ac_c" 1>&6 -echo "configure:1667: checking if C symbols get an underscore after compilation" >&5 +echo "configure:1664: checking if C symbols get an underscore after compilation" >&5 if eval "test \"`echo '$''{'grub_cv_asm_uscore'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1676,7 +1673,7 @@ func (int *list) } EOF -if { ac_try='${CC-cc} ${CFLAGS} -S conftest.c'; { (eval echo configure:1680: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } && test -s conftest.s; then +if { ac_try='${CC-cc} ${CFLAGS} -S conftest.c'; { (eval echo configure:1677: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } && test -s conftest.s; then true else { echo "configure: error: ${CC-cc} failed to produce assembly code" 1>&2; exit 1; } @@ -1702,7 +1699,7 @@ fi echo "$ac_t""$grub_cv_asm_uscore" 1>&6 echo $ac_n "checking whether ${OBJCOPY} works for absolute addresses""... $ac_c" 1>&6 -echo "configure:1706: checking whether ${OBJCOPY} works for absolute addresses" >&5 +echo "configure:1703: checking whether ${OBJCOPY} works for absolute addresses" >&5 if eval "test \"`echo '$''{'grub_cv_prog_objcopy_absolute'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1714,21 +1711,21 @@ cmain (void) } EOF -if { (eval echo configure:1718: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; } && test -s conftest.o; then : +if { (eval echo configure:1715: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; } && test -s conftest.o; then : else { echo "configure: error: ${CC-cc} cannot compile C source code" 1>&2; exit 1; } fi grub_cv_prog_objcopy_absolute=yes for link_addr in 2000 8000 7C00; do - if { ac_try='${CC-cc} ${CFLAGS} -nostdlib -Wl,-N -Wl,-Ttext -Wl,$link_addr conftest.o -o conftest.exec'; { (eval echo configure:1724: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then : + if { ac_try='${CC-cc} ${CFLAGS} -nostdlib -Wl,-N -Wl,-Ttext -Wl,$link_addr conftest.o -o conftest.exec'; { (eval echo configure:1721: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then : else { echo "configure: error: ${CC-cc} cannot link at address $link_addr" 1>&2; exit 1; } fi - if { ac_try='${OBJCOPY-objcopy} -O binary conftest.exec conftest'; { (eval echo configure:1728: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then : + if { ac_try='${OBJCOPY-objcopy} -O binary conftest.exec conftest'; { (eval echo configure:1725: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then : else { echo "configure: error: ${OBJCOPY-objcopy} cannot create binary files" 1>&2; exit 1; } fi - if test ! -f conftest.old || { ac_try='cmp -s conftest.old conftest'; { (eval echo configure:1732: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then + if test ! -f conftest.old || { ac_try='cmp -s conftest.old conftest'; { (eval echo configure:1729: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then mv -f conftest conftest.old else grub_cv_prog_objcopy_absolute=no @@ -1745,7 +1742,7 @@ fi echo $ac_n "checking whether addr32 must be in the same line as the instruction""... $ac_c" 1>&6 -echo "configure:1749: checking whether addr32 must be in the same line as the instruction" >&5 +echo "configure:1746: checking whether addr32 must be in the same line as the instruction" >&5 if eval "test \"`echo '$''{'grub_cv_asm_prefix_requirement'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1754,7 +1751,7 @@ else l1: addr32 movb %al, l1 EOF -if { ac_try='${CC-cc} ${CFLAGS} -c conftest.s'; { (eval echo configure:1758: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } && test -s conftest.o; then +if { ac_try='${CC-cc} ${CFLAGS} -c conftest.s'; { (eval echo configure:1755: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } && test -s conftest.o; then grub_cv_asm_prefix_requirement=yes else grub_cv_asm_prefix_requirement=no @@ -1786,7 +1783,7 @@ echo "$ac_t""$grub_cv_asm_prefix_requirement" 1>&6 echo $ac_n "checking for .code16 addr32 assembler support""... $ac_c" 1>&6 -echo "configure:1790: checking for .code16 addr32 assembler support" >&5 +echo "configure:1787: checking for .code16 addr32 assembler support" >&5 if eval "test \"`echo '$''{'grub_cv_asm_addr32'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1801,7 +1798,7 @@ else sed -e s/@ADDR32@/addr32\;/ < conftest.s.in > conftest.s fi -if { ac_try='${CC-cc} ${CFLAGS} -c conftest.s'; { (eval echo configure:1805: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } && test -s conftest.o; then +if { ac_try='${CC-cc} ${CFLAGS} -c conftest.s'; { (eval echo configure:1802: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } && test -s conftest.o; then grub_cv_asm_addr32=yes else grub_cv_asm_addr32=no @@ -1818,19 +1815,19 @@ fi echo $ac_n "checking if start is defined by the compiler""... $ac_c" 1>&6 -echo "configure:1822: checking if start is defined by the compiler" >&5 +echo "configure:1819: checking if start is defined by the compiler" >&5 if eval "test \"`echo '$''{'grub_cv_check_start_symbol'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:1831: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* grub_cv_check_start_symbol=yes else @@ -1854,19 +1851,19 @@ echo "$ac_t""$grub_cv_check_start_symbol" 1>&6 echo $ac_n "checking if _start is defined by the compiler""... $ac_c" 1>&6 -echo "configure:1858: checking if _start is defined by the compiler" >&5 +echo "configure:1855: checking if _start is defined by the compiler" >&5 if eval "test \"`echo '$''{'grub_cv_check_uscore_start_symbol'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:1867: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* grub_cv_check_uscore_start_symbol=yes else @@ -1895,19 +1892,19 @@ fi echo $ac_n "checking if __bss_start is defined by the compiler""... $ac_c" 1>&6 -echo "configure:1899: checking if __bss_start is defined by the compiler" >&5 +echo "configure:1896: checking if __bss_start is defined by the compiler" >&5 if eval "test \"`echo '$''{'grub_cv_check_uscore_uscore_bss_start_symbol'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:1908: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* grub_cv_check_uscore_uscore_bss_start_symbol=yes else @@ -1931,19 +1928,19 @@ echo "$ac_t""$grub_cv_check_uscore_uscore_bss_start_symbol" 1>&6 echo $ac_n "checking if _edata is defined by the compiler""... $ac_c" 1>&6 -echo "configure:1935: checking if _edata is defined by the compiler" >&5 +echo "configure:1932: checking if _edata is defined by the compiler" >&5 if eval "test \"`echo '$''{'grub_cv_check_uscore_edata_symbol'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:1944: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* grub_cv_check_uscore_edata_symbol=yes else @@ -1967,19 +1964,19 @@ echo "$ac_t""$grub_cv_check_uscore_edata_symbol" 1>&6 echo $ac_n "checking if edata is defined by the compiler""... $ac_c" 1>&6 -echo "configure:1971: checking if edata is defined by the compiler" >&5 +echo "configure:1968: checking if edata is defined by the compiler" >&5 if eval "test \"`echo '$''{'grub_cv_check_edata_symbol'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:1980: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* grub_cv_check_edata_symbol=yes else @@ -2009,19 +2006,19 @@ fi echo $ac_n "checking if end is defined by the compiler""... $ac_c" 1>&6 -echo "configure:2013: checking if end is defined by the compiler" >&5 +echo "configure:2010: checking if end is defined by the compiler" >&5 if eval "test \"`echo '$''{'grub_cv_check_end_symbol'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2022: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* grub_cv_check_end_symbol=yes else @@ -2045,19 +2042,19 @@ echo "$ac_t""$grub_cv_check_end_symbol" 1>&6 echo $ac_n "checking if _end is defined by the compiler""... $ac_c" 1>&6 -echo "configure:2049: checking if _end is defined by the compiler" >&5 +echo "configure:2046: checking if _end is defined by the compiler" >&5 if eval "test \"`echo '$''{'grub_cv_check_uscore_end_symbol'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2058: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* grub_cv_check_uscore_end_symbol=yes else @@ -2095,7 +2092,7 @@ 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:2099: checking for opendisk in -lutil" >&5 +echo "configure:2096: checking for opendisk in -lutil" >&5 ac_lib_var=`echo util'_'opendisk | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -2103,7 +2100,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lutil $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2115: \"$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 @@ -2142,7 +2139,7 @@ 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:2146: checking for wgetch in -lncurses" >&5 +echo "configure:2143: checking for wgetch in -lncurses" >&5 ac_lib_var=`echo ncurses'_'wgetch | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -2150,7 +2147,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:2162: \"$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 @@ -2184,7 +2181,7 @@ EOF else echo "$ac_t""no" 1>&6 echo $ac_n "checking for wgetch in -lcurses""... $ac_c" 1>&6 -echo "configure:2188: checking for wgetch in -lcurses" >&5 +echo "configure:2185: checking for wgetch in -lcurses" >&5 ac_lib_var=`echo curses'_'wgetch | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -2192,7 +2189,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:2204: \"$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 @@ -2238,17 +2235,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:2242: checking for $ac_hdr" >&5 +echo "configure:2239: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'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:2252: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2249: \"$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* @@ -2277,21 +2274,6 @@ done # Check for user options. -# some compile-time options. -# Check whether --enable-lba-support-bitmap-check or --disable-lba-support-bitmap-check was given. -if test "${enable_lba_support_bitmap_check+set}" = set; then - enableval="$enable_lba_support_bitmap_check" - : -fi - - -if test "x$enable_lba_support_bitmap_check" != xno; then - cat >> confdefs.h <<\EOF -#define CHECK_LBA_SUPPORT_BITMAP 1 -EOF - -fi - # filesystems support. # Check whether --enable-ext2fs or --disable-ext2fs was given. if test "${enable_ext2fs+set}" = set; then diff --git a/configure.in b/configure.in index 24c5b4d0e..9da1373e9 100644 --- a/configure.in +++ b/configure.in @@ -163,15 +163,6 @@ AC_CHECK_HEADERS(string.h strings.h ncurses/curses.h ncurses.h curses.h) # Check for user options. -# some compile-time options. -AC_ARG_ENABLE(lba-support-bitmap-check, - [ --disable-lba-support-bitmap-check - disable a check for LBA support bitmap]) - -if test "x$enable_lba_support_bitmap_check" != xno; then - AC_DEFINE(CHECK_LBA_SUPPORT_BITMAP) -fi - # filesystems support. AC_ARG_ENABLE(ext2fs, [ --disable-ext2fs disable ext2fs support in Stage 2]) diff --git a/docs/grub-install.8 b/docs/grub-install.8 index 90180875e..598392c4f 100644 --- a/docs/grub-install.8 +++ b/docs/grub-install.8 @@ -20,6 +20,10 @@ instead of the root directory. .TP \fB\-\-grub\-shell\fR=\fIFILE\fR use FILE as the grub shell. +.TP +\fB\-\-force\-lba\fR +Force GRUB to use LBA mode even for a buggy +BIOS. .PP INSTALL_DEVICE can be a GRUB device name or a system device filename. .PP diff --git a/stage1/stage1.S b/stage1/stage1.S index 53cfb94b6..1595f3196 100644 --- a/stage1/stage1.S +++ b/stage1/stage1.S @@ -91,10 +91,12 @@ stage1_version: boot_drive: .byte 0xff /* the disk to load stage2 from */ /* 0xff means use the boot drive */ -stage2_sector: - .long 1 +force_lba: + .byte 0 stage2_address: .word 0x8000 +stage2_sector: + .long 1 stage2_segment: .word 0x800 @@ -149,12 +151,15 @@ real_start: cmpw $0xaa55, %bx jne chs_mode -#ifdef CHECK_LBA_SUPPORT_BITMAP - /* check if AH=0x42 is supported */ + /* check if AH=0x42 is supported if FORCE_LBA is zero */ + movb ABS(force_lba), %al + testb %al, %al + jnz skip_lba_bitmap_check andw $1, %cx jz chs_mode -#endif /* CHECK_LBA_SUPPORT_BITMAP */ - + +skip_lba_bitmap_check: + /* get the geometry (limited to 2TB!) */ movb $0x48, %ah movw $STAGE1_DRP_ADDR, %si diff --git a/stage1/stage1.h b/stage1/stage1.h index d38419de8..c99c0ab3b 100644 --- a/stage1/stage1.h +++ b/stage1/stage1.h @@ -23,7 +23,7 @@ /* Define the version numbers here, so that Stage 1 can know them. */ #define COMPAT_VERSION_MAJOR 3 -#define COMPAT_VERSION_MINOR 0 +#define COMPAT_VERSION_MINOR 1 #define COMPAT_VERSION ((COMPAT_VERSION_MINOR << 8) \ | COMPAT_VERSION_MAJOR) @@ -33,21 +33,24 @@ /* The offset of the end of BPB (BIOS Parameter Block). */ #define STAGE1_BPBEND 0x3e -/* The offset of STAGE2_SECTOR. */ -#define STAGE1_STAGE2_SECTOR 0x41 - -/* The offset of STAGE2_ADDRESS. */ -#define STAGE1_STAGE2_ADDRESS 0x45 - -/* The offset of STAGE2_SEGMENT. */ -#define STAGE1_STAGE2_SEGMENT 0x47 - /* The offset of the major version. */ #define STAGE1_VER_MAJ_OFFS 0x3e /* The offset of BOOT_DRIVE. */ #define STAGE1_BOOT_DRIVE 0x40 +/* The offset of FORCE_LBA. */ +#define STAGE1_FORCE_LBA 0x41 + +/* The offset of STAGE2_ADDRESS. */ +#define STAGE1_STAGE2_ADDRESS 0x42 + +/* The offset of STAGE2_SECTOR. */ +#define STAGE1_STAGE2_SECTOR 0x44 + +/* The offset of STAGE2_SEGMENT. */ +#define STAGE1_STAGE2_SEGMENT 0x48 + /* The offset of the start of the partition table. */ #define STAGE1_PARTSTART 0x1be diff --git a/stage2/asm.S b/stage2/asm.S index 407f2c59b..aacd58214 100644 --- a/stage2/asm.S +++ b/stage2/asm.S @@ -73,6 +73,8 @@ VARIABLE(install_partition) .long 0x020000 VARIABLE(stage2_id) .byte STAGE2_ID +VARIABLE(force_lba) + .byte 0 VARIABLE(version_string) .string VERSION VARIABLE(config_file) diff --git a/stage2/bios.c b/stage2/bios.c index e588da85d..dca467a82 100644 --- a/stage2/bios.c +++ b/stage2/bios.c @@ -163,20 +163,17 @@ get_diskinfo (int drive, struct geometry *geometry) read/write is supported, so we cannot help assuming that the functions are supported by default and clearing the flag when either of them fails. *sigh* */ -#ifdef CHECK_LBA_SUPPORT_BITMAP + /* Make sure that LBA read/write functions are supported. */ - if (drp.flags & 1) + if (force_lba || (drp.flags & 1)) { -#endif geometry->flags = BIOSDISK_FLAG_LBA_EXTENSION; /* FIXME: when the 2TB limit becomes critical, we must change the type of TOTAL_SECTORS to unsigned long long. */ total_sectors = drp.total_sectors & ~0L; -#ifdef CHECK_LBA_SUPPORT_BITMAP } -#endif } } diff --git a/stage2/builtins.c b/stage2/builtins.c index e79bdc3fb..64dc482ca 100644 --- a/stage2/builtins.c +++ b/stage2/builtins.c @@ -1387,7 +1387,9 @@ install_func (char *arg, int flags) int is_stage1_5 = 0; /* Must call grub_close? */ int is_open = 0; - + /* If LBA is forced? */ + int is_force_lba = 0; + /* Save the first sector of Stage2 in STAGE2_SECT. */ static void disk_read_savesect_func (int sector) { @@ -1423,6 +1425,13 @@ install_func (char *arg, int flags) installaddr += 512; } + /* First, check the GNU-style long option. */ + if (grub_memcmp ("--force-lba", arg, 11) == 0) + { + is_force_lba = 1; + arg = skip_to (0, arg); + } + stage1_file = arg; dest_dev = skip_to (0, stage1_file); if (*dest_dev == 'd') @@ -1486,6 +1495,8 @@ install_func (char *arg, int flags) goto fail; } + /* This below is not true any longer. But should we leave this alone? */ + /* If DEST_DRIVE is a floppy, Stage 2 must have the iteration probe routine. */ if (! (dest_drive & 0x80) @@ -1514,8 +1525,12 @@ install_func (char *arg, int flags) " be installed on a\ndifferent drive than the drive where" " the Stage 2 resides.\n"); + /* Set the boot drive. */ *((unsigned char *) (stage1_buffer + STAGE1_BOOT_DRIVE)) = new_drive; + /* Set the "force LBA" flag. */ + *((unsigned char *) (stage1_buffer + STAGE1_FORCE_LBA)) = is_force_lba; + /* Read the first sector of Stage 2. */ disk_read_hook = disk_read_savesect_func; if (grub_read (stage2_first_buffer, SECTOR_SIZE) != SECTOR_SIZE) @@ -1594,6 +1609,10 @@ install_func (char *arg, int flags) while (*(config_file_location++)) ; + /* Set the "force LBA" flag for Stage2. */ + *((unsigned char *) (stage2_second_buffer + STAGE2_FORCE_LBA)) + = is_force_lba; + if (*ptr == 'p') { *((long *) (stage2_second_buffer + STAGE2_INSTALLPART)) @@ -1649,40 +1668,44 @@ install_func (char *arg, int flags) grub_strcpy (config_file_location + sizeof (device), config_file); } - /* Check if the configuration filename is specified, if a Stage 1.5 - is used. */ + /* If a Stage 1.5 is used, then we need to modify the Stage2. */ if (is_stage1_5) { char *real_config_filename = skip_to (0, ptr); + is_open = grub_open (config_filename); + if (! is_open) + goto fail; + + /* Skip the first sector. */ + grub_seek (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; + } + + /* Set the "force LBA" flag for Stage2. */ + *((unsigned char *) (SCRATCHADDR + STAGE2_FORCE_LBA)) + = is_force_lba; + + /* If REAL_CONFIG_FILENAME is specified, copy it to the Stage2. */ if (*real_config_filename) { /* Specified */ char *location; - is_open = grub_open (config_filename); - if (! is_open) - goto fail; - - /* Skip the first sector. */ - grub_seek (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++)) @@ -1690,15 +1713,16 @@ install_func (char *arg, int flags) /* 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; - } + + } + + /* 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; } } } @@ -1751,7 +1775,7 @@ static struct builtin builtin_install = "install", install_func, BUILTIN_CMDLINE, - "install STAGE1 [d] DEVICE STAGE2 [ADDR] [p] [CONFIG_FILE] [REAL_CONFIG_FILE]", + "install [--force-lba] 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" @@ -1763,6 +1787,8 @@ static struct builtin builtin_install = " 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." + " If the option `--force-lba' is specified, disable some sanity checks" + " for LBA mode." }; @@ -2544,6 +2570,7 @@ setup_func (char *arg, int flags) char cmd_arg[256]; char device[16]; char *buffer = (char *) RAW_ADDR (0x100000); + int is_force_lba = 0; static void sprint_device (int drive, int partition) { @@ -2585,6 +2612,13 @@ setup_func (char *arg, int flags) tmp_drive = saved_drive; tmp_partition = saved_partition; + + /* Check if the user specifies --force-lba. */ + if (grub_memcmp ("--force-lba", arg, 11) == 0) + { + is_force_lba = 1; + arg = skip_to (0, arg); + } install_ptr = arg; image_ptr = skip_to (0, install_ptr); @@ -2697,7 +2731,8 @@ setup_func (char *arg, int flags) #ifdef NO_BUGGY_BIOS_IN_THE_WORLD /* I prefer this, but... */ - grub_sprintf (cmd_arg, "%s %s%s %s p %s", + grub_sprintf (cmd_arg, "%s%s %s%s %s p %s", + is_force_lba? "--force-lba " : "", stage1, (install_drive != image_drive) ? "d " : "", device, @@ -2708,7 +2743,8 @@ setup_func (char *arg, int flags) may not expect that your BIOS will pass a booting drive to stage1 correctly. Thus, always specify the option `d', whether INSTALL_DRIVE is identical with IMAGE_DRIVE or not. *sigh* */ - grub_sprintf (cmd_arg, "%s d %s %s p %s", + grub_sprintf (cmd_arg, "%s%s d %s %s p %s", + is_force_lba? "--force-lba " : "", stage1, device, stage2, @@ -2738,13 +2774,14 @@ static struct builtin builtin_setup = "setup", setup_func, BUILTIN_CMDLINE, - "setup INSTALL_DEVICE [IMAGE_DEVICE]", + "setup [--force-lba] INSTALL_DEVICE [IMAGE_DEVICE]", "Set up the installation of GRUB automatically. This command uses" " the more flexible command \"install\" in the backend and installs" " GRUB into the device INSTALL_DEVICE. If IMAGE_DEVICE is specified," " then find the GRUB images in the device IMAGE_DEVICE, otherwise" " use the current \"root device\", which can be set by the command" - " \"root\"." + " \"root\". If you know that your BIOS should support LBA but GRUB" + " doesn't work in LBA mode, specify the option `--force-lba'." }; diff --git a/stage2/shared.h b/stage2/shared.h index 16cc33fa6..c07c7f3b3 100644 --- a/stage2/shared.h +++ b/stage2/shared.h @@ -192,10 +192,11 @@ extern char *grub_scratch_mem; #include -#define STAGE2_VER_MAJ_OFFS 0x6 -#define STAGE2_INSTALLPART 0x8 -#define STAGE2_STAGE2_ID 0xc -#define STAGE2_VER_STR_OFFS 0xd +#define STAGE2_VER_MAJ_OFFS 0x6 +#define STAGE2_INSTALLPART 0x8 +#define STAGE2_STAGE2_ID 0xc +#define STAGE2_FORCE_LBA 0xd +#define STAGE2_VER_STR_OFFS 0xe /* Stage 2 identifiers */ #define STAGE2_ID_STAGE2 0 @@ -423,6 +424,7 @@ extern unsigned long install_partition; extern unsigned long boot_drive; extern unsigned long boot_part_addr; extern unsigned long boot_part_offset; +extern unsigned char force_lba; extern char version_string[]; extern char config_file[]; diff --git a/util/grub-install.in b/util/grub-install.in index 6e9e0dcfd..c353514ee 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -34,6 +34,7 @@ log_file=/tmp/grub-install.log.$$ rootdir= install_device= +force_lba= debug=no # Usage: usage @@ -48,6 +49,8 @@ Install GRUB on your drive. --root-directory=DIR install GRUB images under the directory DIR instead of the root directory. --grub-shell=FILE use FILE as the grub shell. + --force-lba Force GRUB to use LBA mode even for a buggy + BIOS. INSTALL_DEVICE can be a GRUB device name or a system device filename. @@ -125,6 +128,8 @@ for option; do rootdir=`echo "$option" | sed 's/--root-directory=//'` ;; --grub-shell=*) grub_shell=`echo "$option" | sed 's/--grub-shell=//'` ;; + --force-lba) + force_lba="--force-lba" ;; # This is an undocumented feature... --debug) debug=yes ;; @@ -239,7 +244,7 @@ test -x /bin/tempfile && log_file=`tempfile --prefix=grub` # Now perform the installation. $grub_shell --batch --device-map=$device_map <$log_file root $root_drive -setup $install_drive +setup $force_lba $install_drive quit EOF