diff --git a/ChangeLog b/ChangeLog index 7f6b386c1..7e12dc2eb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2005-02-15 Yoshinori K. Okuji + + * stage2/builtins.c (install_func): If DEST_DRIVE is a hard + disk, enable the workaround in Stage 1 by replacing the jmp + with double nop's. + + * stage1/stage1.h (STAGE1_BOOT_DRIVE_CHECK): New macro. + (STAGE1_BOOT_DRIVE_MASK): Removed. + + * stage1/stage1.S (boot_drive_check): New label. This implements + a different workaround for buggy BIOSes which don't pass boot + drive correctly. This is effective for BIOSes which pass a value + without the seventh bit (0x80). + (boot_drive_mask): Removed. + 2005-02-03 Yoshinori K. Okuji * grub/asmstub.c (console_current_color): Make it global as diff --git a/NEWS b/NEWS index fd75e7dc0..a722101f9 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,11 @@ NEWS - list of user-visible changes between releases of GRUB +New: +* Fix the prototypes and the definitions of nested functions. This was + required for gcc-4. +* Implement a more robust workaround for buggy BIOSes which don't pass + boot drive correctly (notably for HP Vectra). + New in 0.96 - 2005-01-30: * The command "fallback" supports mutiple fallback entries. * The command "savedefault" supports an optional argument which diff --git a/stage1/stage1.S b/stage1/stage1.S index 50c63e4ae..985963dd1 100644 --- a/stage1/stage1.S +++ b/stage1/stage1.S @@ -108,12 +108,18 @@ after_BPB: /* * This is a workaround for buggy BIOSes which don't pass boot - * drive correctly. If GRUB is installed into a HDD, do - * "orb $0x80, %dl", otherwise "orb $0x00, %dl" (i.e. nop). + * drive correctly. If GRUB is installed into a HDD, check if + * DL is masked correctly. If not, assume that the BIOS passed + * a bogus value and set DL to 0x80, since this is the only + * possible boot drive. If GRUB is installed into a floppy, + * this does nothing (only jump). */ - .byte 0x80, 0xca -boot_drive_mask: - .byte 0x00 +boot_drive_check: + jmp 1f + testb $0x80, %dl + jnz 1f + movb $0x80, %dl +1: /* * ljmp to the next instruction because some bogus BIOSes diff --git a/stage1/stage1.h b/stage1/stage1.h index 4205a5fd8..d232ade11 100644 --- a/stage1/stage1.h +++ b/stage1/stage1.h @@ -51,8 +51,8 @@ /* The offset of STAGE2_SEGMENT. */ #define STAGE1_STAGE2_SEGMENT 0x48 -/* The offset of BOOT_DRIVE_MASK. */ -#define STAGE1_BOOT_DRIVE_MASK 0x4d +/* The offset of BOOT_DRIVE_CHECK. */ +#define STAGE1_BOOT_DRIVE_CHECK 0x4b /* The offset of a magic number used by Windows NT. */ #define STAGE1_WINDOWS_NT_MAGIC 0x1b8 diff --git a/stage2/builtins.c b/stage2/builtins.c index df98a1e7a..3e08a8632 100644 --- a/stage2/builtins.c +++ b/stage2/builtins.c @@ -1952,11 +1952,13 @@ install_func (char *arg, int flags) /* Set the "force LBA" flag. */ *((unsigned char *) (stage1_buffer + STAGE1_FORCE_LBA)) = is_force_lba; - /* Set the boot drive mask. This is a workaround for buggy BIOSes which - don't pass boot drive correctly. Instead, they pass 0x00 even when - booted from 0x80. */ - *((unsigned char *) (stage1_buffer + STAGE1_BOOT_DRIVE_MASK)) - = (dest_drive & BIOS_FLAG_FIXED_DISK); + /* If DEST_DRIVE is a hard disk, enable the workaround, which is + for buggy BIOSes which don't pass boot drive correctly. Instead, + they pass 0x00 or 0x01 even when booted from 0x80. */ + if (dest_drive & BIOS_FLAG_FIXED_DISK) + /* Replace the jmp (2 bytes) with double nop's. */ + *((unsigned short *) (stage1_buffer + STAGE1_BOOT_DRIVE_CHECK)) + = 0x9090; /* Read the first sector of Stage 2. */ disk_read_hook = disk_read_savesect_func;