泛泰SKYA850救砖原理与分区表解析[2013.6.3更新]
首先已知高通的CPU内固化了一段引导程序,在手机启动不了时会引导手机进入QHSUSB_DLOAD模式。
而我们可以通过QHSUSB_DLOAD模式向不能正常启动的砖机下载MPRG8064.hex和8064_msimage.mbn
MPRG8064.hex和8064_msimage.mbn这2个文件可以从小米2的线刷包中取得(CPU一样的话,就可以通用),它的作用是让不能正常启动的手机启动到U盘模式,并把内置存储器虚拟成U盘,这时我们可以向其写入分区表、启动分区等,让手机可以启动到刷机模式。
当然,写入全镜像也可以,但因为A850有26个分区,其中只有12个分区刷机时会更新,另外一些分区存有手机固有的IMEI码等信息,不能更新,因为我们没有这些分区的信息,一旦丢失就找不回来了,所以建议手机在正常的时候进行全分区备份,以备不时之需。
首先把binx解压成bin文件,再从bin文件中解压出img,放着备用。
Binx解压可以使用suky制作的解压工具。
Bin的解压可以使用suky制作的工具或我自己写的工具。
工具下载地址:
http://pan.baidu.com/share/link?shareid=575427&uk=3071575749
工具简易使用教程:
http://blog.csdn.net/benjaminwan/article/details/8854542
本文以A850K的S0837210为例来讲解,以下带你手工解析分区表,懒人可以直接使用上面的工具来解析。
一、制作救机镜像最简单的办法
从正常的手机中备份,进入临时recovery,执行以下命令
adb shell dd if=/dev/block/mmcblk0 of=/sdcard/partition0.img bs=512 count= 658432
适用于A850备份文件的大小:512x658432/1024/1024=321.5MB
为什么需要这个数值呢?因为这正好是分区表头+起始8个分区的存储长度。
如何计算出来呢?请耐心接着看。
二、主引导记录(MBR,MasterBoot Record)
手机的内置存储器,其存储方式类似与PC机的硬盘。所以也存在主引导记录
在PC机的硬盘中,主引导记录是位于磁盘最前边的一段引导代码。它负责操作系统对磁盘进行读写时,对分区合法性的判别、分区引导信息的定位。
主引导记录共占用512个字节,由主引导记录(446字节)、分区表(64字节)、结束标志(2字节)组成。如下表所示:
| 起始地址 | 结束地址 | 内容 | 说明 |
| 0x0000 | 0x0088 | 主引导程序 | 主引导记录 |
| 0x0089 | 0x01BD | 出错信息数据区 | |
| 0x01BE | 0x01CD | 分区项1(16字节) | 分区表 |
| 0x01CE | 0x01DD | 分区项2(16字节) | |
| 0x01DE | 0x01ED | 分区项3(16字节) | |
| 0x01EE | 0x01FD | 分区项4(16字节) | |
| 0x01FE | 0x01FF | 55 AA | 结束标志 |
但是在A850手机里的情况,情况稍有不同,
使用此命令在第三方recovery中,可以把分区表备份到内置存储根目录,文件大小5kb:
adb shell dd if=/dev/block/mmcblk0 of=/sdcard/partition0.img bs=512 count=10
如果连接PC时找不到备份的文件,可以用RE管理浏览到此目录,让后台媒体扫描优先找到这个文件。
现在用Winhex打开备份出来的文件,看一下手机内置存储头512字节:

