0

tl;dr: skip to Question section

Background

I have a drive on which Windows 7 was installed. It had a 100MB Windows 7 boot-partition, followed by a partition that took up the rest of the drive. A while back, I shrank the main partition so that I could have a separate volume for files instead of storing them on the same volume where Windows, games, and programs are installed.

Recently I cleared out the secondary partition and used EASEUS Parition Master (Home) to delete it, and the main one to use up the whole disk like it was before.

Problem

Unfortunately, after EASEUS finished successfully doing its job (in Windows Native-API mode), I was no longer able to boot the system with that drive in it. Whenever I tried to boot, the BIOS would detect the drive, read and print the SMART data (STAUS OK), and then just hang.

At first I feared the drive had magically died between the re-size operation and the reboot, but after putting it in an external enclosure, I discovered that the drive was in fact just fine and even better, the partitions are intact and all of the files accessible. The other partition is gone and the main one has been extended to the full length of the drive as desired. It is fully functional from Windows, just not from the BIOS.

Tests and Observations

I ran the Disk Management MMC snap-in, chkdsk, TestDisk, (a newer version of) EASEUS Partition Master (free), EASEUS Partition Recovery, PC Inspector Drive Recovery, and a few other tools in read-only mode and found that most of them had no problem with the drive. The only one that gave any indication of a problem was TestDisk which indicated a mismatch of the drive geometry.

Diagnosis

The conclusion I have drawn is that Windows is able to read the drive and detect the partitions just fine (it probably ignores the irrelevant backward-compatibility) values in the partition table, but when the BIOS tries to read the boot files from the drive, it gets tripped up on the incorrect values and hangs.

Question

What I need now is a way to correct the partition table (and MBR?) to be backward-compatible with the BIOS (and ostensibly DOS) without losing any data.

Restrictions

I know that you can re-write the MBR without any data loss, but I am not sure of a way to re-build the partition table without messing up existing partitions.

Unfortunately, I don’t have a large enough spare drive to which I can copy everything (nor would I want to format and copy back all of that stuff), so I need a safe way to do an in-place repair. I have dumped a copy of the first megabyte or so of the drive as well as some of the beginning of the Windows partition. Therefore, I have a copy of the MBR, partition table, and boot sector of the 100MB boot-partition and Windows partition.

Tools and Skills

I am comfortable with low-level disk tools, including hex- and disk-editors (I have done data-recovery on FAT volumes on several occasions including re-building FAT chains and directories), but not much experience with NTFS.


TestDisk gives the following errors on analysis:

Disk /dev/sdf - 500 GB / 465 GiB - CHS 60801 255 63
Current partition structure:
         Partition                  Start        End    Size in sectors

Warning: number of heads/cylinder mismatches 224 (NTFS) != 255 (HD)
Warning: number of sectors per track mismatches 19 (NTFS) != 63 (HD)
 1 * HPFS - NTFS              0  32 33    12 223 19     204800

Bad relative sector.
 2 P HPFS - NTFS             12 223 20 60801  76 27  976566032

Bad relative sector.

And the backup log is as follows:

#1420342168 Disk /dev/sdf - 500 GB / 465 GiB - CHS 60801 255 63
 1 : start=     2048, size=   204800, Id=07, *
 2 : start=   206848, size=976566032, Id=07, P
#1420342211 Disk /dev/sdf - 500 GB / 465 GiB - CHS 60801 255 63
 1 : start=     2048, size=   204800, Id=07, *
 2 : start=   206848, size=976566032, Id=07, P
5
  • What is the geometry the partition table appears to be using? Running fdisk -l from a linux live cd and adding that information to your question would help.
    – psusi
    Commented Jan 4, 2015 at 1:15
  • Which partition is currently flagged as the "boot partition"? "Recently I cleared out the secondary partition..." -- You probably mean the third partition.
    – sawdust
    Commented Jan 4, 2015 at 2:07
  • @psusi, I didn’t have the system on hand when I posted the question, but I got the information. TestDisk says number of heads/cylinder mismatches 224 (NTFS) != 255 (HD) … number of sectors per track mismatches 19 (NTFS) != 63 (HD) and it says bad relative sectors under each of the two partitions (boot-partition and main full-drive partition—the other one is indeed gone and merged into the main one).
    – Synetech
    Commented Jan 4, 2015 at 3:23
  • @sawdust, well yes, technically third, but in that context, I was referring to the partitions of use (the 100MB boot-partition is actually hidden and inaccessible in Windows, so I wasn’t counting it when I was describing the user-partitions). That partition is the primary anyway, the others are in the extended partition, so in a way, the third one is indeed the secondary partition.
    – Synetech
    Commented Jan 4, 2015 at 3:24
  • Well I let TestDisk rewrite the partition table, and now it is not giving those errors. I will try plugging the drive into the computer tomorrow morning and hopefully it will get past the BIOS like it used to. I’ll update then…
    – Synetech
    Commented Jan 4, 2015 at 6:08

