cfe-partition-tag.py 2.6 KB

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