docs(cp02): add documentation for new firmware utilities

- Document bin_to_txt_converter.py for binary to text conversion
  - Document txt_to_bin_converter.py for text to binary conversion
  - Document merge_encrypted_firmware.py for encrypted firmware merging
  - Add usage examples for all three new tools
This commit is contained in:
Ching L 2026-01-07 11:28:08 +08:00
parent 8f928a93e8
commit 40dcc0db8c
4 changed files with 326 additions and 0 deletions

View File

@ -71,6 +71,40 @@
- 支持多种芯片 ID 的引导加载程序变体 - 支持多种芯片 ID 的引导加载程序变体
- 输出签名的二进制文件和相关 JSON 元数据 - 输出签名的二进制文件和相关 JSON 元数据
### bin_to_txt_converter.py
- **功能**: 将二进制文件转换为文本格式
- **用法**: `python3 bin_to_txt_converter.py <input.bin> [output.txt]`
- **描述**:
- 将二进制文件(如 IUM转换为文本格式
- 按 4 字节块处理数据,转换为十六进制字符串
- 支持小端序字节序转换
- 输出文件包含 start/end 标记
- 未指定输出文件时自动生成文件名
### txt_to_bin_converter.py
- **功能**: 将文本格式转换回二进制文件
- **用法**: `python3 txt_to_bin_converter.py <input.txt> <output.bin>`
- **描述**:
- 将文本格式(如 ium11.txt转换回二进制文件
- 处理 8 字符十六进制字符串为 4 字节整数
- 写入前 63 个完整的 4 字节值
- 第 64 个值仅写入第一个字节
- 跳过 start/end 标记行
### merge_encrypted_firmware.py
- **功能**: 合成已加密的固件和 IUM 为最终 programmer 固件
- **用法**: `python3 merge_encrypted_firmware.py <base.bin> <encrypted.bin> <ium.bin> -o <output.bin>`
- **描述**:
- 合并 Base firmware (16KB)、加密固件 (最大 119KB) 和 IUM storage (256 bytes)
- 固件布局:
- 0x0000 - 0x4000: Base firmware
- 0x4000 - 0x1DC00: 加密用户固件
- 0x1DC00 - 0x1DD00: IUM storage
- 0x1DD00 - 0x1DD10: Metadata (16 bytes)
- 自动生成 metadata包含 blocks 和 last_block_size
- 显示完整的内存布局和校验信息
- IUM storage 包含 CRC8 和 CRC16 校验
## 使用示例 ## 使用示例
```bash ```bash
@ -98,4 +132,12 @@
python3 signer_new.py --firmware firmware.bin --output_dir ./output python3 signer_new.py --firmware firmware.bin --output_dir ./output
python3 signer_new.py --bootloader bootloader.bin --output_dir ./output --enable_swd python3 signer_new.py --bootloader bootloader.bin --output_dir ./output --enable_swd
python3 signer_new.py --firmware firmware.bin --bootloader bootloader.bin --output_dir ./output --boot_directly python3 signer_new.py --firmware firmware.bin --bootloader bootloader.bin --output_dir ./output --boot_directly
# 二进制与文本格式转换
python3 bin_to_txt_converter.py ium.bin # 自动生成输出文件名
python3 bin_to_txt_converter.py ium.bin ium_converted.txt # 指定输出文件
python3 txt_to_bin_converter.py ium11.txt ium11.bin # 文本转二进制
# 合成加密固件
python3 merge_encrypted_firmware.py base.bin encrypted.bin ium.bin -o programmer.bin
``` ```

100
CP02/bin_to_txt_converter.py Executable file
View File

@ -0,0 +1,100 @@
#!/usr/bin/env python3
"""
Binary to Text Converter for IUM files
Converts .bin files to .txt format matching ium11.txt structure
"""
import sys
import os
def bin_to_txt(bin_file_path, txt_file_path=None):
"""
Convert binary file to text format matching the ium11.txt structure
Args:
bin_file_path (str): Path to input binary file
txt_file_path (str): Path to output text file (optional)
Returns:
str: Path to generated text file
"""
if not os.path.exists(bin_file_path):
raise FileNotFoundError(f"Binary file not found: {bin_file_path}")
# Generate output filename if not provided
if txt_file_path is None:
base_name = os.path.splitext(bin_file_path)[0]
txt_file_path = f"{base_name}_converted.txt"
# Read binary file
try:
with open(bin_file_path, 'rb') as bin_file:
binary_data = bin_file.read()
except Exception as e:
raise Exception(f"Error reading binary file: {e}")
# Convert binary data to text format
try:
with open(txt_file_path, 'w') as txt_file:
# Write start marker
txt_file.write("start\n")
# Process binary data in 4-byte chunks (32-bit words)
for i in range(0, len(binary_data), 4):
chunk = binary_data[i:i+4]
# Pad with zeros if chunk is less than 4 bytes
if len(chunk) < 4:
chunk = chunk + b'\x00' * (4 - len(chunk))
# Convert to little-endian 32-bit hex value
hex_value = chunk[::-1].hex().upper() # Reverse bytes for little-endian
# Format as 8-character hex string
hex_value = hex_value.zfill(8)
# Write hex value
txt_file.write(f"{hex_value}\n")
# Write end marker
txt_file.write("end\n")
txt_file.write("\n")
return txt_file_path
except Exception as e:
raise Exception(f"Error writing text file: {e}")
def main():
"""Main function to handle command line arguments"""
if len(sys.argv) < 2:
print("Usage: python bin_to_txt_converter.py <input_bin_file> [output_txt_file]")
print("\nExample:")
print(" python bin_to_txt_converter.py ium11.bin")
print(" python bin_to_txt_converter.py ium11.bin ium11_converted.txt")
sys.exit(1)
bin_file_path = sys.argv[1]
txt_file_path = sys.argv[2] if len(sys.argv) > 2 else None
try:
output_path = bin_to_txt(bin_file_path, txt_file_path)
print(f"Successfully converted {bin_file_path} to {output_path}")
# Show file sizes for verification
bin_size = os.path.getsize(bin_file_path)
txt_size = os.path.getsize(output_path)
print(f"Binary file size: {bin_size} bytes")
print(f"Text file size: {txt_size} bytes")
except Exception as e:
print(f"Error: {e}")
sys.exit(1)
if __name__ == "__main__":
main()

View File

@ -0,0 +1,139 @@
#!/usr/bin/env python3
"""
合成已加密的固件和 IUM 为最终 programmer 固件
固件布局:
0x0000 - 0x4000: Base firmware (16KB)
0x4000 - 0x1DC00: 加密后的用户固件 (最大 119KB)
0x1DC00 - 0x1DD00: IUM storage (256 bytes)
0x1DD00 - 0x1DD10: Metadata (16 bytes)
IUM Storage 结构 (256 bytes):
Bytes 0-252: Modified IUM (253 bytes)
Byte 253: CRC8
Bytes 254-255: CRC16 (little-endian)
用法:
python3 merge_encrypted_firmware.py base.bin encrypted.bin ium_storage.bin -o output.bin
"""
import argparse
import struct
import sys
from pathlib import Path
# 常量定义
BASE_FIRMWARE_SIZE = 0x4000 # 16KB
USER_FIRMWARE_MAX_SIZE = 0x1DC00 # 119KB
IUM_STORAGE_SIZE = 0x100 # 256 bytes
METADATA_SIZE = 0x10 # 16 bytes
BASE_FIRMWARE_OFFSET = 0x0000
USER_FIRMWARE_OFFSET = 0x4000
IUM_OFFSET = 0x1DC00
METADATA_OFFSET = 0x1DD00
def main():
parser = argparse.ArgumentParser(
description='合成加密固件和IUM为最终programmer固件',
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog='''
示例:
%(prog)s base.bin encrypted_binary.bin ium.bin -o programmer.bin
输入文件说明:
base_firmware - Base firmware BIN 文件 (最大 16KB)
encrypted_binary - 已加密的固件 BIN 文件 (*_encrypted_binary.bin)
ium_storage - IUM storage 文件 (256 bytes, *_ium.bin)
'''
)
parser.add_argument('base_firmware', help='Base firmware BIN 文件 (最大 16KB)')
parser.add_argument('encrypted_binary', help='已加密的固件 BIN 文件')
parser.add_argument('ium_storage', help='IUM storage 文件 (256 bytes)')
parser.add_argument('-o', '--output', required=True, help='输出文件路径')
args = parser.parse_args()
# 检查文件是否存在
for filepath, name in [
(args.base_firmware, 'Base firmware'),
(args.encrypted_binary, 'Encrypted binary'),
(args.ium_storage, 'IUM storage')
]:
if not Path(filepath).exists():
print(f"错误: {name} 文件不存在: {filepath}")
sys.exit(1)
# 读取文件
base_firmware = Path(args.base_firmware).read_bytes()
encrypted_binary = Path(args.encrypted_binary).read_bytes()
ium_storage = Path(args.ium_storage).read_bytes()
# 验证大小
if len(base_firmware) > BASE_FIRMWARE_SIZE:
print(f"错误: Base firmware 最大 {BASE_FIRMWARE_SIZE} bytes (16KB), 实际 {len(base_firmware)} bytes")
sys.exit(1)
if len(encrypted_binary) > USER_FIRMWARE_MAX_SIZE:
print(f"错误: 加密固件最大 {USER_FIRMWARE_MAX_SIZE} bytes (119KB), 实际 {len(encrypted_binary)} bytes")
sys.exit(1)
if len(ium_storage) != IUM_STORAGE_SIZE:
print(f"错误: IUM storage 必须是 {IUM_STORAGE_SIZE} bytes (256), 实际 {len(ium_storage)} bytes")
sys.exit(1)
print("合成 Programmer 固件:")
print(f" Base firmware: {args.base_firmware} ({len(base_firmware)} bytes)")
print(f" Encrypted binary: {args.encrypted_binary} ({len(encrypted_binary)} bytes)")
print(f" IUM storage: {args.ium_storage} ({len(ium_storage)} bytes)")
print()
# 创建输出缓冲区 (填充 0xFF)
total_size = METADATA_OFFSET + METADATA_SIZE
output = bytearray([0xFF] * total_size)
# 复制 base firmware (0x0000)
output[BASE_FIRMWARE_OFFSET:BASE_FIRMWARE_OFFSET + len(base_firmware)] = base_firmware
# 复制加密固件 (0x4000)
output[USER_FIRMWARE_OFFSET:USER_FIRMWARE_OFFSET + len(encrypted_binary)] = encrypted_binary
# 复制 IUM storage (0x1DC00)
output[IUM_OFFSET:IUM_OFFSET + IUM_STORAGE_SIZE] = ium_storage
# 生成 metadata
blocks = len(encrypted_binary) // 256
last_block_size = len(encrypted_binary) % 256
# Metadata 结构: uint16_t blocks, uint8_t last_block_size, uint8_t reserved[13]
metadata = struct.pack('<HB', blocks, last_block_size) + bytes(13)
output[METADATA_OFFSET:METADATA_OFFSET + METADATA_SIZE] = metadata
# 写入输出文件
Path(args.output).write_bytes(output)
# 解析 IUM storage 中的 CRC
ium_crc8 = ium_storage[253]
ium_crc16 = ium_storage[254] | (ium_storage[255] << 8)
print("固件结构:")
print(f" Base firmware: 0x{BASE_FIRMWARE_OFFSET:04X} - 0x{BASE_FIRMWARE_OFFSET + len(base_firmware):04X} ({len(base_firmware)} bytes)")
print(f" Encrypted binary: 0x{USER_FIRMWARE_OFFSET:04X} - 0x{USER_FIRMWARE_OFFSET + len(encrypted_binary):04X} ({len(encrypted_binary)} bytes)")
print(f" IUM storage: 0x{IUM_OFFSET:04X} - 0x{IUM_OFFSET + IUM_STORAGE_SIZE:04X} ({IUM_STORAGE_SIZE} bytes)")
print(f" Metadata: 0x{METADATA_OFFSET:04X} - 0x{METADATA_OFFSET + METADATA_SIZE:04X} ({METADATA_SIZE} bytes)")
print()
print("Metadata 信息:")
print(f" Blocks: {blocks}")
print(f" Last block size: {last_block_size} bytes")
print(f" Total size: {blocks * 256 + last_block_size} bytes")
print()
print("IUM 校验:")
print(f" CRC8: 0x{ium_crc8:02X}")
print(f" CRC16: 0x{ium_crc16:04X}")
print()
print(f"✓ 输出文件: {args.output} ({len(output)} bytes)")
if __name__ == '__main__':
main()

View File

@ -0,0 +1,45 @@
#!/usr/bin/env python3
import sys
import struct
import re
def convert_txt_to_bin(txt_file, bin_file):
with open(txt_file, 'r', encoding='utf-8') as f:
lines = f.readlines()
with open(bin_file, 'wb') as f:
count = 0
for line in lines:
line = line.strip()
if line == 'start' or line == 'end' or not line:
continue
# Check if line contains only hex digits (8 characters)
if re.match(r'^[0-9A-Fa-f]{8}$', line):
hex_value = line
# Convert hex string to integer
int_value = int(hex_value, 16)
count += 1
# Write first 63 complete 4-byte integers
if count <= 63:
f.write(struct.pack('<I', int_value))
# For the 64th value, only write the first byte
elif count == 64:
f.write(struct.pack('<I', int_value)[:1])
break
if __name__ == "__main__":
if len(sys.argv) != 3:
print("Usage: python txt_to_bin_converter.py <input.txt> <output.bin>")
sys.exit(1)
txt_file = sys.argv[1]
bin_file = sys.argv[2]
try:
convert_txt_to_bin(txt_file, bin_file)
print(f"Successfully converted {txt_file} to {bin_file}")
except Exception as e:
print(f"Error: {e}")
sys.exit(1)