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.
SATA‑AHCI BIOS (Translated Device Parameter Table): 255 heads, 63 sectors/track
Install Windows 7 (CHS values of partitions from the partition table):
- start:
0 32 33
(hex:20 21 00
), end:12 223 19
(hex:DF 13 0C
)
- start:
12 223 20
(hex:DF 14 0C
), end:1023 254 63
(hex:FE FF FF
)
SATA‑AHCI BIOS (TDPT): 224 heads, 19 sectors/track
After adding 2 more partitions:
- start:
0 107 16
, end:48 134 14
- start:
48 134 15
, end:1023 223 19
???
- start:
1023 223 19
???, end:1023 223 19
???
- 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.
SATA‑AHCI BIOS (TDPT): 135 heads, 14 sectors/track
After removing the 4th partition:
- start:
1 11 5
, end:109 59 12
- start:
109 59 13
, end:1023 134 14
???
- start:
1023 134 14
???, end:1023 134 14
???
SATA‑AHCI BIOS (TDPT): 60 heads, 12 sectors/track
After adding the 4th partition:
- start:
2 50 9
(hex:32 09 02
), end:287 17 4
(hex:11 44 1F
)
- start:
287 17 5
(hex:11 45 1F
), end:1023 59 12
(hex:3B CC FF
)
- start:
1023 59 12
(hex:3B CC FF
), end:1023 59 12
(hex:3B CC FF
)
- start:
1023 59 12
(hex:3B CC FF
), end:1023 59 12
(hex:3B CC FF
)
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:
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.
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 .
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:
- start‑hex:
40 01 00
, end‑hex:C9 20 1F
- start‑hex:
00 01 20
, end‑hex:C9 E0 FF
- start‑hex:
C9 E0 FF
, end‑hex:C9 E0 FF
- 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):
- start‑hex:
20 21 00
, end‑hex:DF 13 0C
- start‑hex:
DF 14 0C
, end‑hex:FE FF FF
- start‑hex:
FE FF FF
, end‑hex:FE FF FF
- 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:
- start‑hex:
20 21 00
, end‑hex:FE FF FF
- start‑hex:
FE FF FF
, end‑hex:FE FF FF
- start‑hex:
FE FF FF
, end‑hex:FE FF FF
- 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.
fdisk -l
from a linux live cd and adding that information to your question would help.number of heads/cylinder mismatches 224 (NTFS) != 255 (HD) … number of sectors per track mismatches 19 (NTFS) != 63 (HD)
and it saysbad 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).