b.liu | e958203 | 2025-04-17 19:18:16 +0800 | [diff] [blame] | 1 | #!/usr/bin/env python3 |
| 2 | |
| 3 | """ |
| 4 | Whole Flash Image Tag |
| 5 | |
| 6 | { |
| 7 | u32 crc32; |
| 8 | u32 version; |
| 9 | u32 chipID; |
| 10 | u32 flashType; |
| 11 | u32 flags; |
| 12 | } |
| 13 | |
| 14 | CRC32: Ethernet (Poly 0x04C11DB7) |
| 15 | |
| 16 | Version: |
| 17 | 0x00005700: Any version |
| 18 | 0x00005731: NAND 1MB data partition |
| 19 | 0x00005732: Normal version |
| 20 | |
| 21 | Chip ID: |
| 22 | Broadcom Chip ID |
| 23 | 0x00006328: BCM6328 |
| 24 | 0x00006362: BCM6362 |
| 25 | 0x00006368: BCM6368 |
| 26 | 0x00063268: BCM63268 |
| 27 | |
| 28 | Flash Type: |
| 29 | 1: NOR |
| 30 | 2: NAND 16k blocks |
| 31 | 3: NAND 128k blocks |
| 32 | 4: NAND 256k blocks |
| 33 | 5: NAND 512k blocks |
| 34 | 6: NAND 1MB blocks |
| 35 | 7: NAND 2MB blocks |
| 36 | |
| 37 | Flags: |
| 38 | 0x00000001: PMC |
| 39 | 0x00000002: Secure BootROM |
| 40 | |
| 41 | """ |
| 42 | |
| 43 | import argparse |
| 44 | import os |
| 45 | import struct |
| 46 | import binascii |
| 47 | |
| 48 | |
| 49 | def auto_int(x): |
| 50 | return int(x, 0) |
| 51 | |
| 52 | |
| 53 | def create_tag(args, in_bytes): |
| 54 | # JAM CRC32 is bitwise not and unsigned |
| 55 | crc = ~binascii.crc32(in_bytes) & 0xFFFFFFFF |
| 56 | tag = struct.pack( |
| 57 | ">IIIII", |
| 58 | crc, |
| 59 | args.tag_version, |
| 60 | args.chip_id, |
| 61 | args.flash_type, |
| 62 | args.flags, |
| 63 | ) |
| 64 | return tag |
| 65 | |
| 66 | |
| 67 | def create_output(args): |
| 68 | in_st = os.stat(args.input_file) |
| 69 | in_size = in_st.st_size |
| 70 | |
| 71 | in_f = open(args.input_file, "r+b") |
| 72 | in_bytes = in_f.read(in_size) |
| 73 | in_f.close() |
| 74 | |
| 75 | tag = create_tag(args, in_bytes) |
| 76 | |
| 77 | out_f = open(args.output_file, "w+b") |
| 78 | out_f.write(in_bytes) |
| 79 | out_f.write(tag) |
| 80 | out_f.close() |
| 81 | |
| 82 | |
| 83 | def main(): |
| 84 | global args |
| 85 | |
| 86 | parser = argparse.ArgumentParser(description="") |
| 87 | |
| 88 | parser.add_argument( |
| 89 | "--input-file", |
| 90 | dest="input_file", |
| 91 | action="store", |
| 92 | type=str, |
| 93 | help="Input file", |
| 94 | ) |
| 95 | |
| 96 | parser.add_argument( |
| 97 | "--output-file", |
| 98 | dest="output_file", |
| 99 | action="store", |
| 100 | type=str, |
| 101 | help="Output file", |
| 102 | ) |
| 103 | |
| 104 | parser.add_argument( |
| 105 | "--version", |
| 106 | dest="tag_version", |
| 107 | action="store", |
| 108 | type=auto_int, |
| 109 | help="WFI Tag Version", |
| 110 | ) |
| 111 | |
| 112 | parser.add_argument( |
| 113 | "--chip-id", |
| 114 | dest="chip_id", |
| 115 | action="store", |
| 116 | type=auto_int, |
| 117 | help="WFI Chip ID", |
| 118 | ) |
| 119 | |
| 120 | parser.add_argument( |
| 121 | "--flash-type", |
| 122 | dest="flash_type", |
| 123 | action="store", |
| 124 | type=auto_int, |
| 125 | help="WFI Flash Type", |
| 126 | ) |
| 127 | |
| 128 | parser.add_argument( |
| 129 | "--flags", dest="flags", action="store", type=auto_int, help="WFI Flags" |
| 130 | ) |
| 131 | |
| 132 | args = parser.parse_args() |
| 133 | |
| 134 | if not args.flags: |
| 135 | args.flags = 0 |
| 136 | |
| 137 | if ( |
| 138 | (not args.input_file) |
| 139 | or (not args.output_file) |
| 140 | or (not args.tag_version) |
| 141 | or (not args.chip_id) |
| 142 | or (not args.flash_type) |
| 143 | ): |
| 144 | parser.print_help() |
| 145 | else: |
| 146 | create_output(args) |
| 147 | |
| 148 | |
| 149 | main() |