feat(cp02): add firmware processing tools
- Add extract_firmware.sh for extracting firmware components from merged bins - Add merge_2323_firmware.sh for merging PA768 updater, firmware and IUM data - Add split_and_merge.sh for splitting firmware and creating 40W firmware - Add comprehensive README.md with usage documentation and examples
This commit is contained in:
commit
db8f25a518
43
CP02/README.md
Normal file
43
CP02/README.md
Normal file
@ -0,0 +1,43 @@
|
||||
# CP02 固件处理工具
|
||||
|
||||
## 文件说明
|
||||
|
||||
### split_and_merge.sh
|
||||
- **功能**: 切分固件文件并与 updater.bin 合并,用于制作 40W 固件
|
||||
- **用法**: `./split_and_merge.sh <待切分文件> <updater.bin路径> <输出文件名>`
|
||||
- **描述**:
|
||||
- 将输入固件文件切分为前面部分和最后256字节
|
||||
- 调用合并脚本生成最终固件
|
||||
- 自动删除最后1字节并检查文件大小限制
|
||||
|
||||
### merge_2323_firmware.sh
|
||||
- **功能**: 合并 PA768 updater、2323固件和IUM数据为单一固件文件
|
||||
- **用法**: `./merge_2323_firmware.sh -u <updater> -f <firmware> -i <ium> -o <output>`
|
||||
- **描述**:
|
||||
- 创建基础0xFF填充文件
|
||||
- 在指定偏移位置写入各组件
|
||||
- 生成固件元数据
|
||||
- 输出完整内存布局信息
|
||||
|
||||
### extract_firmware.sh
|
||||
- **功能**: 从合并的 bin 文件中提取 firmware、IUM 和 metadata
|
||||
- **用法**: `./extract_firmware.sh <merged_bin> [output_prefix]`
|
||||
- **描述**:
|
||||
- 从固定偏移位置提取 firmware (0x04000)
|
||||
- 提取 IUM 数据 (0x1dc00, 256 bytes)
|
||||
- 解析并生成 metadata.json (blocks 和 last_block_size)
|
||||
- 如未指定前缀,自动使用原文件名
|
||||
|
||||
## 使用示例
|
||||
|
||||
```bash
|
||||
# 切分并合并固件
|
||||
./split_and_merge.sh /Users/ching/Library/Containers/com.tencent.xinWeChat/Data/Documents/xwechat_files/looching_5217/msg/attach/61f8147fd472041d44f609e3618e827c/2025-12/Rec/ff6a18f4ab8db2a9/F/3/SW2303P_B_V1.0_00_D1F6_UFCS.bin ~/Downloads/固件/PA503_Updater.bin 40_ufcs2.bin
|
||||
|
||||
# 直接合并固件组件
|
||||
./merge_2323_firmware.sh -u PA768_Updater.bin -f 2323_firmware.bin -i 2323_ium.bin -o merged.bin
|
||||
|
||||
# 提取固件组件
|
||||
./extract_firmware.sh 40_ufcs2.bin firmware # 指定输出前缀
|
||||
./extract_firmware.sh merged.bin # 使用原文件名作为前缀
|
||||
```
|
||||
129
CP02/extract_firmware.sh
Executable file
129
CP02/extract_firmware.sh
Executable file
@ -0,0 +1,129 @@
|
||||
#!/bin/bash
|
||||
# 用法: ./extract_firmware.sh <merged_bin> [output_prefix]
|
||||
# 从合并的 bin 文件中提取 head file (firmware), tail file (IUM), 以及生成 metadata.json
|
||||
#
|
||||
# 文件布局:
|
||||
# 0x04000: firmware (head file)
|
||||
# 0x1dc00: IUM (tail file, 256 bytes)
|
||||
# 0x1dd00: metadata (blocks: uint16, last_block_size: uint8)
|
||||
|
||||
INPUT="$1"
|
||||
# 如果没有传 PREFIX,使用原文件名(去掉扩展名)
|
||||
if [ -n "$2" ]; then
|
||||
PREFIX="$2"
|
||||
else
|
||||
# 获取文件名(不含路径),然后去掉扩展名
|
||||
BASENAME=$(basename "$INPUT")
|
||||
PREFIX="${BASENAME%.*}"
|
||||
fi
|
||||
|
||||
if [ -z "$INPUT" ]; then
|
||||
echo "用法: $0 <merged_bin> [output_prefix]"
|
||||
echo "示例: $0 40_ufcs2.bin firmware"
|
||||
echo " $0 40_ufcs2.bin # 使用原文件名作为前缀"
|
||||
echo ""
|
||||
echo "输出文件:"
|
||||
echo " {prefix}.firmware - firmware 部分"
|
||||
echo " {prefix}.ium - IUM 部分 (256 bytes)"
|
||||
echo " {prefix}_metadata.json - 元数据"
|
||||
echo ""
|
||||
echo "注: 如果不指定 output_prefix,将使用原文件名(去掉扩展名)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$INPUT" ]; then
|
||||
echo "错误: 文件不存在: $INPUT"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 常量定义
|
||||
FIRMWARE_OFFSET=$((0x4000)) # 16384
|
||||
IUM_OFFSET=$((0x1dc00)) # 121856
|
||||
METADATA_OFFSET=$((0x1dd00)) # 122112
|
||||
IUM_SIZE=256
|
||||
|
||||
# 获取文件大小
|
||||
if stat --version >/dev/null 2>&1; then
|
||||
FILE_SIZE=$(stat -c%s "$INPUT") # Linux
|
||||
else
|
||||
FILE_SIZE=$(stat -f%z "$INPUT") # macOS
|
||||
fi
|
||||
|
||||
echo "输入文件: $INPUT"
|
||||
echo "文件大小: $FILE_SIZE bytes (0x$(printf '%x' $FILE_SIZE))"
|
||||
echo ""
|
||||
|
||||
# 读取 metadata (位于 0x1dd00)
|
||||
# 结构: uint16_t blocks (little-endian), uint8_t last_block_size
|
||||
echo "读取 metadata (offset 0x1dd00)..."
|
||||
|
||||
METADATA=$(dd if="$INPUT" bs=1 skip=$METADATA_OFFSET count=3 2>/dev/null | xxd -p)
|
||||
|
||||
if [ ${#METADATA} -lt 6 ]; then
|
||||
echo "错误: 无法读取 metadata"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 解析 little-endian uint16 (blocks) 和 uint8 (last_block_size)
|
||||
BLOCKS_LOW=$((16#${METADATA:0:2}))
|
||||
BLOCKS_HIGH=$((16#${METADATA:2:2}))
|
||||
BLOCKS=$(( BLOCKS_LOW + BLOCKS_HIGH * 256 ))
|
||||
LAST_BLOCK_SIZE=$((16#${METADATA:4:2}))
|
||||
|
||||
echo " blocks: $BLOCKS (0x$(printf '%04x' $BLOCKS))"
|
||||
echo " last_block_size: $LAST_BLOCK_SIZE (0x$(printf '%02x' $LAST_BLOCK_SIZE))"
|
||||
|
||||
# 计算 firmware 大小
|
||||
FIRMWARE_SIZE=$(( BLOCKS * 256 + LAST_BLOCK_SIZE ))
|
||||
echo " 计算出 firmware 大小: $FIRMWARE_SIZE bytes"
|
||||
echo ""
|
||||
|
||||
# 提取 head file (firmware: 从 0x4000 开始)
|
||||
HEAD_FILE="${PREFIX}.firmware"
|
||||
echo "提取 head file (firmware)..."
|
||||
dd if="$INPUT" of="$HEAD_FILE" bs=1 skip=$FIRMWARE_OFFSET count=$FIRMWARE_SIZE status=none
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
ACTUAL_HEAD_SIZE=$(stat -f%z "$HEAD_FILE" 2>/dev/null || stat -c%s "$HEAD_FILE" 2>/dev/null)
|
||||
echo " ✓ 已保存: $HEAD_FILE ($ACTUAL_HEAD_SIZE bytes)"
|
||||
else
|
||||
echo " ✗ 提取失败"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 提取 tail file (IUM: 从 0x1dc00 开始, 256 bytes)
|
||||
TAIL_FILE="${PREFIX}.ium"
|
||||
echo "提取 tail file (IUM)..."
|
||||
dd if="$INPUT" of="$TAIL_FILE" bs=1 skip=$IUM_OFFSET count=$IUM_SIZE status=none
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
ACTUAL_TAIL_SIZE=$(stat -f%z "$TAIL_FILE" 2>/dev/null || stat -c%s "$TAIL_FILE" 2>/dev/null)
|
||||
echo " ✓ 已保存: $TAIL_FILE ($ACTUAL_TAIL_SIZE bytes)"
|
||||
else
|
||||
echo " ✗ 提取失败"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 生成 metadata.json
|
||||
METADATA_FILE="${PREFIX}_metadata.json"
|
||||
echo "生成 metadata.json..."
|
||||
|
||||
cat > "$METADATA_FILE" << EOF
|
||||
{"blocks": "0x$(printf '%04x' $BLOCKS)", "lastBlockSize": "0x$(printf '%02x' $LAST_BLOCK_SIZE)"}
|
||||
EOF
|
||||
|
||||
echo " ✓ 已保存: $METADATA_FILE"
|
||||
echo ""
|
||||
|
||||
# 显示结果
|
||||
echo "========================================="
|
||||
echo "提取完成!"
|
||||
echo ""
|
||||
echo "输出文件:"
|
||||
echo " Head (firmware): $HEAD_FILE ($ACTUAL_HEAD_SIZE bytes)"
|
||||
echo " Tail (IUM): $TAIL_FILE ($ACTUAL_TAIL_SIZE bytes)"
|
||||
echo " Metadata: $METADATA_FILE"
|
||||
echo ""
|
||||
echo "Metadata 内容:"
|
||||
cat "$METADATA_FILE"
|
||||
echo ""
|
||||
188
CP02/merge_2323_firmware.sh
Executable file
188
CP02/merge_2323_firmware.sh
Executable file
@ -0,0 +1,188 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Function to show usage
|
||||
show_usage() {
|
||||
echo "Usage: $0 [OPTIONS]"
|
||||
echo ""
|
||||
echo "Options:"
|
||||
echo " -o, --output FILE Output file (default: 40w.bin)"
|
||||
echo " -u, --updater FILE PA768 Updater binary file"
|
||||
echo " -f, --firmware FILE 2323 firmware binary file"
|
||||
echo " -i, --ium FILE 2323 IUM binary file"
|
||||
echo " -h, --help Show this help message"
|
||||
echo ""
|
||||
echo "Example:"
|
||||
echo " $0 -u PA768_Updater.bin -f 2323_firmware.bin -i 2323_ium.bin -o output.bin"
|
||||
echo ""
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Default values
|
||||
OUTPUT_FILE="40w.bin"
|
||||
PA768_FILE=""
|
||||
FIRMWARE_FILE=""
|
||||
IUM_FILE=""
|
||||
|
||||
# Parse command line arguments
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
-o | --output)
|
||||
OUTPUT_FILE="$2"
|
||||
shift 2
|
||||
;;
|
||||
-u | --updater)
|
||||
PA768_FILE="$2"
|
||||
shift 2
|
||||
;;
|
||||
-f | --firmware)
|
||||
FIRMWARE_FILE="$2"
|
||||
shift 2
|
||||
;;
|
||||
-i | --ium)
|
||||
IUM_FILE="$2"
|
||||
shift 2
|
||||
;;
|
||||
-h | --help)
|
||||
show_usage
|
||||
;;
|
||||
*)
|
||||
echo "Unknown option: $1"
|
||||
show_usage
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Configuration
|
||||
MAX_LENGTH=0x1df00 # 122,624 bytes
|
||||
|
||||
# Convert hex to decimal for dd
|
||||
MAX_LENGTH_DEC=$((MAX_LENGTH)) # 122,624 bytes
|
||||
IUM_OFFSET=$((0x1dc00)) # 121,856 bytes
|
||||
METADATA_OFFSET=$((0x1dd00)) # 121,088 bytes
|
||||
|
||||
echo "Creating merged binary file: $OUTPUT_FILE"
|
||||
echo "Maximum file size: $MAX_LENGTH ($MAX_LENGTH_DEC bytes)"
|
||||
echo ""
|
||||
echo "Input files:"
|
||||
echo " PA768 Updater: ${PA768_FILE:-"(not specified)"}"
|
||||
echo " Firmware: ${FIRMWARE_FILE:-"(not specified)"}"
|
||||
echo " IUM: ${IUM_FILE:-"(not specified)"}"
|
||||
echo ""
|
||||
|
||||
# Step 1: Create initial file filled with 0xFF bytes
|
||||
echo "Step 1: Creating base file filled with 0xFF..."
|
||||
dd if=/dev/zero bs=1 count=$MAX_LENGTH_DEC 2>/dev/null | LC_ALL=C tr "\000" "\377" >"$OUTPUT_FILE"
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error: Failed to create base file"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Step 2: Write PA768_Updater.bin at offset 0 (entire file)
|
||||
echo "Step 2: Writing PA768_Updater.bin at offset 0..."
|
||||
if [ -n "$PA768_FILE" ] && [ -f "$PA768_FILE" ]; then
|
||||
UPDATER_SIZE=$(stat -f%z "$PA768_FILE" 2>/dev/null || stat -c%s "$PA768_FILE" 2>/dev/null)
|
||||
echo " Updater size: $UPDATER_SIZE bytes"
|
||||
dd if="$PA768_FILE" of="$OUTPUT_FILE" bs=1 conv=notrunc 2>/dev/null
|
||||
echo " ✓ PA768_Updater.bin written successfully"
|
||||
elif [ -n "$PA768_FILE" ]; then
|
||||
echo " ✗ Error: $PA768_FILE not found"
|
||||
exit 1
|
||||
else
|
||||
echo " - PA768_Updater.bin skipped (not specified)"
|
||||
fi
|
||||
|
||||
# Step 3: Write firmware at offset 0x4000 (16,384) - entire file
|
||||
echo "Step 3: Writing firmware at offset 0x4000..."
|
||||
if [ -n "$FIRMWARE_FILE" ] && [ -f "$FIRMWARE_FILE" ]; then
|
||||
# Get firmware file size first
|
||||
FIRMWARE_SIZE=$(stat -f%z "$FIRMWARE_FILE" 2>/dev/null || stat -c%s "$FIRMWARE_FILE" 2>/dev/null)
|
||||
|
||||
# Calculate blocks for 2323_firmware.bin
|
||||
BLOCK_SIZE=256
|
||||
FIRMWARE_BLOCKS=$((FIRMWARE_SIZE / BLOCK_SIZE))
|
||||
LAST_BLOCK_SIZE=$((FIRMWARE_SIZE % BLOCK_SIZE))
|
||||
|
||||
echo " Firmware size: $FIRMWARE_SIZE bytes"
|
||||
echo " Complete blocks: $FIRMWARE_BLOCKS"
|
||||
echo " Last block size: $LAST_BLOCK_SIZE bytes"
|
||||
|
||||
dd if="$FIRMWARE_FILE" of="$OUTPUT_FILE" bs=1 seek=16384 conv=notrunc 2>/dev/null
|
||||
echo " ✓ 2323_firmware.bin written successfully"
|
||||
|
||||
# Write metadata at 0x1dd00
|
||||
echo "Step 3a: Writing firmware metadata at offset 0x1dd00..."
|
||||
|
||||
# Create metadata structure using Python for reliable binary output
|
||||
python3 -c "
|
||||
import struct
|
||||
blocks = $FIRMWARE_BLOCKS
|
||||
last_size = $LAST_BLOCK_SIZE
|
||||
# struct UserFirmwareMetadata: uint16_t blocks, uint8_t last_block_size, uint8_t reserved[13]
|
||||
metadata = struct.pack('<HB13x', blocks, last_size) # little-endian uint16 + uint8 + 13 zero bytes
|
||||
with open('temp_metadata.bin', 'wb') as f:
|
||||
f.write(metadata)
|
||||
print(f' Metadata: blocks={blocks} (0x{blocks:04x}), last_block_size={last_size} (0x{last_size:02x})')
|
||||
"
|
||||
|
||||
# Write metadata to file
|
||||
dd if=temp_metadata.bin of="$OUTPUT_FILE" bs=1 seek=$METADATA_OFFSET conv=notrunc 2>/dev/null
|
||||
rm temp_metadata.bin
|
||||
echo " ✓ Firmware metadata written successfully"
|
||||
|
||||
elif [ -n "$FIRMWARE_FILE" ]; then
|
||||
echo " ✗ Error: $FIRMWARE_FILE not found"
|
||||
exit 1
|
||||
else
|
||||
echo " - Firmware skipped (not specified)"
|
||||
FIRMWARE_SIZE=0
|
||||
FIRMWARE_BLOCKS=0
|
||||
LAST_BLOCK_SIZE=0
|
||||
fi
|
||||
|
||||
# Step 4: Write IUM data at offset 0x1dc00 (121,856)
|
||||
echo "Step 4: Writing IUM data at offset 0x1dc00..."
|
||||
if [ -n "$IUM_FILE" ] && [ -f "$IUM_FILE" ]; then
|
||||
IUM_SIZE=$(stat -f%z "$IUM_FILE" 2>/dev/null || stat -c%s "$IUM_FILE" 2>/dev/null)
|
||||
echo " IUM size: $IUM_SIZE bytes"
|
||||
dd if="$IUM_FILE" of="$OUTPUT_FILE" bs=1 count=256 seek=$IUM_OFFSET conv=notrunc 2>/dev/null
|
||||
echo " ✓ 2323_ium.bin written successfully"
|
||||
elif [ -n "$IUM_FILE" ]; then
|
||||
echo " ✗ Error: $IUM_FILE not found"
|
||||
exit 1
|
||||
else
|
||||
echo " - IUM data skipped (not specified)"
|
||||
fi
|
||||
|
||||
# Verify final file size
|
||||
ACTUAL_SIZE=$(stat -f%z "$OUTPUT_FILE" 2>/dev/null || stat -c%s "$OUTPUT_FILE" 2>/dev/null)
|
||||
echo ""
|
||||
echo "Merge completed successfully!"
|
||||
echo "Output file: $OUTPUT_FILE"
|
||||
echo "Expected size: $MAX_LENGTH_DEC bytes"
|
||||
echo "Actual size: $ACTUAL_SIZE bytes"
|
||||
|
||||
if [ "$ACTUAL_SIZE" -eq "$MAX_LENGTH_DEC" ]; then
|
||||
echo "✓ File size matches expected length"
|
||||
else
|
||||
echo "⚠ Warning: File size mismatch"
|
||||
fi
|
||||
|
||||
# Show memory layout with firmware blocks
|
||||
echo ""
|
||||
echo "Memory Layout:"
|
||||
if [ -n "$PA768_FILE" ]; then
|
||||
echo " 0x00000 - varies: PA768_Updater.bin (entire file)"
|
||||
fi
|
||||
if [ -n "$FIRMWARE_FILE" ] && [ $FIRMWARE_SIZE -gt 0 ]; then
|
||||
FIRMWARE_END=$((16384 + FIRMWARE_SIZE))
|
||||
echo " 0x04000 - 0x$(printf '%x' $((FIRMWARE_END - 1))): 2323_firmware.bin ($FIRMWARE_SIZE bytes, $FIRMWARE_BLOCKS blocks + $LAST_BLOCK_SIZE bytes)"
|
||||
echo " 0x1dd00 - 0x1dd0f: Firmware metadata (blocks=$FIRMWARE_BLOCKS, last_block_size=$LAST_BLOCK_SIZE)"
|
||||
fi
|
||||
if [ -n "$IUM_FILE" ]; then
|
||||
echo " 0x1dc00 - 0x1dcff: 2323_ium.bin (256 bytes)"
|
||||
fi
|
||||
echo " Total size: $ACTUAL_SIZE bytes (0x$(printf '%x' $ACTUAL_SIZE))"
|
||||
|
||||
echo ""
|
||||
echo "Use 'hexdump -C $OUTPUT_FILE | grep 1dd00' to verify metadata"
|
||||
84
CP02/split_and_merge.sh
Executable file
84
CP02/split_and_merge.sh
Executable file
@ -0,0 +1,84 @@
|
||||
#!/usr/bin/env bash
|
||||
# 用法: ./split256_and_merge.sh <待切分文件> <updater.bin路径> <输出文件名>
|
||||
# 示例: ./split256_and_merge.sh /Users/ching/Downloads/4_SW2303P_B_V1.0_00_E5C3.bin ~/Downloads/PA503_Updater.bin 40_4.bin
|
||||
|
||||
input="$1"
|
||||
updater="$2"
|
||||
output="$3"
|
||||
|
||||
if [ -z "$input" ] || [ -z "$updater" ] || [ -z "$output" ]; then
|
||||
echo "用法: $0 <待切分文件> <updater.bin路径> <输出文件名>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 检查文件是否存在
|
||||
if [ ! -f "$input" ]; then
|
||||
echo "文件不存在: $input"
|
||||
exit 1
|
||||
fi
|
||||
if [ ! -f "$updater" ]; then
|
||||
echo "文件不存在: $updater"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 获取文件大小(兼容 Linux / macOS)
|
||||
if stat --version >/dev/null 2>&1; then
|
||||
size=$(stat -c%s "$input") # Linux
|
||||
else
|
||||
size=$(stat -f%z "$input") # macOS
|
||||
fi
|
||||
|
||||
if [ "$size" -lt 256 ]; then
|
||||
echo "文件太小 (<256 字节),无法切分"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
head_size=$((size - 256))
|
||||
|
||||
# 输出文件名
|
||||
head_file="${input}.head"
|
||||
tail_file="${input}.tail"
|
||||
|
||||
# 切分
|
||||
dd if="$input" of="$head_file" bs=1 count=$head_size status=none
|
||||
dd if="$input" of="$tail_file" bs=1 skip=$head_size status=none
|
||||
|
||||
echo "切分完成:"
|
||||
echo " 前面部分: $head_file ($head_size 字节)"
|
||||
echo " 最后部分: $tail_file (256 字节)"
|
||||
|
||||
# 调用 merge 脚本
|
||||
if ./merge_2323_firmware.sh -u "$updater" -f "$head_file" -i "$tail_file" -o "$output"; then
|
||||
echo "✅ 合并成功,输出文件: $output"
|
||||
|
||||
# 获取输出文件大小
|
||||
if stat --version >/dev/null 2>&1; then
|
||||
out_size=$(stat -c%s "$output") # Linux
|
||||
else
|
||||
out_size=$(stat -f%z "$output") # macOS
|
||||
fi
|
||||
|
||||
# 删除最后 1 字节
|
||||
if [ "$out_size" -gt 0 ]; then
|
||||
if command -v truncate >/dev/null 2>&1 && truncate -s $((out_size - 1)) "$output" 2>/dev/null; then
|
||||
echo "已删除最后 1 字节(使用 truncate)"
|
||||
else
|
||||
# 使用 dd 备用方案
|
||||
dd if="$output" of="${output}.tmp" bs=1 count=$((out_size - 1)) status=none && mv "${output}.tmp" "$output"
|
||||
echo "已删除最后 1 字节(使用 dd)"
|
||||
fi
|
||||
echo "最终文件大小: $(stat -c%s "$output" 2>/dev/null || stat -f%z "$output")"
|
||||
fi
|
||||
|
||||
# 检查是否 < 0x1df00
|
||||
final_size=$(stat -c%s "$output" 2>/dev/null || stat -f%z "$output")
|
||||
if [ "$final_size" -gt 122624 ]; then
|
||||
echo "⚠️ 警告: 文件大小仍然 >= 0x1df00 (当前 $final_size 字节)"
|
||||
fi
|
||||
|
||||
# 清理临时文件
|
||||
rm -f "$head_file" "$tail_file"
|
||||
echo "⚠️⚠️⚠️ Remember signing output file! ⚠️⚠️⚠️"
|
||||
else
|
||||
echo "合并失败,保留临时文件以便排查"
|
||||
fi
|
||||
Loading…
x
Reference in New Issue
Block a user