一些小技巧分享给大家,关于小米刷机的
- EDL 模式,即高通 9008 模式下,可以刷入更多内容,可参考:小米 Note 3 进 EDL (9008) 模式方法。可修复传感器、相机启动贼慢问题
- 线刷包解压后,在使用 MiFlash 刷机前,可以用「蘑菇 ROM 助手」进行 IMG 镜像 编辑:下载地址
- 第 2 点提到的软件,建议修改
cust.img
、userdata.img
,system.img
修改后有一定概率打包失败,不建议修改他,因为即便是修改了,系统 OTA 更新时也会覆盖掉 - 编辑
partition.xml
和rawprogram0.xml
可以刷入更多的分区,例如在 9008 下通过修改这两个文件,加入persist.img
可以修复传感器、陀螺仪等失效问题 - 编辑后需要执行
flash_gen_crc_list.py
和flash_gen_md5_list.py
两个文件进行校验值的生成。而flash_gen_crc_list.py
需要手动编辑并加入需要额外刷入的镜像及修正代码
flash_gen_crc_list.py
这个文件因为依赖了 flash_gen_resparsecount
这个程序,导致我们没法在 Windows 以及 Mac 上直接运行。
如果是 Windows 10 的用户可以打开 Ubuntu Linux For Windows 10,切换到 bash Ubuntu 命令行上,是可以正常的通过 python3
运行这个程序的。
否则,只能依靠虚拟机或者实体安装的 Linux 系统才能运行。
以下是修正的代码:
#!/usr/bin/env python
from __future__ import print_function
import binascii
import os
import struct
# sparse_file_list 及 unsparse_file_list 自行根据各自的线刷包调整
sparse_file_list = {
"cache": "cache.img",
"system": "system.img",
"cust": "cust.img",
"userdata": "userdata.img",
"persist": "persist.img"
}
unsparse_file_list = {
"xbl": "xbl.elf",
"xblbak": "xbl.elf",
"abl": "abl.elf",
"ablbak": "abl.elf",
"tz": "tz.mbn",
"tzbak": "tz.mbn",
"hyp": "hyp.mbn",
"hypbak": "hyp.mbn",
"rpm": "rpm.mbn",
"rpmbak": "rpm.mbn",
"pmic": "pmic.elf",
"pmicbak": "pmic.elf",
"devcfg": "devcfg.mbn",
"devcfgbak": "devcfg.mbn",
"storsec": "storsec.mbn",
"storsecbak": "storsec.mbn",
"bluetooth": "BTFM.bin",
"cmnlib": "cmnlib.mbn",
"cmnlibbak": "cmnlib.mbn",
"cmnlib64": "cmnlib64.mbn",
"cmnlib64bak": "cmnlib64.mbn",
"modem": "NON-HLOS.bin",
"dsp": "dspso.bin",
"keymaster": "keymaster.mbn",
"keymasterbak": "keymaster.mbn",
"logo": "logo.img",
"misc": "misc.img",
"recovery": "recovery.img",
"boot": "boot.img"
}
file_list = dict(unsparse_file_list, **sparse_file_list)
def gen_sparse_crc(path):
global crc
FH = open(path, 'rb')
header_bin = FH.read(28)
header = struct.unpack("<I4H4I", header_bin)
magic = header[0]
major_version = header[1]
minor_version = header[2]
file_hdr_sz = header[3]
chunk_hdr_sz = header[4]
blk_sz = header[5]
total_blks = header[6]
total_chunks = header[7]
image_checksum = header[8]
sparsecrc = 0
if magic != 0xED26FF3A:
print("%s: Magic should be 0xED26FF3A but is 0x%08X"
% (path, magic))
return 0
if major_version != 1 or minor_version != 0:
print("%s: I only know about version 1.0, but this is version %u.%u"
% (path, major_version, minor_version))
return 0
if file_hdr_sz != 28:
print("%s: The file header size was expected to be 28, but is %u."
% (path, file_hdr_sz))
return 0
if chunk_hdr_sz != 12:
print("%s: The chunk header size was expected to be 12, but is %u."
% (path, chunk_hdr_sz))
return 0
print("%s: Total of %u %u-byte output blocks in %u input chunks."
% (path, total_blks, blk_sz, total_chunks))
if image_checksum != 0:
print("checksum=0x%08X" % image_checksum)
offset = 0
for i in range(1, total_chunks + 1):
header_bin = FH.read(12)
header = struct.unpack("<2H2I", header_bin)
chunk_type = header[0]
reserved1 = header[1]
chunk_sz = header[2]
total_sz = header[3]
data_sz = total_sz - 12
if chunk_type == 0xCAC1:
if data_sz != (chunk_sz * blk_sz):
print("Raw chunk input size (%u) does not match output size (%u)"
% (data_sz, chunk_sz * blk_sz))
break
else:
sparsecrc = binascii.crc32(FH.read(data_sz), sparsecrc)
elif chunk_type == 0xCAC2:
if data_sz != 4:
print("Fill chunk should have 4 bytes of fill, but this has %u"
% (data_sz), end="")
break
else:
fill_bin = FH.read(4)
fill = struct.unpack("<I", fill_bin)
print("Fill with 0x%08X" % (fill))
fill_buf = [fill] * (blk_sz / data_sz)
# Python 3 没有 xrange,用 range 代替
for j in range(1, chunk_sz + 1):
sparsecrc = binascii.crc32(fill_buf, sparsecrc)
elif chunk_type == 0xCAC3:
if data_sz != 0:
print("Don't care chunk input size is non-zero (%u)" % (data_sz))
break
elif chunk_type == 0xCAC4:
if data_sz != 4:
print("CRC32 chunk should have 4 bytes of CRC, but this has %u"
% (data_sz), end="")
break
else:
crc_bin = FH.read(4)
crc = struct.unpack("<I", crc)
print("Unverified CRC32 0x%08X" % crc)
else:
print("Unknown chunk type 0x%04X" % chunk_type, end="")
break
offset += chunk_sz
return sparsecrc
def gen_crc(file_path):
f = open(file_path, "rb")
crc = binascii.crc32(f.read())
return crc
def get_sparse_count(cmd):
line = os.popen(cmd, 'r').readline()
if line[0] == 'I' or line[0] == 'i':
return -1
return int(line)
# ------------------------------------------------------------------------------
if __name__ == "__main__":
thispath = os.path.dirname(__file__)
path = os.path.join(thispath, 'images')
crclist = os.path.join(path, 'crclist.txt')
sparsecrclist = os.path.join(path, 'sparsecrclist.txt')
max_download_size = 512 * 1024 * 1024
crc = 0
try:
fs = open(sparsecrclist, 'w')
f = open(crclist, 'w')
fs.write("SPARSECRC-LIST\n")
f.write("CRC-LIST\n")
for ptn in file_list:
filepath = os.path.join(path, file_list[ptn])
print(filepath)
if not os.path.isfile(filepath):
print(filepath + ' doesn\'t exist, skip it')
continue
# has_key 废弃,用 in 代替
if ptn in unsparse_file_list:
crc = gen_crc(filepath)
if crc:
f.write(ptn + ' ' + hex(crc & (2 ** 32 - 1)) + '\n')
else:
size = os.path.getsize(filepath)
if size < max_download_size:
crc = gen_crc(filepath)
if crc:
f.write(ptn + ' ' + hex(crc & (2 ** 32 - 1)) + '\n')
else:
# need get the sparsecount
cmdarg = './flash_gen_resparsecount' + ' -S ' + str(max_download_size) + ' ' + filepath
cmd = os.path.join(thispath, cmdarg)
count = get_sparse_count(cmd)
if count > 0:
countstr = str(count)
crc = gen_sparse_crc(filepath)
if crc:
fs.write(ptn + ' ' + hex(crc & (2 ** 32 - 1)) + ' ' + countstr + '\n')
# except Exception, e,逗号修改为 as
except Exception as e:
os.remove(crclist)
os.remove(sparsecrclist)
raise