3 Answers 3

1

The BIOS generally shouldn't be reading any boot files, just the 440 bytes of bootstrap code in MBR, the rest is your bootloader's business... (Though there are unfortunate exceptions.)

So it's possible that you only need to reinstall the Windows bootloader using bootrec /fixmbr.

To recreate the partition table, a Linux CD would work. Run fdisk /dev/sd…, write down the partition layout (type, start sector, size), use o to create an empty partition table, re-add all partitions using the exact same layout, and write out the new table.

5
  • That likely will fix it. If the geometry is wrong, that would trip up the windows boot loader because iirc, it doesn't switch to LBA mode and continues to use CHS addressing if possible.
    – psusi
    Commented Jan 4, 2015 at 1:17
  • Except that I cannot boot into Windows on the drive in question. I can boot into another instance of Windows with the problem-drive attached as a USB drive. I don’t think bootrec can affect the MBR of another drive. And I’d prefer to avoid live-cds and such if at all possible; I’m sure it doesn’t have to come to that, there should be a way to do it in Windows.
    – Synetech
    Commented Jan 4, 2015 at 3:27
  • @Synetech, the incorrect relative sectors ( another foolish thing Microsoft decided to encode in their boot sectors ) will also prevent it from booting. You should be able to use fixboot from another system's recovery console on the problem disk just fine.
    – psusi
    Commented Jan 4, 2015 at 3:51
  • With what psusi is saying - you should be able to use a recovery disk or Hiren's or something to boot to and then from the command-line tool do the repair on the disk which is not booting.
    – Abraxas
    Commented Jan 4, 2015 at 3:54
  • I tired fixboot, but it did nothing (testdisk still gives the same error).
    – Synetech
    Commented Jan 4, 2015 at 5:39
1

This looks like an old bug (divide‑integer overflow) in the AHCI/RAID firmware of an Intel chipset SATA controller — booting stops with POST code 23 at the enumeration of devices connected to the SATA controller (the "problematic" SATA device is connected to "Port-01"):

――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
Serial ATA AHCI BIOS, Version iSrc 1.20E
Copyright (c) 2003-2008 Intel Corporation                       23
** This version supports only Hard Disk and CDROM drives **
Please wait. This will take few seconds.

Controller Bus#00, Device#1F, Function#02: 06 Ports, 02 Devices
  Port-00: No device detected
_
――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――

Detailed description of the bug and specifics of the AHCI/RAID firmware:

A few links that will help you figure out the MBR structure and fix the problem manually:

Let me clarify what kondra meant when he wrote:

if you partition the disk several times and the drive geometry gets changed by diskpar, diskpart and Windows Setup CD, it is possible that you end with a controller hang, because the CHS values get even more corrupted from time to time.

Consider the case of a clean install of Windows 7 with, for example, a Gigabyte desktop motherboard.

Note: each item in the list below represents one system boot.

  1. SATA‑AHCI BIOS (Translated Device Parameter Table): 255 heads, 63 sectors/track
    Install Windows 7 (CHS values of partitions from the partition table):

    1. start:0 32 33 (hex:20 21 00), end:12 223 19 (hex:DF 13 0C)
    2. start:12 223 20 (hex:DF 14 0C), end:1023 254 63 (hex:FE FF FF)
  2. SATA‑AHCI BIOS (TDPT): 224 heads, 19 sectors/track
    After adding 2 more partitions:

    1. start:0 107 16, end:48 134 14
    2. start:48 134 15, end:1023 223 19???
    3. start:1023 223 19???, end:1023 223 19???
    4. start:1023 223 19???, end:1023 223 19???

    Note: for already existing partitions (the first two), only the CHS values are changed, while the LBAs remains the same.

  3. SATA‑AHCI BIOS (TDPT): 135 heads, 14 sectors/track
    After removing the 4th partition:

    1. start:1 11 5, end:109 59 12
    2. start:109 59 13, end:1023 134 14???
    3. start:1023 134 14???, end:1023 134 14???
  4. SATA‑AHCI BIOS (TDPT): 60 heads, 12 sectors/track
    After adding the 4th partition:

    1. start:2 50 9 (hex:32 09 02), end:287 17 4 (hex:11 44 1F)
    2. start:287 17 5 (hex:11 45 1F), end:1023 59 12 (hex:3B CC FF)
    3. start:1023 59 12 (hex:3B CC FF), end:1023 59 12 (hex:3B CC FF)
    4. start:1023 59 12 (hex:3B CC FF), end:1023 59 12 (hex:3B CC FF)
  5. SATA‑AHCI BIOS: POST code 23 …

