To be on the safe side I duplicate below the message sent to bug-grub@gnu.org, just recently.
I might add that I did cross check that my patch is not touching anything that is not present in the upstreams tar-ball. In addition, the patched setup function acts on whatever Stage1 is to be deposited in the mbr, after the boot partition was searched for originals, or lacking thereof, the new one was imported from the performing grub-version's library. I do hope my message to bug-grub wasn't premature, though! Best regards Mats Erik Andersson --- Mats Erik Andersson <[EMAIL PROTECTED]> skrev: > Dear Maintainers and Bugtrackers, > > I would like to submit a patch to grub 0.97 that > closes the urgent and long standing bug #345931 > recorded with Debian users. I will at some length > try > motivate an upstream acceptance. My arguments are of > some implications even for Grub2, so please read > this > with an open mind. > > In a change 2005-02-15, the underlying principle > for > a workaround to recover from inferior drive-flags > for > harddisks in some BIOSes, was drastically changed. > This > meant that a three-byte instruction in Stage1 of > grub > 0.96 and a new two-byte instruction of grub 0.97 > became > instrumental as to how the workaround are applied in > the respective versions. The outcome was that grub > 0.97 > completely breaks the code in Stage1 from grub 0.96 > when grub 0.97 is used to restore the installed boot > files deposited by grub 0.96. This provoked #345931 > with the elaps of time. > I personally find the above incompatibility to be > a serious mistake, should it be allowed to prevail. > Admittedly, the more recent workaround may well be > superior, but it should not be allowed to disrupt > perfectly fitting installments of grub 0.94-0.96. > My proposed patch simply equips the setup-function > of the grub-shell with the ability to test which > workaround was used in the Stage1-sector present > on the chosen harddisk partition, and then it takes > the corresponding measures needed to correctly > restore Stage1. > At the very end of the patch I have deliberately > coded and commented in a way to allow the proper > actions to be implemented also for providing > backward > compatibility all the way back to grub 0.92, should > the maintainers desire to effectuate also this. > For the time being, the code deliberately fails > for grub 0.93 and older. Please tell me to implement > the extension or do it yourself. I must say again > that I find it imperative to keep versions 0.96 and > 0.97 compatible, since grub 0.95/96 are present on > very many systems and will be for some time to come. > A policy to implement compatibility visavi grub > 0.92/3 > is negotiable and left to the maintainers to decide > upon. > > Now over to Grub2. Robert Millan encouraged me to > determine whether my patch is of relevance to Grub2. > An investigation of the code in grub 1.94 reveals > that > the new code base uses the same mechanism as has > been > applied in grub 0.97 for this particular workaround. > Thus it is well possible that the principle behind > my patch - after insertion of new naming conventions > - > should or could be applied at > > grub-1.94/util/i386/pc/grub-setup.c lines 253-- > > The maintainers must think through and state their > decisions on backwards compatibility in this > respect. > I myself know too little of the code for Grub2 in > order > to state a thought through opinion, but out of > principle I can second backwards compatibility, > where it does not disturb the main objectives. > > As a final side remark, Otavio Salvador urged me > to correct my indentation from the previous version > of the patch. I did my inexperienced best to do > it in the style of the file builtins.c. Feel free to > correct me or complain, as the case may be. > > Best regards > > Mats Erik Andersson > [EMAIL PROTECTED]> # boot_drive_correction.diff > # > # Enables the workaround for the "boot drive flag" > used in grub 0.94-0.96 > # to coexist with the revised principle of grub > 0.97. Thereby the present > # version of the grub-shell restores correctly from > (hd?,?)/boot/grub/* > # for the full span of versions 0.94-0.97. This is > extendible also to > # grub 0.92-0.93, by following my proposition in > the last comment below. > # > diff -Naur grub-0.97.orig/stage2/builtins.c > grub-0.97.patched/stage2/builtins.c > --- grub-0.97.orig/stage2/builtins.c 2005-02-15 > 22:58:23.000000000 +0100 > +++ grub-0.97.patched/stage2/builtins.c 2006-09-28 > 21:05:36.040085552 +0200 > @@ -1956,10 +1956,29 @@ > 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; > - > + { > + if ( *((unsigned char *) (stage1_buffer + > STAGE1_BOOT_DRIVE_CHECK)) == 0xeb ) > + /* For present version 0.97: Replace the > jmp (2 bytes) with double nop's. */ > + *((unsigned short *) (stage1_buffer + > STAGE1_BOOT_DRIVE_CHECK)) > + = 0x9090; > + else if ( *((unsigned char *) (stage1_buffer > + STAGE1_BOOT_DRIVE_CHECK)) == 0x80 ) > + { > + /* For previous versions 0.94-96: Set > the "boot-drive-mask". > + This is the old workaround for buggy > BIOSes which do not pass boot drive correctly. > + The technique was to use 'or dl,0x80', > hence testing for 0x80, i.e. or-instruction. > + REM: the old STAGE1_BOOT_DRIVE_MASK > equals STAGE1_BOOT_DRIVE_CHECK + 2. */ > + *((unsigned char *) (stage1_buffer + > STAGE1_BOOT_DRIVE_CHECK + 2)) > + = (dest_drive & BIOS_FLAG_FIXED_DISK); > + } > + else > + { > + /* The boot sector is thus older than > version 0.94. > + Changing 'goto fail' to a "do nothing" > could even make 0.92 and 0.93 > + acceptable for the purpose of rescuing > their installations. */ > + goto fail; > + } > + } > + > /* Read the first sector of Stage 2. */ > disk_read_hook = disk_read_savesect_func; > if (grub_read (stage2_first_buffer, SECTOR_SIZE) > != SECTOR_SIZE) >
# boot_drive_correction.diff # # Enables the workaround for the "boot drive flag" used in grub 0.94-0.96 # to coexist with the revised principle of grub 0.97. Thereby the present # version of the grub-shell restores correctly from (hd?,?)/boot/grub/* # for the full span of versions 0.94-0.97. This is extendible also to # grub 0.92-0.93, by following my proposition in the last comment below. # diff -Naur grub-0.97.orig/stage2/builtins.c grub-0.97.patched/stage2/builtins.c --- grub-0.97.orig/stage2/builtins.c 2005-02-15 22:58:23.000000000 +0100 +++ grub-0.97.patched/stage2/builtins.c 2006-09-28 21:05:36.040085552 +0200 @@ -1956,10 +1956,29 @@ 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; - + { + if ( *((unsigned char *) (stage1_buffer + STAGE1_BOOT_DRIVE_CHECK)) == 0xeb ) + /* For present version 0.97: Replace the jmp (2 bytes) with double nop's. */ + *((unsigned short *) (stage1_buffer + STAGE1_BOOT_DRIVE_CHECK)) + = 0x9090; + else if ( *((unsigned char *) (stage1_buffer + STAGE1_BOOT_DRIVE_CHECK)) == 0x80 ) + { + /* For previous versions 0.94-96: Set the "boot-drive-mask". + This is the old workaround for buggy BIOSes which do not pass boot drive correctly. + The technique was to use 'or dl,0x80', hence testing for 0x80, i.e. or-instruction. + REM: the old STAGE1_BOOT_DRIVE_MASK equals STAGE1_BOOT_DRIVE_CHECK + 2. */ + *((unsigned char *) (stage1_buffer + STAGE1_BOOT_DRIVE_CHECK + 2)) + = (dest_drive & BIOS_FLAG_FIXED_DISK); + } + else + { + /* The boot sector is thus older than version 0.94. + Changing 'goto fail' to a "do nothing" could even make 0.92 and 0.93 + acceptable for the purpose of rescuing their installations. */ + goto fail; + } + } + /* Read the first sector of Stage 2. */ disk_read_hook = disk_read_savesect_func; if (grub_read (stage2_first_buffer, SECTOR_SIZE) != SECTOR_SIZE)