Core ReactOS
  1. Core ReactOS
  2. CORE-12692

FreeLdr believes our CD is a HDD if it has a 0xAA55 MBR signature

    Details

    • Type: Bug Bug
    • Status: In Progress In Progress
    • Priority: Major Major
    • Resolution: Unresolved
    • Fix Version/s: None
    • Component/s: Bootloader
    • Labels:
      None

      Description

      In CORE-12648, I'm using isohybrid to patch isombr.bin at the beginning of our ISO. As soon as I have done this, the ISO is unbootable either way, because FreeLdr always believes it is a HDD.

      The guilty code can be found in boot/freeldr/freeldr/disk/disk.c. Look for the /* FIXME */

        Issue Links

          Activity

          Hide
          HBelusca
          added a comment -

          Hi Colin Finck, please retest with r73621+.

          Show
          HBelusca
          added a comment - Hi Colin Finck , please retest with r73621+.
          Hide
          HBelusca
          added a comment - - edited

          As you did point out to me sooner, the INT13h AX=4B01h fails on Dell Latitude D531 when booting from a CD (why??): I get:

          (boot\freeldr\freeldr\arch\i386\pcdisk.c:627) err: DiskIsCdRomDrive(0x82)
          (boot\freeldr\freeldr\arch\i386\pcdisk.c:97) err:
          Packet->PacketSize  = 0x13
          Packet->MediaType   = 0x0
          Packet->DriveNumber = 0x0
          Packet->Controller  = 0x0
          Packet->LBAImage    = 0x0
          Packet->DeviceSpec  = 0x0
          Packet->Buffer      = 0x0
          Packet->LoadSeg     = 0x0
          Packet->SectorCount = 0x0
          (boot\freeldr\freeldr\arch\i386\pcdisk.c:667) err: INT386_SUCCESS failed
          (boot\freeldr\freeldr\arch\i386\pcdisk.c:670) err: AX = 0x0701
          (boot\freeldr\freeldr\arch\i386\pcdisk.c:97) err:
          Packet->PacketSize  = 0x13
          Packet->MediaType   = 0x40
          Packet->DriveNumber = 0x82
          Packet->Controller  = 0x0
          Packet->LBAImage    = 0x84
          Packet->DeviceSpec  = 0x0
          Packet->Buffer      = 0x0
          Packet->LoadSeg     = 0x0
          Packet->SectorCount = 0x4
          (boot\freeldr\freeldr\arch\i386\pcdisk.c:607) err: FallbackDiskIsCdRomDrive(0x82)
          (boot\freeldr\freeldr\arch\i386\pcdisk.c:416) err: PcDiskReadLogicalSectors() DriveNumber: 0x82 SectorNumber: 0 SectorCount: 1 Buffer: 0x6d000
          (boot\freeldr\freeldr\arch\i386\pcdisk.c:323) err: DiskInt13ExtensionsSupported()
          

          so, CF flag is set, AX is set to some error (that I cannot find on the Internet), while the Spec Packet is filled with correct values, and the BIOS still supports INT 13h extensions on the drive.
          Also it should be noticed that the 4B01h call in isoboot.S does not fail (does not run the AWARD patch hack nor the failure paths).

          GRUB4DOS might have a workaround:
          https://github.com/chenall/grub4dos/blob/master/stage2/eltorito.asm#L51
          https://github.com/chenall/grub4dos/blob/master/stage2/eltorito.asm#L862

          Also in GRUB:
          http://git.savannah.gnu.org/gitweb/?p=grub.git;a=blob;f=grub-core/disk/i386/pc/biosdisk.c;hb=f3df8f961f19fa8ecfb463b1559ba2ae68b53c5d#l206
          and see comment lines 221-222.

          EDIT: I note that the error returned:

          (boot\freeldr\freeldr\arch\i386\pcdisk.c:670) err: AX = 0x0701

          aka. AH = 0x07, means "07h - drive parameter activity failed (hard disk)" (see Int 13/AH=01h - Get Status of Last Operation).

          Show
          HBelusca
          added a comment - - edited As you did point out to me sooner, the INT13h AX=4B01h fails on Dell Latitude D531 when booting from a CD (why??): I get: (boot\freeldr\freeldr\arch\i386\pcdisk.c:627) err: DiskIsCdRomDrive(0x82) (boot\freeldr\freeldr\arch\i386\pcdisk.c:97) err: Packet->PacketSize = 0x13 Packet->MediaType = 0x0 Packet->DriveNumber = 0x0 Packet->Controller = 0x0 Packet->LBAImage = 0x0 Packet->DeviceSpec = 0x0 Packet->Buffer = 0x0 Packet->LoadSeg = 0x0 Packet->SectorCount = 0x0 (boot\freeldr\freeldr\arch\i386\pcdisk.c:667) err: INT386_SUCCESS failed (boot\freeldr\freeldr\arch\i386\pcdisk.c:670) err: AX = 0x0701 (boot\freeldr\freeldr\arch\i386\pcdisk.c:97) err: Packet->PacketSize = 0x13 Packet->MediaType = 0x40 Packet->DriveNumber = 0x82 Packet->Controller = 0x0 Packet->LBAImage = 0x84 Packet->DeviceSpec = 0x0 Packet->Buffer = 0x0 Packet->LoadSeg = 0x0 Packet->SectorCount = 0x4 (boot\freeldr\freeldr\arch\i386\pcdisk.c:607) err: FallbackDiskIsCdRomDrive(0x82) (boot\freeldr\freeldr\arch\i386\pcdisk.c:416) err: PcDiskReadLogicalSectors() DriveNumber: 0x82 SectorNumber: 0 SectorCount: 1 Buffer: 0x6d000 (boot\freeldr\freeldr\arch\i386\pcdisk.c:323) err: DiskInt13ExtensionsSupported() so, CF flag is set, AX is set to some error (that I cannot find on the Internet), while the Spec Packet is filled with correct values, and the BIOS still supports INT 13h extensions on the drive. Also it should be noticed that the 4B01h call in isoboot.S does not fail (does not run the AWARD patch hack nor the failure paths). GRUB4DOS might have a workaround: https://github.com/chenall/grub4dos/blob/master/stage2/eltorito.asm#L51 https://github.com/chenall/grub4dos/blob/master/stage2/eltorito.asm#L862 Also in GRUB: http://git.savannah.gnu.org/gitweb/?p=grub.git;a=blob;f=grub-core/disk/i386/pc/biosdisk.c;hb=f3df8f961f19fa8ecfb463b1559ba2ae68b53c5d#l206 and see comment lines 221-222. EDIT: I note that the error returned: (boot\freeldr\freeldr\arch\i386\pcdisk.c:670) err: AX = 0x0701 aka. AH = 0x07, means "07h - drive parameter activity failed (hard disk)" (see Int 13/AH=01h - Get Status of Last Operation ).
          Hide
          HBelusca
          added a comment -

          Some news: if we manually reset the drive (status) just before calling INT 13h, AX=0x4B01, then the call succeeds:

              // HACK?? Reset the disk before getting its status.....
              RegsIn.w.ax=0;
              RegsIn.b.dl = DriveNumber;
              Int386(0x13, &RegsIn, &RegsOut);
              Success = INT386_SUCCESS(RegsOut);
              if (!Success)
                  TRACE("INT 13h AH=0x00 failed\n");
              TRACE("AX = 0x%04x\n", RegsOut.w.ax);
              RegsIn.w.ax = 0x4B01;
              RegsIn.b.dl = DriveNumber;
              RegsIn.x.ds = BIOSCALLBUFSEGMENT;   // DS:SI -> specification packet
              RegsIn.w.si = BIOSCALLBUFOFFSET;
          // Possibly resetting CF to zero too...
              PrintCdRomPacket(Packet);
              Int386(0x13, &RegsIn, &RegsOut);
          ...
              Success = INT386_SUCCESS(RegsOut);
              if (!Success)
                  TRACE("INT 13h AX=0x4B01 failed\n");

          Now we get:

          (H:\trunk\reactos_clean\boot\freeldr\freeldr\arch\i386\pcdisk.c:627) err: DiskIsCdRomDrive(0x82)
          (H:\trunk\reactos_clean\boot\freeldr\freeldr\arch\i386\pcdisk.c:644) err: AX = 0x0000
          (H:\trunk\reactos_clean\boot\freeldr\freeldr\arch\i386\pcdisk.c:97) err:
          Packet->PacketSize  = 0x13
          Packet->MediaType   = 0x0
          Packet->DriveNumber = 0x0
          Packet->Controller  = 0x0
          Packet->LBAImage    = 0x0
          Packet->DeviceSpec  = 0x0
          Packet->Buffer      = 0x0
          Packet->LoadSeg     = 0x0
          Packet->SectorCount = 0x0
          (H:\trunk\reactos_clean\boot\freeldr\freeldr\arch\i386\pcdisk.c:686) err: AX = 0x0001
          (H:\trunk\reactos_clean\boot\freeldr\freeldr\arch\i386\pcdisk.c:97) err:
          Packet->PacketSize  = 0x13
          Packet->MediaType   = 0x40
          Packet->DriveNumber = 0x82
          Packet->Controller  = 0x0
          Packet->LBAImage    = 0x23
          Packet->DeviceSpec  = 0x0
          Packet->Buffer      = 0x0
          Packet->LoadSeg     = 0x0
          Packet->SectorCount = 0x4
          (H:\trunk\reactos_clean\boot\freeldr\freeldr\arch\i386\pcdisk.c:416) err: PcDiskReadLogicalSectors() DriveNumber: 0x82 SectorNumber: 16 SectorCount: 1 Buffer: 0x6d000
          (H:\trunk\reactos_clean\boot\freeldr\freeldr\arch\i386\pcdisk.c:323) err: DiskInt13ExtensionsSupported()

          so now, we do not get anymore INT13_STATUS failed, and AH is == 0x00 (status success).

          Show
          HBelusca
          added a comment - Some news: if we manually reset the drive (status) just before calling INT 13h, AX=0x4B01, then the call succeeds: // HACK?? Reset the disk before getting its status..... RegsIn.w.ax=0; RegsIn.b.dl = DriveNumber; Int386(0x13, &RegsIn, &RegsOut); Success = INT386_SUCCESS(RegsOut); if (!Success) TRACE( "INT 13h AH=0x00 failed\n" ); TRACE( "AX = 0x%04x\n" , RegsOut.w.ax); RegsIn.w.ax = 0x4B01; RegsIn.b.dl = DriveNumber; RegsIn.x.ds = BIOSCALLBUFSEGMENT; // DS:SI -> specification packet RegsIn.w.si = BIOSCALLBUFOFFSET; // Possibly resetting CF to zero too... PrintCdRomPacket(Packet); Int386(0x13, &RegsIn, &RegsOut); ... Success = INT386_SUCCESS(RegsOut); if (!Success) TRACE( "INT 13h AX=0x4B01 failed\n" ); Now we get: (H:\trunk\reactos_clean\boot\freeldr\freeldr\arch\i386\pcdisk.c:627) err: DiskIsCdRomDrive(0x82) (H:\trunk\reactos_clean\boot\freeldr\freeldr\arch\i386\pcdisk.c:644) err: AX = 0x0000 (H:\trunk\reactos_clean\boot\freeldr\freeldr\arch\i386\pcdisk.c:97) err: Packet->PacketSize = 0x13 Packet->MediaType = 0x0 Packet->DriveNumber = 0x0 Packet->Controller = 0x0 Packet->LBAImage = 0x0 Packet->DeviceSpec = 0x0 Packet->Buffer = 0x0 Packet->LoadSeg = 0x0 Packet->SectorCount = 0x0 (H:\trunk\reactos_clean\boot\freeldr\freeldr\arch\i386\pcdisk.c:686) err: AX = 0x0001 (H:\trunk\reactos_clean\boot\freeldr\freeldr\arch\i386\pcdisk.c:97) err: Packet->PacketSize = 0x13 Packet->MediaType = 0x40 Packet->DriveNumber = 0x82 Packet->Controller = 0x0 Packet->LBAImage = 0x23 Packet->DeviceSpec = 0x0 Packet->Buffer = 0x0 Packet->LoadSeg = 0x0 Packet->SectorCount = 0x4 (H:\trunk\reactos_clean\boot\freeldr\freeldr\arch\i386\pcdisk.c:416) err: PcDiskReadLogicalSectors() DriveNumber: 0x82 SectorNumber: 16 SectorCount: 1 Buffer: 0x6d000 (H:\trunk\reactos_clean\boot\freeldr\freeldr\arch\i386\pcdisk.c:323) err: DiskInt13ExtensionsSupported() so now, we do not get anymore INT13_STATUS failed, and AH is == 0x00 (status success).
          Hide
          Colin Finck
          added a comment -

          Ok, just had a look at this bug, your latest findings and the comments in GRUB and GRUB4DOS.
          This INT 13h function 4B01h still looks like a peculiar thing to me, which we should avoid wherever possible. Some BIOSes return correct data and don't clear AH, some don't clear carry on success, some require a reset before they return anything at all, etc.

          Therefore, my preferred solution to this mess is passing a value in DH from the boot sector that indicates whether we're booting from HDD or CDROM.
          This would need to be done in all our boot sectors and should go together with cleaning up our reactos\boot\freeldr\bootsect directory from outdated stuff. I also don't mind if people use other bits in DH later to pass more flags.

          Do you agree?

          Show
          Colin Finck
          added a comment - Ok, just had a look at this bug, your latest findings and the comments in GRUB and GRUB4DOS. This INT 13h function 4B01h still looks like a peculiar thing to me, which we should avoid wherever possible. Some BIOSes return correct data and don't clear AH, some don't clear carry on success, some require a reset before they return anything at all, etc. Therefore, my preferred solution to this mess is passing a value in DH from the boot sector that indicates whether we're booting from HDD or CDROM. This would need to be done in all our boot sectors and should go together with cleaning up our reactos\boot\freeldr\bootsect directory from outdated stuff. I also don't mind if people use other bits in DH later to pass more flags. Do you agree?
          Hide
          HBelusca
          added a comment -

          I agree (DH is normally the partition number, and in some parts of freeldr we set it to 0xFF for CDROM, so you can do that too in the bootsectors). However I'm still trying to think about a bootsector-independent solution too so that we should not have to be tied to a particular bootsector (ours), but we can run on others...

          Show
          HBelusca
          added a comment - I agree (DH is normally the partition number, and in some parts of freeldr we set it to 0xFF for CDROM, so you can do that too in the bootsectors). However I'm still trying to think about a bootsector-independent solution too so that we should not have to be tied to a particular bootsector (ours), but we can run on others...

            People

            • Assignee:
              HBelusca
              Reporter:
              Colin Finck
            • Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

              • Created:
                Updated: