From: okuji Date: Sun, 17 Jul 2005 14:57:07 +0000 (+0000) Subject: 2005-07-17 Yoshinori Okuji X-Git-Tag: 1.98~2116 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f806d18efd1e124a389157a68aa20f004c8731d6;p=thirdparty%2Fgrub.git 2005-07-17 Yoshinori Okuji * boot/i386/pc/boot.S (boot_drive_check): New label. * include/grub/i386/pc/boot.h (GRUB_BOOT_MACHINE_DRIVE_CHECK): New macro. * util/i386/pc/grub-setup.c (setup): Added a workaround for BIOSes which do not pass a boot drive correctly. Copied from GRUB Legacy. --- diff --git a/ChangeLog b/ChangeLog index 63a4c8599..e1aa12fdc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2005-07-17 Yoshinori Okuji + + * boot/i386/pc/boot.S (boot_drive_check): New label. + + * include/grub/i386/pc/boot.h (GRUB_BOOT_MACHINE_DRIVE_CHECK): New + macro. + + * util/i386/pc/grub-setup.c (setup): Added a workaround for BIOSes + which do not pass a boot drive correctly. Copied from GRUB Legacy. + 2005-07-17 Yoshinori Okuji * kern/i386/pc/startup.S (gate_a20_try_system_control_port_a): diff --git a/boot/i386/pc/boot.S b/boot/i386/pc/boot.S index 2e2aaf514..0d7f4279d 100644 --- a/boot/i386/pc/boot.S +++ b/boot/i386/pc/boot.S @@ -1,7 +1,7 @@ /* -*-Asm-*- */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002 Free Software Foundation, Inc. + * Copyright (C) 1999,2000,2001,2002,2005 Free Software Foundation, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -108,6 +108,21 @@ after_BPB: /* general setup */ cli /* we're not safe here! */ + /* + * This is a workaround for buggy BIOSes which don't pass boot + * 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). + */ +boot_drive_check: + jmp 1f + testb $0x80, %dl + jnz 1f + movb $0x80, %dl +1: + /* * ljmp to the next instruction because some bogus BIOSes * jump to 07C0:0000 instead of 0000:7C00. diff --git a/include/grub/i386/pc/boot.h b/include/grub/i386/pc/boot.h index a9e9e9800..967b499f1 100644 --- a/include/grub/i386/pc/boot.h +++ b/include/grub/i386/pc/boot.h @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2002 Free Software Foundation, Inc. + * Copyright (C) 1999,2000,2002,2005 Free Software Foundation, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -47,6 +47,9 @@ /* The offset of KERNEL_SEGMENT. */ #define GRUB_BOOT_MACHINE_KERNEL_SEGMENT 0x48 +/* The offset of BOOT_DRIVE_CHECK. */ +#define GRUB_BOOT_MACHINE_DRIVE_CHECK 0x4b + /* The offset of a magic number used by Windows NT. */ #define GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC 0x1b8 diff --git a/util/i386/pc/grub-setup.c b/util/i386/pc/grub-setup.c index 91e0d52b4..01d25a7fa 100644 --- a/util/i386/pc/grub-setup.c +++ b/util/i386/pc/grub-setup.c @@ -1,7 +1,7 @@ /* grub-setup.c - make GRUB usable */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. + * Copyright (C) 1999,2000,2001,2002,2003,2004,2005 Free Software Foundation, Inc. * * GRUB is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -86,6 +86,7 @@ setup (const char *prefix, const char *dir, grub_device_t root_dev, dest_dev; grub_uint8_t *boot_drive; grub_uint32_t *kernel_sector; + grub_uint16_t *boot_drive_check; struct boot_blocklist *first_block, *block; grub_int32_t *install_dos_part, *install_bsd_part; char *install_prefix; @@ -168,10 +169,12 @@ setup (const char *prefix, const char *dir, boot_img = grub_util_read_image (boot_path); free (boot_path); - /* Set the addresses of BOOT_DRIVE and KERNEL_SECTOR. */ + /* Set the addresses of BOOT_DRIVE, KERNEL_SECTOR and BOOT_DRIVE_CHECK. */ boot_drive = (grub_uint8_t *) (boot_img + GRUB_BOOT_MACHINE_BOOT_DRIVE); kernel_sector = (grub_uint32_t *) (boot_img + GRUB_BOOT_MACHINE_KERNEL_SECTOR); + boot_drive_check = (grub_uint16_t *) (boot_img + + GRUB_BOOT_MACHINE_DRIVE_CHECK); core_path = grub_util_get_path (dir, core_file); core_size = grub_util_get_image_size (core_path); @@ -228,6 +231,13 @@ setup (const char *prefix, const char *dir, free (tmp_img); + /* 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_dev->disk->id & 0x80) + /* Replace the jmp (2 bytes) with double nop's. */ + *boot_drive_check = 0x9090; + /* If the destination device can have partitions and it is the MBR, try to embed the core image into after the MBR. */ if (dest_dev->disk->has_partitions && ! dest_dev->disk->partition)