b.liu | e958203 | 2025-04-17 19:18:16 +0800 | [diff] [blame] | 1 | #!/usr/bin/env python3 |
| 2 | |
| 3 | """ |
| 4 | CFE Partition Tag |
| 5 | |
| 6 | { |
| 7 | u32 part_id; |
| 8 | u32 part_size; |
| 9 | u16 flags; |
| 10 | char part_name[33]; |
| 11 | char part_version[21]; |
| 12 | u32 part_crc32; |
| 13 | } |
| 14 | |
| 15 | """ |
| 16 | |
| 17 | import argparse |
| 18 | import os |
| 19 | import struct |
| 20 | import binascii |
| 21 | |
| 22 | |
| 23 | PART_NAME_SIZE = 33 |
| 24 | PART_VERSION_SIZE = 21 |
| 25 | |
| 26 | |
| 27 | def auto_int(x): |
| 28 | return int(x, 0) |
| 29 | |
| 30 | |
| 31 | def str_to_bytes_pad(string, size): |
| 32 | str_bytes = string.encode() |
| 33 | num_bytes = len(str_bytes) |
| 34 | if num_bytes >= size: |
| 35 | str_bytes = str_bytes[: size - 1] + "\0".encode() |
| 36 | else: |
| 37 | str_bytes += "\0".encode() * (size - num_bytes) |
| 38 | return str_bytes |
| 39 | |
| 40 | |
| 41 | def create_tag(args, in_bytes, size): |
| 42 | # JAM CRC32 is bitwise not and unsigned |
| 43 | crc = ~binascii.crc32(in_bytes) & 0xFFFFFFFF |
| 44 | |
| 45 | tag = bytearray() |
| 46 | tag += struct.pack(">I", args.part_id) |
| 47 | tag += struct.pack(">I", size) |
| 48 | tag += struct.pack(">H", args.part_flags) |
| 49 | tag += str_to_bytes_pad(args.part_name, PART_NAME_SIZE) |
| 50 | tag += str_to_bytes_pad(args.part_version, PART_VERSION_SIZE) |
| 51 | tag += struct.pack(">I", crc) |
| 52 | |
| 53 | return tag |
| 54 | |
| 55 | |
| 56 | def create_output(args): |
| 57 | in_st = os.stat(args.input_file) |
| 58 | in_size = in_st.st_size |
| 59 | |
| 60 | in_f = open(args.input_file, "r+b") |
| 61 | in_bytes = in_f.read(in_size) |
| 62 | in_f.close() |
| 63 | |
| 64 | tag = create_tag(args, in_bytes, in_size) |
| 65 | |
| 66 | out_f = open(args.output_file, "w+b") |
| 67 | out_f.write(tag) |
| 68 | out_f.close() |
| 69 | |
| 70 | |
| 71 | def main(): |
| 72 | global args |
| 73 | |
| 74 | parser = argparse.ArgumentParser(description="") |
| 75 | |
| 76 | parser.add_argument( |
| 77 | "--flags", |
| 78 | dest="part_flags", |
| 79 | action="store", |
| 80 | type=auto_int, |
| 81 | help="Partition Flags", |
| 82 | ) |
| 83 | |
| 84 | parser.add_argument( |
| 85 | "--id", |
| 86 | dest="part_id", |
| 87 | action="store", |
| 88 | type=auto_int, |
| 89 | help="Partition ID", |
| 90 | ) |
| 91 | |
| 92 | parser.add_argument( |
| 93 | "--input-file", |
| 94 | dest="input_file", |
| 95 | action="store", |
| 96 | type=str, |
| 97 | help="Input file", |
| 98 | ) |
| 99 | |
| 100 | parser.add_argument( |
| 101 | "--output-file", |
| 102 | dest="output_file", |
| 103 | action="store", |
| 104 | type=str, |
| 105 | help="Output file", |
| 106 | ) |
| 107 | |
| 108 | parser.add_argument( |
| 109 | "--name", |
| 110 | dest="part_name", |
| 111 | action="store", |
| 112 | type=str, |
| 113 | help="Partition Name", |
| 114 | ) |
| 115 | |
| 116 | parser.add_argument( |
| 117 | "--version", |
| 118 | dest="part_version", |
| 119 | action="store", |
| 120 | type=str, |
| 121 | help="Partition Version", |
| 122 | ) |
| 123 | |
| 124 | args = parser.parse_args() |
| 125 | |
| 126 | if ( |
| 127 | (not args.part_flags) |
| 128 | or (not args.part_id) |
| 129 | or (not args.input_file) |
| 130 | or (not args.output_file) |
| 131 | or (not args.part_name) |
| 132 | or (not args.part_version) |
| 133 | ): |
| 134 | parser.print_help() |
| 135 | else: |
| 136 | create_output(args) |
| 137 | |
| 138 | |
| 139 | main() |