cfe-partition-tag.py 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  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('--flags',
  54. dest='part_flags',
  55. action='store',
  56. type=auto_int,
  57. help='Partition Flags')
  58. parser.add_argument('--id',
  59. dest='part_id',
  60. action='store',
  61. type=auto_int,
  62. help='Partition ID')
  63. parser.add_argument('--input-file',
  64. dest='input_file',
  65. action='store',
  66. type=str,
  67. help='Input file')
  68. parser.add_argument('--output-file',
  69. dest='output_file',
  70. action='store',
  71. type=str,
  72. help='Output file')
  73. parser.add_argument('--name',
  74. dest='part_name',
  75. action='store',
  76. type=str,
  77. help='Partition Name')
  78. parser.add_argument('--version',
  79. dest='part_version',
  80. action='store',
  81. type=str,
  82. help='Partition Version')
  83. args = parser.parse_args()
  84. if ((not args.part_flags) or
  85. (not args.part_id) or
  86. (not args.input_file) or
  87. (not args.output_file) or
  88. (not args.part_name) or
  89. (not args.part_version)):
  90. parser.print_help()
  91. else:
  92. create_output(args)
  93. main()