该方案基于个人理解,已修复一砖,不过不保证一定适合所有情况
主要使用QPST中的eMMC Software Download工具进行修复
这里使用的版本主要是QPST_2.7_374,也可以下其他更新的版本(366等旧版本不支持8660的hex,会报错)
QPST_2.7_374.rar
此时QPST的主要用处就是将手机重新分区,并写入bootloader等底层,最终实现将手机启动到S/W刷机模式或fastboot模式来进行刷机。
需要的文件主要有MPRG8660.hex,8660_msimage.mbn,还有根据对应手机编写的的rawprogram0.xml
MPRG8660.hex的生成可以参考http://www.anyclub.org/2012/04/how-to-build-emmc-flash-programmer.html
不过显然我们是无法得到那些文件的,所以这里就只能借用小米手机fastboot包中的MPRG8660.hex
不过这个hex文件是个刷机程序(flash programmer),在我看来应该就是一个让cpu知道如何把数据写入到ROM中并启动bootloader的程序,所以它应该是相同的cpu之间通用的
而8660_msimage.mbn应该就是bootloader了,小米的8660_msimage.mbn的作用就是让手机启动到U盘模式(此时手机的emmc作为磁盘接到电脑上进行操作,方便进行重新分区并写入正确的底层)
这个文件的生成可以参考http://www.anyclub.org/2012/05/how-to-generate-8660msimagembn.html
需要相应手机的sbl1.mbn,sbl2.mbn,sbl3.mbn,rpm.mbn,tz.mbn和partition_boot.xml来生成(注意,并不推荐这样做,这样生成的文件A820L不能使用,会造成手机无法再进入QHSUSB_DLOAD模式,只能使用JTAG进行恢复)
下面的partition_boot.xml格式在374及更新版本中已经不再使用了,这里附上仅供参考
partition_boot.xml
<?xml version="1.0"?> <image> <physical_partition number="0"> <primary order="1" type="4d" bootable="true" label="SBL1" size="1000" readonly="false"> <file name="sbl1.mbn" offset="0"/> </primary> <primary order="2" type="51" bootable="false" label="SBL2" size="3000" readonly="false"> <file name="sbl2.mbn" offset="0"/> </primary> <primary order="3" type="45" bootable="false" label="SBL3" size="1500" readonly="false"> <file name="sbl3.mbn" offset="0"/> </primary> <primary order="4" type="5" bootable="false" label="EXT" size="1000000"> <extended order="1" type="47" label="RPM" size="1000" readonly="false"> <file name="rpm.mbn" offset="0"/> </extended> <extended order="2" type="46" label="TZ" size="1000" readonly="false"> <file name="tz.mbn" offset="0"/> </extended> </primary> </physical_partition> </image>需要用到eMMC Software Download工具来生成8660_msimage.mbn(版本366)
emmcswdownload.exe -f 8660_msimage.mbn -x partition_boot.xml -s 1G -g 4M
这里再给出用374生成正确8660_msimage.mbn的方法
需要制作一个partition_boot.xml,还要有提取的分区表partition0.bin
partition_boot.xml(不保证该文件的正确性,仅供参考,后果自负)
<?xml version="1.0" ?> <data> <!--NOTE: Sector size is 512bytes--> <program file_sector_offset="0" filename="" label="MODEM" num_partition_sectors="65536" physical_partition_number="0" size_in_KB="32768.0" start_sector="1"/> <program file_sector_offset="0" filename="sbl1.mbn" label="SBL1" num_partition_sectors="1000" physical_partition_number="0" size_in_KB="500.0" start_sector="65537"/> <program file_sector_offset="0" filename="sbl2.mbn" label="SBL2" num_partition_sectors="3000" physical_partition_number="0" size_in_KB="1500.0" start_sector="66537"/> <program file_sector_offset="0" filename="rpm.mbn" label="RPM" num_partition_sectors="1000" physical_partition_number="0" size_in_KB="500.0" start_sector="69559"/> <program file_sector_offset="0" filename="sbl3.mbn" label="SBL3" num_partition_sectors="4096" physical_partition_number="0" size_in_KB="2048.0" start_sector="70559"/> <program file_sector_offset="0" filename="emmc_appsboot.mbn" label="ABOOT" num_partition_sectors="5000" physical_partition_number="0" size_in_KB="2500.0" start_sector="74655"/> <program file_sector_offset="0" filename="" label="BOOT" num_partition_sectors="20480" physical_partition_number="0" size_in_KB="10240.0" start_sector="79655"/> <program file_sector_offset="0" filename="tz.mbn" label="TZ" num_partition_sectors="1000" physical_partition_number="0" size_in_KB="500.0" start_sector="100135"/> <program file_sector_offset="0" filename="pdl_phoneinfo.bin" label="INFO" num_partition_sectors="8192" physical_partition_number="0" size_in_KB="4096.0" start_sector="131072"/> <program file_sector_offset="0" filename="partition0.bin" label="MBR" num_partition_sectors="1" physical_partition_number="0" size_in_KB="0.5" start_sector="0"/> <program file_sector_offset="1" filename="partition0.bin" label="EXT" num_partition_sectors="22" physical_partition_number="0" size_in_KB="11.0" start_sector="69537"/> </data>
上面的filename后面的是要写到对应分区的文件,这个可以从手机对应分区中提取,也可以根据我的另一篇博文进行提取
需要注意的是已经证实mmcblk0p10中包含手机的NV信息,所以若是没有进行过备份的话,建议去除
<program file_sector_offset="0" filename="pdl_phoneinfo.bin" label="INFO" num_partition_sectors="8192" physical_partition_number="0" size_in_KB="4096.0" start_sector="131072"/>不过这样的话在p10损坏的情况下S/W模式下有可能不识别手机的机型(但还是可以启动的,若内核损坏只要在boot项中添加boot.img,即便system损坏,也只要在boot项中添加recovery.img就可以进入recovery来进行恢复)
也可以先在第一项中加入NON-HLOS.bin,防止无限重启,当然也可以不加,后面再进行恢复
生成mbn所需要的命令
emmcswdownload.exe -f 8660_msimage.mbn -x partition_boot.xml -s 16G
当然,这个文件你可以直接用小米的fastboot包中的8660_msimage.mbn,应该是可以通用的,它的作用是让手机启动到U盘模式,可以让我们直接对emmc进行访问读写
也可以尝试使用自行制作的8660_msimage.mbn,这样应该就能够直接启动到S/W模式或Fastboot模式下进行恢复分区表及分区了
rawprogram0.xml这个文件就需要个人根据手机的不同进行改写了,因为它是描述如何分区并在各个中写入什么文件的
当然,这个不可能凭空的写出来,可以根据
adb shell cat /proc/partitions
和
adb shell su -c "fdisk -l /dev/block/mmcblk0"
的结果来写
下面是备份完整partition0.bin,和分析它生成分区信息的脚本,强烈建议运行备份分区表,方便恢复
这个脚本应该支持所有/dev/block/mmcblk0的手机
是用Python语言写的,有些简陋,高手勿见笑
import os from struct import * def mbr(): global offset, partitions os.popen("adb shell su -c 'dd if=/dev/block/mmcblk0 of=/cache/partition0.bin bs=512 count=1'").close() os.popen("adb shell su -c 'cp /cache/partition0.bin /sdcard/partition0.bin'").close() os.popen("adb pull /sdcard/partition0.bin .").close() f = open("partition0.bin", 'rb') data = f.read() f.close() partitions = [ ] n=0 while True: buf = data[446+(16*n):446+(16*(n+1))] partition = dict(zip(('boot', 'id', 'start', 'size'), unpack('4I', buf))) partition['type'] = "MBR" n += 1 partition['no'] = n partitions.append(partition) if partition['id'] == 5: offset = partition['start'] break def ebr(): global offset, partitions n = 0 while True: a = 0 os.popen("adb shell su -c 'dd if=/dev/block/mmcblk0 of=/cache/ebr bs=512 count=1 skip=" + str(offset+n) + "\'").close() n += 1 os.popen("adb shell su -c 'dd if=/cache/ebr of=/cache/partition0.bin bs=512 count=1 seek=" + str(n) + "'").close() os.popen("adb shell su -c 'cp /cache/ebr /sdcard/partition0.bin'").close() os.popen("adb pull /sdcard/partition0.bin .").close() f = open("partition0.bin", 'rb') data = f.read() f.close() while True: buf = data[446+16*a:446+16*(a+1)] partition = dict(zip(('boot', 'id', 'start', 'size'), unpack('4I', buf))) if partition['id'] == 5: break if partition['id'] == 0: return partition['type'] = "EBR" partition['no'] = n partition['start'] += n-1+offset partitions.append(partition) a += 1 if __name__ == "__main__": mbr() ebr() os.popen("adb shell su -c 'cp /cache/partition0.bin /sdcard/partition0.bin'").close() os.popen("adb pull /sdcard/partition0.bin .").close() for part in partitions: print "%s %2i, Boot: 0x%02X, Id: 0x%02X, Start: 0x%08X (%8i), Size: 0x%08X (%8i, %8i KB)" % (part['type'], part['no'], part['boot'], part['id'], part['start'], part['start'], part['size'], part['size'], part['size']/2)
运行上面脚本可以得到partition0.bin和下列信息(IM-A820L):
EXT Start: 69537 MBR 1, Boot: 0x00, Id: 0x0C, Start: 0x00000001 ( 1), Size: 0x00010000 ( 65536, 32768 KB) MBR 2, Boot: 0x80, Id: 0x4D, Start: 0x00010001 ( 65537), Size: 0x000003E8 ( 1000, 500 KB) MBR 3, Boot: 0x00, Id: 0x51, Start: 0x000103E9 ( 66537), Size: 0x00000BB8 ( 3000, 1500 KB) MBR 4, Boot: 0x00, Id: 0x05, Start: 0x00010FA1 ( 69537), Size: 0x01D4905F (30707807, 15353903 KB) EBR 1, Boot: 0x00, Id: 0x47, Start: 0x00010FB7 ( 69559), Size: 0x000003E8 ( 1000, 500 KB) EBR 2, Boot: 0x00, Id: 0x45, Start: 0x0001139F ( 70559), Size: 0x00001000 ( 4096, 2048 KB) EBR 3, Boot: 0x00, Id: 0x4C, Start: 0x0001239F ( 74655), Size: 0x00001388 ( 5000, 2500 KB) EBR 4, Boot: 0x00, Id: 0x48, Start: 0x00013727 ( 79655), Size: 0x00005000 ( 20480, 10240 KB) EBR 5, Boot: 0x00, Id: 0x46, Start: 0x00018727 ( 100135), Size: 0x000003E8 ( 1000, 500 KB) EBR 6, Boot: 0x00, Id: 0x71, Start: 0x00020000 ( 131072), Size: 0x00002000 ( 8192, 4096 KB) EBR 7, Boot: 0x00, Id: 0x4A, Start: 0x00022000 ( 139264), Size: 0x00001800 ( 6144, 3072 KB) EBR 8, Boot: 0x00, Id: 0x4B, Start: 0x00023800 ( 145408), Size: 0x00001800 ( 6144, 3072 KB) EBR 9, Boot: 0x00, Id: 0x83, Start: 0x00040000 ( 262144), Size: 0x0012C000 ( 1228800, 614400 KB) EBR 10, Boot: 0x00, Id: 0x83, Start: 0x00180000 ( 1572864), Size: 0x00200000 ( 2097152, 1048576 KB) EBR 11, Boot: 0x00, Id: 0x83, Start: 0x00380000 ( 3670016), Size: 0x00004000 ( 16384, 8192 KB) EBR 12, Boot: 0x00, Id: 0x83, Start: 0x00384000 ( 3686400), Size: 0x00032000 ( 204800, 102400 KB) EBR 13, Boot: 0x00, Id: 0x83, Start: 0x003B6000 ( 3891200), Size: 0x00080000 ( 524288, 262144 KB) EBR 14, Boot: 0x00, Id: 0x60, Start: 0x00440000 ( 4456448), Size: 0x00005000 ( 20480, 10240 KB) EBR 15, Boot: 0x00, Id: 0x0C, Start: 0x00445000 ( 4476928), Size: 0x00019000 ( 102400, 51200 KB) EBR 16, Boot: 0x00, Id: 0x59, Start: 0x00460000 ( 4587520), Size: 0x00001800 ( 6144, 3072 KB) EBR 17, Boot: 0x00, Id: 0x5A, Start: 0x00461800 ( 4593664), Size: 0x00001800 ( 6144, 3072 KB) EBR 18, Boot: 0x00, Id: 0x5B, Start: 0x00463000 ( 4599808), Size: 0x00001800 ( 6144, 3072 KB) EBR 19, Boot: 0x00, Id: 0x58, Start: 0x00464800 ( 4605952), Size: 0x00001800 ( 6144, 3072 KB) EBR 20, Boot: 0x00, Id: 0x5D, Start: 0x00466000 ( 4612096), Size: 0x00000010 ( 16, 8 KB) EBR 21, Boot: 0x00, Id: 0x83, Start: 0x00466010 ( 4612112), Size: 0x0000A000 ( 40960, 20480 KB) EBR 22, Boot: 0x00, Id: 0x83, Start: 0x00470010 ( 4653072), Size: 0x018E9FEF (26124271, 13062135 KB)
根据上面的信息就可以改写rawprogram0.xml了
我再提供下我个人修改的rawprogram0.xml(IM-A820L)
<?xml version="1.0" ?> <data> <!--NOTE: Sector size is 512bytes--> <program file_sector_offset="0" filename="" label="MODEM" num_partition_sectors="65536" physical_partition_number="0" size_in_KB="32768.0" start_sector="1"/> <!--program file_sector_offset="0" filename="NON-HLOS.bin" label="MODEM" num_partition_sectors="65536" physical_partition_number="0" size_in_KB="32768.0" start_sector="1"/--> <program file_sector_offset="0" filename="" label="SBL1" num_partition_sectors="1000" physical_partition_number="0" size_in_KB="500.0" start_sector="65537"/> <program file_sector_offset="0" filename="sbl1.mbn" label="SBL1" num_partition_sectors="1000" physical_partition_number="0" size_in_KB="500.0" start_sector="65537"/> <program file_sector_offset="0" filename="" label="SBL2" num_partition_sectors="3000" physical_partition_number="0" size_in_KB="1500.0" start_sector="66537"/> <program file_sector_offset="0" filename="sbl2.mbn" label="SBL2" num_partition_sectors="3000" physical_partition_number="0" size_in_KB="1500.0" start_sector="66537"/> <program file_sector_offset="0" filename="" label="RPM" num_partition_sectors="1000" physical_partition_number="0" size_in_KB="500.0" start_sector="69559"/> <program file_sector_offset="0" filename="rpm.mbn" label="RPM" num_partition_sectors="1000" physical_partition_number="0" size_in_KB="500.0" start_sector="69559"/> <program file_sector_offset="0" filename="" label="SBL3" num_partition_sectors="4096" physical_partition_number="0" size_in_KB="2048.0" start_sector="70559"/> <program file_sector_offset="0" filename="sbl3.mbn" label="SBL3" num_partition_sectors="4096" physical_partition_number="0" size_in_KB="2048.0" start_sector="70559"/> <program file_sector_offset="0" filename="" label="ABOOT" num_partition_sectors="5000" physical_partition_number="0" size_in_KB="2500.0" start_sector="74655"/> <program file_sector_offset="0" filename="emmc_appsboot.mbn" label="ABOOT" num_partition_sectors="5000" physical_partition_number="0" size_in_KB="2500.0" start_sector="74655"/> <program file_sector_offset="0" filename="" label="BOOT" num_partition_sectors="20480" physical_partition_number="0" size_in_KB="10240.0" start_sector="79655"/> <!--program file_sector_offset="0" filename="boot.img" label="BOOT" num_partition_sectors="20480" physical_partition_number="0" size_in_KB="10240.0" start_sector="79655"/--> <program file_sector_offset="0" filename="" label="TZ" num_partition_sectors="1000" physical_partition_number="0" size_in_KB="500.0" start_sector="100135"/> <program file_sector_offset="0" filename="tz.mbn" label="TZ" num_partition_sectors="1000" physical_partition_number="0" size_in_KB="500.0" start_sector="100135"/> <program file_sector_offset="0" filename="" label="INFO" num_partition_sectors="8192" physical_partition_number="0" size_in_KB="4096.0" start_sector="131072"/> <program file_sector_offset="0" filename="pdl_phoneinfo.bin" label="INFO" num_partition_sectors="8192" physical_partition_number="0" size_in_KB="4096.0" start_sector="131072"/> <program file_sector_offset="0" filename="" label="" num_partition_sectors="6144" physical_partition_number="0" size_in_KB="3072.0" start_sector="139264"/> <program file_sector_offset="0" filename="" label="" num_partition_sectors="6144" physical_partition_number="0" size_in_KB="3072.0" start_sector="145408"/> <program file_sector_offset="0" filename="" label="SYSTEM" num_partition_sectors="1228800" physical_partition_number="0" size_in_KB="614400.0" start_sector="262144"/> <!--program file_sector_offset="0" filename="system.img.ext4" label="SYSTEM" num_partition_sectors="1228800" physical_partition_number="0" size_in_KB="614400.0" start_sector="262144"/--> <program file_sector_offset="0" filename="" label="USERDATA" num_partition_sectors="2097152" physical_partition_number="0" size_in_KB="1048576.0" start_sector="1572864"/> <!--program file_sector_offset="0" filename="userdata.img.ext4" label="USERDATA" num_partition_sectors="2097152" physical_partition_number="0" size_in_KB="1048576.0" start_sector="1572864"/--> <program file_sector_offset="0" filename="" label="PERSIST" num_partition_sectors="16384" physical_partition_number="0" size_in_KB="8192.0" start_sector="3670016"/> <!--program file_sector_offset="0" filename="persist.img.ext4" label="PERSIST" num_partition_sectors="16384" physical_partition_number="0" size_in_KB="8192.0" start_sector="3670016"/--> <program file_sector_offset="0" filename="" label="CACHE" num_partition_sectors="204800" physical_partition_number="0" size_in_KB="102400.0" start_sector="3686400"/> <!--program file_sector_offset="0" filename="cache.img.ext4" label="CACHE" num_partition_sectors="204800" physical_partition_number="0" size_in_KB="102400.0" start_sector="3686400"/--> <program file_sector_offset="0" filename="" label="tombstones" num_partition_sectors="524288" physical_partition_number="0" size_in_KB="262144.0" start_sector="3891200"/> <program file_sector_offset="0" filename="" label="RECOVERY" num_partition_sectors="20480" physical_partition_number="0" size_in_KB="10240.0" start_sector="4456448"/> <!--program file_sector_offset="0" filename="recovery.img" label="RECOVERY" num_partition_sectors="20480" physical_partition_number="0" size_in_KB="10240.0" start_sector="4456448"/--> <program file_sector_offset="0" filename="" label="MDM" num_partition_sectors="102400" physical_partition_number="0" size_in_KB="51200.0" start_sector="4476928"/> <!--program file_sector_offset="0" filename="fat.bin" label="MDM" num_partition_sectors="102400" physical_partition_number="0" size_in_KB="51200.0" start_sector="4476928"/--> <program file_sector_offset="0" filename="" label="" num_partition_sectors="6144" physical_partition_number="0" size_in_KB="3072.0" start_sector="4587520"/> <program file_sector_offset="0" filename="" label="" num_partition_sectors="6144" physical_partition_number="0" size_in_KB="3072.0" start_sector="4593664"/> <program file_sector_offset="0" filename="" label="" num_partition_sectors="6144" physical_partition_number="0" size_in_KB="3072.0" start_sector="4599808"/> <program file_sector_offset="0" filename="" label="" num_partition_sectors="6144" physical_partition_number="0" size_in_KB="3072.0" start_sector="4605952"/> <program file_sector_offset="0" filename="" label="" num_partition_sectors="16" physical_partition_number="0" size_in_KB="8.0" start_sector="4612096"/> <program file_sector_offset="0" filename="" label="SKYLOG" num_partition_sectors="40960" physical_partition_number="0" size_in_KB="20480.0" start_sector="4612112"/> <program file_sector_offset="0" filename="" label="SDCARD" num_partition_sectors="26124271" physical_partition_number="0" size_in_KB="2147483647.0" start_sector="4653072"/> <program file_sector_offset="0" filename="partition0.bin" label="MBR" num_partition_sectors="1" physical_partition_number="0" size_in_KB="0.5" start_sector="0"/> <program file_sector_offset="1" filename="partition0.bin" label="EXT" num_partition_sectors="22" physical_partition_number="0" size_in_KB="11.0" start_sector="69537"/> </data>其中num_partition_sectors是Size括号里的第一个数值,size_in_KB是第二个数值了,start_sector就是Start
最后关于partition0.bin的项里,MBR项一般不用改,EXT项num_partition_sectors是逻辑分区数就是EBR数,size_in_KB就是它的一半,start_sector就是MBR 4那一项的Start,需要注意的是两项的size_in_KB加起来就是partition0.bin的大小
最后,把这些个文件,还有partition.xml或rawprogram0.xml中用到的文件放到同一文件夹中
以下运行版本均为374
运行eMMC Software Download工具
点击Browse选择手机对应的端口,当然需要先在QPST Configuration中添加对应端口
Flash Programmer file name 中填MPRG8660.hex
Boot Image中填8660_msimage.mbn
去掉Program MMC device的勾选
勾选Search path 2并填入或选择文件所在目录
最后,点击Download吧
若是使用的是小米的2个文件,成功的话应该会将手机启动到U盘模式
此时便可随意操作手机的eMMC了
之后,最简单的恢复方法:若是有mmcblk0前面几十兆的备份,此时就可以直接到Linux环境下(或在windows下用一些工具)直接写回去,而不用管分区到底是怎样的
这里给出一些命令范例
首先是备份,这里就姑且以备份100M为例吧(注意:一定要用自己手机备份的版本,以免覆盖手机内原有各种IMEI之类的特有信息)
adb shell su -c 'dd if=/dev/block/mmcblk0 of=/sdcard/mmcblk0.img bs=512 count=200000若是没有备份,必须得用别人的备份,也要在启动到U盘模式后进行备份
Linux下
dd if=/dev/sdX of=mmcblk0.img bs=512 count=200000Windows下(也以windows版dd为例)
dd if=\\?\Device\HarddiskX\Partition0 of=mmcblk0.img bs=512 count=200000
恢复(警告:不熟悉者勿要乱用,否则把电脑硬盘数据都破坏了)
Linux下
dd if=mmcblk0.img of=/dev/sdX bs=512 count=200000
Windows下
dd if=mmcblk0.img of=\\?\Device\HarddiskX\Partition0 bs=512 count=200000
选中代表手机的那项,载入rawprogram0.xml点Download
转载请注明出处:http://blog.csdn.net/su_ky/article/details/7773273