??? — assumed value.

Spoiler: To generate the subsequent CHS addresses (of last absolute sector in 1st partition), I used the following JavaScript code to investigate the effect of to analyze the impact of this specific DPT Translation on the CHS address:

(function(){"use strict";
    // https://en.wikipedia.org/wiki/Logical_block_addressing?oldid=1061258642#CHS_conversion

    var LBA_to_c = function(LBA, TDPT_H, TDPT_S){ return LBA/(TDPT_H*TDPT_S) |0; };
    var LBA_to_h = function(LBA, TDPT_H, TDPT_S){ return (LBA/TDPT_S |0) % TDPT_H; };
    var LBA_to_s = function(LBA,         TDPT_S){ return LBA % TDPT_S + 1; };

    var print = function(i, c,h,s){
        console.log(
            (   " "+i).slice(-2) +": "+
            ("    "+c).slice(-5)  +" "+
            (  "  "+h).slice(-3)  +" "+
            (   " "+s).slice(-2)
        );
    };

    var LBA = 206847;

    var c = LBA_to_c(LBA, 255, 63),
        h = LBA_to_h(LBA, 255, 63),
        s = LBA_to_s(LBA,      63);

    print(0, c,h,s);

    for(var i=1; i<=16; i++){
        c = LBA_to_c(LBA, h+1, s),
        h = LBA_to_h(LBA, h+1, s),
        s = LBA_to_s(LBA,      s);

        print(i, c,h,s);
    }
})();

Output:

        c   h  s
 0:    12 223 19
 1:    48 134 14
 2:   109  59 12
 3:   287  17  4
 4:  2872  15  4
 5:  3231  15  4
 6:  3231  15  4
 7:  3231  15  4
 …

As you can see, the divide‑integer overflow occursi:(3)⇥4 before the CHS values stabilizei:4→5.

It turns out that after installing the system, we can change the partition table (including reboot) only 2 times.

Possible Solutions

Mathematical Solution

We need to find such a CHS address (of last absolute sector in 1st partition) that would remain constant taking into account the DPT Translation. That is:

  1. Find an 𝒔 such that:

    𝟣 ≤ 𝒔 ≤ 𝟨𝟥,
    𝒔 ∈ ℕ,
    𝑠 = TDPT𝑺,
    𝑠  =  (LBA 𝗺𝗼𝗱 TDPT𝑺) + 𝟣 = (LBA 𝗺𝗼𝗱 𝑠) + 𝟣,

    where 𝒔 is the sector number (in CHS address of last absolute sector in 1st partition), TDPT𝑺 is the translated number of sectors per track.

    For clarity, I'll slightly transform (the +𝟣 is moved to the left‑hand side, and the sides are swapped) the last equation:

    LBA 𝗺𝗼𝗱 𝑠 = 𝑠 − 𝟣,

    which is equivalent to I hope you are well versed in modular arithmetic:

    (LBA + 𝟣) 𝗺𝗼𝗱 𝑠 = 𝟢,

    LBA 𝗺𝗼𝗱 𝑠 = 𝑠 − 𝟣
    LBA 𝗺𝗼𝗱 𝑠 = (𝑠 − 𝟣) 𝗺𝗼𝗱 𝑠
    (LBA + 𝟣) 𝗺𝗼𝗱 𝑠 = (𝑠 − 𝟣 + 𝟣) 𝗺𝗼𝗱 𝑠
    (LBA + 𝟣) 𝗺𝗼𝗱 𝑠 = 𝑠 𝗺𝗼𝗱 𝑠
    (LBA + 𝟣) 𝗺𝗼𝗱 𝑠 = 𝟢

    i.e., to find all 𝒔, it is sufficient to find the factors of (LBA + 𝟣).

    For LBA = 206847, 𝑠 = {32,16,8,4,2,1}.
    I'll choose the largest value 𝑠 = 32 . This will not only allow more LBA addresses to be addressed (CHS) but will also avoid the divide‑integer overflow mentioned above that occurs when the ((ℎ+𝟣) × 𝑠) value is small.

  2. Find an ℎ such that:

    𝟢 ≤ ℎ ≤ 𝟤𝟧𝟧,
    ℎ ∈ ℕ,
    ℎ + 𝟣 = TDPT𝑯,
    ℎ  =  (LBA ÷ TDPT𝑺) 𝗺𝗼𝗱 TDPT𝑯 = (LBA ÷ 𝟥𝟤) 𝗺𝗼𝗱 (ℎ + 𝟣),

    where ℎ is the head number (in CHS address of last absolute sector in 1st partition), TDPT𝑯 is the translated number of heads per cylinder, "÷" is integer division.

    In this case, it will be easier to determine the value of TDPT𝑯 first and then ℎ. Transform (the substitution ℎ = TDPT𝑯 − 𝟣 is used, and the sides are swapped) the last equation:

    (LBA ÷ 𝟥𝟤) 𝗺𝗼𝗱 TDPT𝑯 = TDPT𝑯 − 𝟣,

    which, again, is equivalent to:

    ((LBA ÷ 𝟥𝟤) + 𝟣) 𝗺𝗼𝗱 TDPT𝑯 = 𝟢,

    i.e., to find all TDPT𝑯, it is sufficient to find the factors of ((LBA ÷ 𝟥𝟤) + 𝟣).

    For LBA = 206847 and 𝑠 = 32, TDPT𝑯 = {202,101,64,32,16,8,4,2,1}.
    I'll choose the largest value TDPT𝑯 = 202; therefore ℎ = 201 .

  3. It remains to calculate 𝑐 (cylinder number) by the formula:

    𝑐 = LBA ÷ (TDPT𝑯 × TDPT𝑺)

    For LBA = 206847 and 𝑠 = 32 and ℎ = 201, 𝑐 = 31.

