下面是一个完整的示例,展示了如何使用 zlib.crc32 函数和 quicklz 压缩算法来实现 qboot 文件的打包功能:
import os
import sys
import struct
import zlib
import time
import quicklz
def pack_qboot(bin_file, qboot_file, type_string, algo, algo2, part_name, fw_ver, prod_code):
with open(bin_file, 'rb') as f:
bin_data = f.read()
# 对文件进行4字节对齐,不足补零
align_value = 0
bin_data = bin_data + align_value.to_bytes(4-len(bin_data)%4,byteorder='big')
# 计算对齐后固件大小和固件 CRC32
firmware_size = len(bin_data)
firmware_crc32 = zlib.crc32(bin_data)
#print(firmware_size)
#print(firmware_crc32)
# 使用 quicklz 压缩数据
compressed_full_data = bytes()
bin_data_parts = [bin_data[i:i+4096] for i in range(0, len(bin_data), 4096)]
for part in bin_data_parts:
compressed_data = quicklz.compress(part)
compressedSize = len(compressed_data)
compressed_full_data = compressed_full_data + compressedSize.to_bytes(4, byteorder='big') + compressed_data
#print(compressed_data)
# 计算打包大小和打包 CRC32
pack_size = len(compressed_full_data)
pack_crc32 = zlib.crc32(compressed_full_data)
# 获取当前时间戳
timestamp = int(time.time())
# 计算 qboot 文件长度
qboot_len = pack_size + 120
# 准备包头数据
header_data = struct.pack('<4sHHI16s24s24sIIII', type_string.encode(), algo, algo2, timestamp, part_name.encode(), fw_ver.encode(), prod_code.encode(), pack_crc32, firmware_crc32, firmware_size, pack_size)
# 计算包头 CRC32
header_crc32 = zlib.crc32(header_data)
# 更新包头 CRC32
header_data = struct.pack('<4sHHI16s24s24sIIIII', type_string.encode(), algo, algo2, timestamp, part_name.encode(), fw_ver.encode(), prod_code.encode(), pack_crc32, firmware_crc32, firmware_size, pack_size, header_crc32)
#print(pack_crc32)
#print(header_data)
with open(qboot_file, 'wb') as f:
f.write(header_data)
f.write(compressed_full_data)
print(firmware_size)
print(pack_size)
print(prod_code)
print(fw_ver)
if __name__ == '__main__':
if len(sys.argv) != 9:
print('Usage: python qboot_pack.py input.bin output.qbt type_string algo algo2 part_name fw_ver prod_code')
sys.exit(1)
bin_file = sys.argv[1]
qboot_file = sys.argv[2]
type_string = sys.argv[3]
algo = int(sys.argv[4])
algo2 = int(sys.argv[5])
part_name = sys.argv[6]
fw_ver = sys.argv[7]
prod_code = sys.argv[8]
pack_qboot(bin_file, qboot_file, type_string, algo, algo2, part_name, fw_ver, prod_code)
上面的代码定义了一个名为 pack_qboot 的函数,用于将一个二进制文件打包成一个 qboot 文件。它接受多个参数,包括输入的二进制文件、输出的 qboot 文件、类型字符串、算法编号、分区名称、固件版本和产品代码等。
这个脚本还包含了一个主程序,用于在命令行中运行这个脚本。你可以使用以下命令来运行这个脚本:
python qboot_pack.py input.bin output.qbt RBL 1 2 my_part_name v1.0.0 my_product
其中 input.bin 是你要打包的二进制文件,output.qbt 是输出的 qboot 文件,其他参数分别表示类型字符串、算法编号、分区名称、固件版本和产品代码等。
你可以根据自己的需求修改这些代码,以实现更多的功能。
是的,在 Python 中,zlib.crc32 函数使用的是固定的初始多项式。这个多项式的值为 0xEDB88320,它是一个常用的 CRC32 多项式。
如果你想要使用不同的初始多项式来计算 CRC32,你可以使用其他库来实现这个功能。例如,你可以使用 crcmod 库来自定义 CRC32 多项式。你可以使用以下命令来安装这个库:
pip install crcmod
安装完成后,你可以在 pack_qboot 函数中使用 crcmod 库来计算 CRC32。下面是一个简单的示例,展示了如何使用自定义的初始多项式来计算 CRC32:
import crcmod
def pack_qboot(bin_file, qboot_file):
with open(bin_file, 'rb') as f:
bin_data = f.read()
# 使用 quicklz 压缩数据
compressed_data = quicklz.compress(bin_data)
# 计算打包大小和打包 CRC32
pack_size = len(compressed_data)
# 使用自定义的初始多项式计算 CRC32
crc32_func = crcmod.mkCrcFun(0x104C11DB7, initCrc=0, xorOut=0xFFFFFFFF)
pack_crc32 = crc32_func(compressed_data)
# 获取当前时间戳
timestamp = int(time.time())
# 计算 qboot 文件长度
qboot_len = pack_size + 28
# 准备包头数据
header_data = struct.pack('<IIIIIII', qboot_len, 0x00000000, firmware_size, pack_size, firmware_crc32, pack_crc32, timestamp)
# 计算包头 CRC32
header_crc32 = crc32_func(header_data)
with open(qboot_file, 'wb') as f:
f.write(header_data)
f.write(struct.pack('<I', header_crc32))
f.write(compressed_data)
上面的代码使用 crcmod.mkCrcFun 函数创建了一个自定义的 CRC32 函数。它传递了三个参数:初始多项式、初始 CRC 值和最终异或值。然后,它使用这个自定义的 CRC32 函数来计算压缩数据和包头数据的 CRC32 值。
你可以根据自己的需求修改这些代码,以实现更多的功能。
要在上述代码的基础上使用 quicklz 算法实现压缩功能,你需要安装 pyquicklz 库。你可以使用以下命令来安装这个库:
pip install pyquicklz
安装完成后,你可以在 pack_qboot 函数中使用 quicklz 库来实现压缩功能。下面是一个简单的示例,展示了如何在 pack_qboot 函数中使用 quicklz 压缩:
import quicklz
def pack_qboot(bin_file, qboot_file):
with open(bin_file, 'rb') as f:
bin_data = f.read()
# 使用 quicklz 压缩数据
compressed_data = quicklz.compress(bin_data)
# 计算 CRC32 校验值
crc32_value = zlib.crc32(compressed_data)
compressed_len = len(compressed_data)
qboot_len = compressed_len + 12
with open(qboot_file, 'wb') as f:
f.write(struct.pack('<III', qboot_len, 0x00000000, crc32_value))
f.write(compressed_data)
上面的代码使用 quicklz.compress 函数来实现 quicklz 压缩。它将二进制数据作为参数传递给 quicklz.compress 函数,然后获取压缩后的数据。
你可以根据自己的需求修改这些代码,以实现更多的功能。

Comments | NOTHING