可以看到本应该是主引导记录区的0x0000~0x01BD全为0,因为引导程序已固化在CPU中了,所以手机就不需要主引导记录了。
而唯一有数据的是0x01BE~0x01CD颜色标示部分,是分区表的第一项。
这一段数据为:0x 00 00 01 00 EE FF FF FF 01 00 00 00 FF FF FF FF
这段对于A850来说是固定的。
这是分区表项的定义:
| 存贮字节位 | 内容及含义 |
| 第1字节 | 引导标志。若值为80H表示活动分区,若值为00H表示非活动分区。 |
| 第2、3、4字节 | 本分区的起始磁头号、扇区号、柱面号。其中: |
| 磁头号——第2字节; | |
| 扇区号——第3字节的低6位; | |
| 柱面号——为第3字节高2位+第4字节8位。 | |
| 第5字节 | 分区类型符。GPT分区类型为EEH。这里是符合的。 |
| 00H——表示该分区未用(即没有指定); | |
| 06H——FAT16基本分区; | |
| 0BH——FAT32基本分区; | |
| 05H——扩展分区; | |
| 07H——NTFS分区; | |
| 0FH——(LBA模式)扩展分区(83H为Linux分区等)。 | |
| 第6、7、8字节 | 本分区的结束磁头号、扇区号、柱面号。其中: |
| 磁头号——第6字节; | |
| 扇区号——第7字节的低6位; | |
| 柱面号——第7字节的高2位+第8字节。 | |
| 第9、10、11、12字节 | 本分区之前已用了的扇区数。 |
| 第13、14、15、16字节 | 本分区的总扇区数。 |
后面的分区表项都为0。难道A850只有一个分区吗?不是的。
因为传统的MBR分区表只能容纳4个分区,4个主分区或几个主分区加1个扩展分区。
而随着时代的发展,出现了GPT分区表,相关知识请自行科普。
三、GPT表头
GPT分区表比MBR分区表支持更大容量的磁盘和分区,GPT分区表的结构中,每个逻辑块(LBA)为512字节,每个分区的记录为128字节。结构图参考如下:
GPT的标准出于兼容性考虑,硬盘的第一个扇区仍然用作MBR,之后才是GPT头。
那么就明白了,前512字节只是为了兼容MBR标准才保留的。
那么我们来看看GPT头,接下来的512字节,0x200~0x3FF:
代入表头格式来看:
| 起始 | 长度 | 内容解释 | 实际内容 | 实际内容 |
| 0 | 8字节 | 签名("EFI PART", 45 46 49 20 50 41 52 54) | 45 46 49 20 50 41 52 54 |
|
| 8 | 4字节 | 修订(在1.0版中,值是 00 00 01 00) | 00 00 01 00 |
|
| 12 | 4字节 | 分区表头的大小(单位是字节,通常是92字节,即 5C 00 00 00) | 5C 00 00 00 | 92 |
| 16 | 4字节 | 分区表头(第0-91字节)的CRC32校验,在计算时,把这个字段作为0处理,需要计算出分区串行的CRC32校验后再计算本字段 | 43 D9 A1 8E |
|
| 20 | 4字节 | 保留,必须是 0 | 00 00 00 00 | 0 |
| 24 | 8字节 | 当前LBA(这个分区表头的位置) | 01 00 00 00 00 00 00 00 | 1 |
| 32 | 8字节 | 备份LBA(另一个分区表头的位置) | FF EF D1 01 00 00 00 00 |
|
| 40 | 8字节 | 第一个可用于分区的LBA(主分区表的最后一个LBA + 1) | 22 00 00 00 00 00 00 00 |
|
| 48 | 8字节 | 最后一个可用于分区的LBA(备份分区表的第一个LBA − 1) | DE EF D1 01 00 00 00 00 |
|
| 56 | 16字节 | 硬盘GUID(在类UNIX系统中也叫UUID) | 32 1B 10 98 E2 BB F2 4B A0 6E 2B B3 3D 00 0C 20 |
|
| 72 | 8字节 | 分区表项的起始LBA(在主分区表中是2) | 02 00 00 00 00 00 00 00 | 2 |
| 80 | 4字节 | 分区表项的数量 | 1C 00 00 00 | 28 |
| 84 | 4字节 | 一个分区表项的大小(通常是128) | 80 00 00 00 | 128 |
| 88 | 4字节 | 分区串行的CRC32校验 | 46 17 03 AF |
|
| 92 | * | 保留,剩余的字节必须是0(对于512字节LBA的硬盘即是420个字节) |
|
|
对于A850,这个表头的内容也是固定的。
重点查看蓝色的部分,注意这里读法为小端序(little-endian),请自行科普,简单来讲就是每个字节(2个字符)倒过来读。
起始LBA为2,每个扇区为512(0x200)字节,那么2Hx200H=400H
那么我们转到400H这个地址。
四、分区表项
可以看到400H为第一个分区表项,长度为选中的部分,128字节
代入分区表项定义:
| 起始 | 长度 | 内容 | 实际内容 | 内容解释 |
| 0 | 16字节 | 分区类型GUID | A2 A0 D0 EB E5 B9 33 44 87 C0 68 B6 B7 26 99 C7 |
|
| 16 | 16字节 | 分区GUID | 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | 01代表分区号 |
| 32 | 8字节 | 起始LBA(小端序) | 00 00 02 00 00 00 00 00 | 4000000H |
| 40 | 8字节 | 末尾LBA | FF DB 04 00 00 00 00 00 | 9B7FE00H |
| 48 | 8字节 | 属性标签(如:60表示“只读”) | 08 00 00 00 00 00 00 00 |
|
| 56 | 72字节 | 分区名 | 6D 00 6F 00 64 00 65 00 6D 00 | modem |
重点查看起始LBA为20000H,每个扇区为512(200H)字节,那么20000Hx200H=4000000H
从分区名,可以看出第一个分区为modem。
那么我们转到4000000H这个地址,再打开从bin文件解压出来的1_NON-HLOS.img,可以发现内容是一样的。
需要注意的是第一分区的末尾LBA并没有与第二分区的起始LBA靠在一起,存在一部分间隙。
看第一分区的表头,有MSDOS5.0字样,这是FAT16格式的分区,是可读写的。想要查看modem分区的内容,可以在linux下加载modem分区的镜像来修改,详细教程请关注后续文章。
接下来查看第二个表项目,长度为选中的部分,128字节:
代入分区表项定义:
| 起始 | 长度 | 内容 | 实际内容 | 内容解释 |
| 0 | 16字节 | 分区类型GUID | 2C BA A0 DE DD CB 05 48 B4 F9 F4 28 25 1C 3E 98 |
|
| 16 | 16字节 | 分区GUID | 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | 02代表分区号 |
| 32 | 8字节 | 起始LBA(小端序) | 00 00 06 00 00 00 00 00 | C000000H |
| 40 | 8字节 | 末尾LBA | FF 0B 06 00 00 00 00 00 | C17FE00H |
| 48 | 8字节 | 属性标签(如:60表示“只读”) | 00 00 00 00 00 00 00 00 |
|
| 56 | 72字节 | 分区名 | 73 00 62 00 6C 00 31 00 | sbl1 |
重点查看起始LBA为60000H,每个扇区为512(200H)字节,那么60000Hx200H= C000000H
从分区名,可以看出第二个分区为sbl1。
那么我们转到C000000H这个地址,再打开从bin文件解压出来的2_SBL1.img,可以发现内容是一样的。
接下来查看第三个表项目,长度为选中的部分,128字节:
代入分区表项定义:
| 起始 | 长度 | 内容 | 实际内容 | 内容解释 |
| 0 | 16字节 | 分区类型GUID | AD 52 6B 8C 9E 8A 98 43 AD 09 AE 91 6E 53 AE 2D |
|
| 16 | 16字节 | 分区GUID | 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | 03代表分区号 |
| 32 | 8字节 | 起始LBA(小端序) | 00 0C 06 00 00 00 00 00 | C180000H |
| 40 | 8字节 | 末尾LBA | FF 17 06 00 00 00 00 00 | C2FFE00H |
| 48 | 8字节 | 属性标签(如:60表示“只读”) | 00 00 00 00 00 00 00 00 |
|
| 56 | 72字节 | 分区名 | 73 00 62 00 6C 00 32 00 | sbl2 |
重点查看起始LBA为60C00H,每个扇区为512(200H)字节,那么60C00Hx200H= C180000H
从分区名,可以看出第三个分区为sbl2。
同样的第二分区与第三分区之前也存在一定的间隙,这些间隙都是以0填充。
那么我们转到C000000H这个地址,再打开从bin文件解压出来的2_SBL2.img,可以发现内容是一样的。
接下来的解读方法是一样的,就不重复描述了。
最后,第九个表的起始LBA 为:A0C00H,转换为偏移地址为:A0C00H x200H= 14180000H
,这就是前8个分区占用的大小。把这个值除以512,得到658432。这就是为什么之前提到的备份长度是658432的原因了。
如何手工构建一份A850的分区表和启动分区镜像,读到这里,大家应该有个大概的思路了吧。
有一点需要注意,A850正式机和工程机的分区表稍有差别,但个人认为工程机只要备份了全分区表,即使改成正式机的分区表并重新全分区重新刷入后,应该也能正常使用。
简单点来讲,想要手工构建一个镜像可以:MBR+GTP表头+表项1~n+分区1数据+分区2数据+……
其中的间隙以0填充,每个数据段的起始地址正确就行了。
但现实是残酷的,不是每台砖机都有救砖资料,也不是每个机型都有救砖教程。
手头没有任何备份文件,怎么做出救砖用的镜像呢?
这里提醒一下,小心驶得万年船,在机子正常的时候,最好先在recovery中把分区表和启动区使用adb命令备份一下,其它的机型不知道该备份多大长度,请估摸着输入个大的数值吧。
五、从PHONEINFO镜像中取得分区表信息
刚才提到砖了以后才发现没有备份资料。咋办?找同类机型备份?也没有,咋办……
打开从bin文件中解压出来的12_PHONEINFO.img,并定位到200H处。
从关键字EFI PART,你就可以猜到这是GPT表头了,起始位置是234H。
然后从234H再往后偏移512字节(200H),因为GPT表头的长度为512。那么434H应该就是分区表项才对,看看猜得对不对。
果然猜对了。
再转到4433H,这个地址,你还能找到同样的分区表项,推测是备份用的。
再转到8434H,你还能找到一个EFI PART标志,但不是我们需要的数据。用途未知。
好了,分区表信息有了,分区资料也有了,动手能力强的就可以直接用Winhex构建救砖镜像了。
MBR表头固定512字节(可以从最前面的图复制)+GPT表头固定512字节(从phoneinfo复制)+分区表项+填充0直到modem分区的起始地址+modem分区内容+填充0直到sbl1分区的起始地址+sbl1分区的内容+……
要让A850能够启动,保险的话至少8个分区:modem、sbl1、sbl2、sbl3、aboot、rpm、boot、tz。
应该所有人都不希望采用这种麻烦的方法来制作救砖镜像吧,那就做好备份先。
这篇文章暂时探讨到此。
最后,你可能会好奇,MPRG8064.hex和8064_msimage.mbn到底是什么?为什么能够救砖。
Hex文件和cpu相关,可由高通开发平台编译得来,详情可参考:
http://blog.csdn.net/fyh2003/article/details/7754327
另外特别强调一点,锁了BL的手机,不可以用类似方法来救砖,下载的第一步就会收到警告提示。
而8064_msimage.mbn这个文件,把扩展名改为img,再用winhex或本人编写的工具打开。可以看到其实内部就是一个包含必要启动分区的最小系统。
那么小米2的线刷包,为何不把全镜像做成mbn呢?不就改个扩展名吗?
这里有2个原因:
1、 刷机时,并非每个分区都需要更新,有一些分区是不能刷新的,比如存有串号IMEI码的rawdata分区。
并且需要更新的分区并非都挨在一起,比如system和recovery一般都靠后,所以就没有办法做成一个连续的镜像来更新。
2、 为何不用emmcdownload直接把我们做好的恢复镜像直接刷进去,而要先刷个小米2的mbn文件让手机启动到u盘模式呢?
确实恢复镜像直接刷进去也是没错的,可行。但小米2的线刷为什么不采用这种方式呢。
Emmcdownlaod其实是通过usb模拟的串口向手机写入信息的,串口的速度大家都知道是多慢的,写个几mb的内容还好,写入大文件可就惨了,试想刷个机刷一天,谁受得了呢!
手机进入U盘模式后,就是通过usb来连接,速度就快了。
能看到这里,也真是不容易,好了,就说到这里。
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