Let's check that the divide‑integer overflow (see the disassembled AHCI.BIN at the end of the message) will not occur ( (ℎ+𝟣) × 𝑠 = 202 × 32 = 6464 = 1940h ) :

seg000:36C1  div bp  ; dx:ax / bp = FB0400h / 1940h, ax = quotient, dx = remainder
                     ; ax = 09F0h
                     ; dx = 1800h

Overflow did not occur. We have successfully obtained the stable CHS address that does not cause overflow and fully conform to the standard (for LBA < 16450559, the CHS address should match LBA, i.e. one should not use the CHS bytes FE FF FF to force the use of LBA — !citation needed! ).

The corrected CHS bytes of the partition table entries for the example above Windows 7 look like this:

  1. start‑hex:40 01 00, end‑hex:C9 20 1F
  2. start‑hex:00 01 20, end‑hex:C9 E0 FF
  3. start‑hex:C9 E0 FF, end‑hex:C9 E0 FF
  4. start‑hex:C9 E0 FF, end‑hex:C9 E0 FF

Note: an example of encoding the CHS address 31 201 32:

  • head 201 → C9h
  • sector 32 and cylinder 31 → [10 0000][00 0001 1111] → (0010 0000)(0001 1111) → 20h 1Fh

Spoiler: You can use the following function (in JavaScript) to encode CHS addresses:

function CHS2bytes(c,h,s){ "use strict";

  if( h < 0 ||  254 < h ||
      s < 1 ||   63 < s ||
      c < 0 || 1023 < c  ) return "Wrong!";  // http://starman.vertcomp.com/asm/mbr/PartTables.htm#Decoding  (see the NOTE)
                                             // http://starman.vertcomp.com/asm/mbr/PartTables3.htm#20GBpt
                                                                                                      console.warn("!!! Always check the source code before using it !!!");
  return (
      ("0"+( h                    ).toString(16)).slice(-2) +" "+
      ("0"+( s | ((c & 0x300)>>2) ).toString(16)).slice(-2) +" "+
      ("0"+( c & 0xFF             ).toString(16)).slice(-2)
  ).toUpperCase();
}

Using it in the browser's JS console: after entering the function code, it can be called, for example, like CHS2bytes(31,201,32), which will return "C9 20 1F".

Note: it might work better to use FE FF FF (as the more expectedhard‑coded address) instead of C9 E0 FF (CHS address 1023 201 32).

Note: The changes are made with AHCI disabled so that the computer can boot from a LiveCDfor example: WinPE(open the CMD:Shift+F10, type:wpeinit), and the portable HxD Hex Editor "installed" on a USB flash drive with the target drive attached. After making changes, it is necessary to restore the previous mode (AHCI or RAID) of the SATA controller.

