Package: grub Version: 0.97-47 Severity: normal Tags: patch Hello!
For a rather special application, I tried to use grub's "map" command in a creative way, something like: map (hd0) (hd1) map (hd1) (hd2) map (hd2) (hd3) map (hd3) (hd4) chainloader (hd1)+1 The idea was to "shift" the BIOS numbering of disks and then to jump to the MBR code of the next disk. This worked partially, but only partially... it ended with either "read error" when loading stage1.5, or (if done twice) by a mixup of files from the 2nd and 3rd disk. After a day of debugging I found out the cause of this misbehaviour: The map command installs an INT13 handler that does the remapping of device numbers. After calling the previous handler, it tries to restore register %dl (drive number) to the original value, because it's traditionally a called-saved register (and grub itself relies on that). However, there are two functions (08h and 15h) that return something in %dl/%dx, so in their case the restauration should not happen. Therefore the code tries to catch these, but the conditions are horribly wrong ;) (see patch below: wrong condition tests, and also comparing %ax instead %ah), with the effect that %dl was never restored. So grub started to read one sector from 0x80, the rest coming from 0x81 (or, in the double case, from 0x82)... I guess nobody noticed that until now, because the normal usage of "map" is to swap (hd0) and (hd1) to boot DOS/Win from the second disk. And those two insist on booting from device 0x80 (otherwise you wouldn't need the swap...), so I guess it the device number is hardcoded in their boot loaders. Anyway, the patch below fixes the handler to restore %dl exactly in the cases when it should be. As upstream doesn't maintain "GRUB Legacy" anymore, I want to submit this patch at least here. GRUB2 doesn't contain the map command (yet?), nor the INT13 handler at all, so the fix doesn't apply there. Roman --- grub/stage2/asm.S~ 2004-03-11 13:00:30.000000000 +0100 +++ grub/stage2/asm.S 2008-10-17 16:13:04.000000000 +0200 @@ -713,10 +713,10 @@ movw %ax, 0xc(%bp) /* check if should map the drive number */ movw 6(%bp), %ax - cmpw $0x8, %ax - jne 3f - cmpw $0x15, %ax - jne 3f + cmpb $0x8, %ah + je 3f + cmpb $0x15, %ah + je 3f /* check if the mapping was performed */ movw 2(%bp), %ax testw %ax, %ax -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]