Other Solutions

Each of the solutions below has its disadvantages (see Cons), and in general they give incorrect CHS addresses. But, nevertheless, the divide‑integer overflow will be eliminated — the computer will be able to boot in AHCI mode of the SATA controller with the target drive attached. The operating system Windows 7 will also boot successfully.

Note: the changes are made with AHCI disabled; after making changes, it is necessary to restore the previous mode (AHCI or RAID) of the SATA controller.

  • Revert CHS addresses to the original ones (calculated with TDPT: 255 heads, 63 sectors/track — when installing Windows 7):

    1. start‑hex:20 21 00, end‑hex:DF 13 0C
    2. start‑hex:DF 14 0C, end‑hex:FE FF FF
    3. start‑hex:FE FF FF, end‑hex:FE FF FF
    4. start‑hex:FE FF FF, end‑hex:FE FF FF

    Cons: CHS and LBA addresses will not match (keep in mind the Translated DPT); you will still be able to change_partition_table‑reboot only 2 times — on the 3rd change of the partition table, you will have to edit the CHS addresses manually again.

  • Use the CHS address 1023 254 63 (bytes FE FF FF) as kondra suggested:

    1. start‑hex:20 21 00, end‑hex:FE FF FF
    2. start‑hex:FE FF FF, end‑hex:FE FF FF
    3. start‑hex:FE FF FF, end‑hex:FE FF FF
    4. start‑hex:FE FF FF, end‑hex:FE FF FF

    Cons: these values do not conform to the standard (for LBA < 16450559, the CHS address should match LBA — !citation needed! ); the next time you change the partition table, a program the EASEUS Partition Master you mentioned, or … will most likely recalculate the CHS addresses, and DF 13 0C (CHS of the last absolute sector in 1st partition) will comeback again…

  • Run TestDisk — it will recalculate CHS addresses according to the current values from TDPT.

    Cons: see the cons to the first solution "Revert CHS addresses to the original ones".

  • Recall the quote (perhaps it was Stallman):

    By sponsoring proprietary software (Closed Source & Closed Project/System Documentation), you sponsor bugs that will remain in the software forever — no one will want to fix them ("by design") except you, and it will be difficult for you to fix them yourself, seeing only machine codes in front of you.

    Cons: you might never await for the source code and documentation to be opened.

1
0

In the past, I have been impressed by Christophe Grenier's PhotoRec. Obviously he really knows what he is doing and has done a great deal of research into file-systems and file-types. As such, I decided to trust his expertise and let TestDisk do its thing (especially since it was the only tool that actually detected any problems at all).

After the error message, I continued on and reached a point where it gave me the option to write the partition table I was looking at or search for more. Since the listed partitions were already correct, I allowed it to write the partition table and reboot. The drive was still recognized and all files accessible (still in the external enclosure), so I did a chkdsk for peace of mind which checked out.

The final step was to plug it into the system and see if it could get past the BIOS. Sure enough, it did. I did one more chkdsk just to be extra sure, and it checked out again. In fact, I am currently writing this post while the drive spins happily away in the computer.

So if anyone resizes a partition and finds that their BIOS hangs after detecting the drive, either put it in an external enclosure or put it in another system with a different BIOS, then have TestDisk re-write the partition table. It should adjust the parameters to once again be compatible with an older BIOS (and probably DOS as well). It will write the correct partition table with correct parameters and should leave all of the other data on the drive intact.


Stock screenshot of TestDisk's write—partition-table screen



(I'll note that once TestDisk re-wrote the partition-table, it no longer showed errors it re-wrote the partition-table while it was still in the enclosure, but after putting the drive back in the system, TestDisk is once again showing errors, some old, some new, some different, but the drive is working fine nonetheless. I've included the new errors below in case anybody wants to attempt to debug the exact cause of the BIOS-hang since it seems to only partially related to the geometry parameters.)

Disk /dev/sdb - 500 GB / 465 GiB - CHS 229504 224 19
Current partition structure:
         Partition                  Start        End    Size in sectors

 1 * HPFS - NTFS              0 107 16    48 134 14     204800

Warning: Bad starting sector (CHS and LBA don't match)
Warning: number of heads/cylinder mismatches 255 (NTFS) != 224 (HD)
Warning: number of sectors per track mismatches 63 (NTFS) != 19 (HD)
 2 P HPFS - NTFS             48 134 15 229504 215 11  976566272

Warning: Bad starting sector (CHS and LBA don't match)

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .