sercomm-kernel-header.py 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. #!/usr/bin/env python3
  2. """
  3. # SPDX-License-Identifier: GPL-2.0-or-later
  4. #
  5. # sercomm-kernel-header.py: Creates Sercomm kernel header
  6. #
  7. # Copyright © 2022 Mikhail Zhilkin
  8. """
  9. import argparse
  10. import binascii
  11. import os
  12. import struct
  13. KERNEL_HEADER_SIZE = 0x100
  14. PADDING = 0xff
  15. ROOTFS_FAKE_HEADER = "UBI#"
  16. def auto_int(x):
  17. return int(x, 0)
  18. def create_kernel_header(args):
  19. out_file = open(args.header_file, "wb")
  20. header = get_kernel_header(args)
  21. out_file.write(header)
  22. out_file.close()
  23. def get_kernel_header(args):
  24. header = bytearray([PADDING] * KERNEL_HEADER_SIZE)
  25. struct.pack_into('<L', header, 0xc, 0xffffff02)
  26. struct.pack_into('<L', header, 0x1c, 0x0)
  27. struct.pack_into('<L', header, 0x34, 0x0)
  28. struct.pack_into('<L', header, 0x10, args.kernel_offset)
  29. struct.pack_into('<L', header, 0x28, args.rootfs_offset)
  30. if (args.rootfs_file):
  31. if (args.rootfs_checking_size):
  32. rootfs_size = args.rootfs_checking_size
  33. else:
  34. rootfs_size = os.path.getsize(args.rootfs_file)
  35. buf = open(args.rootfs_file,'rb').read(rootfs_size)
  36. crc = binascii.crc32(buf) & 0xffffffff
  37. else:
  38. rootfs_size = len(ROOTFS_FAKE_HEADER)
  39. crc = binascii.crc32(str.encode(ROOTFS_FAKE_HEADER)) & \
  40. 0xffffffff
  41. struct.pack_into('<L', header, 0x2c, rootfs_size)
  42. struct.pack_into('<L', header, 0x30, crc)
  43. kernel_size = os.path.getsize(args.kernel_file)
  44. struct.pack_into('<L', header, 0x14, kernel_size)
  45. kernel_end_offset = args.kernel_offset + kernel_size
  46. struct.pack_into('<L', header, 0x4, kernel_end_offset)
  47. buf = open(args.kernel_file,'rb').read()
  48. crc = binascii.crc32(buf) & 0xffffffff
  49. struct.pack_into('<L', header, 0x18, crc)
  50. crc = binascii.crc32(header) & 0xffffffff
  51. struct.pack_into('<L', header, 0x8, crc)
  52. struct.pack_into('<L', header, 0x0, 0x726553)
  53. return header
  54. def main():
  55. global args
  56. parser = argparse.ArgumentParser(description='This script generates \
  57. a kernel header for the Sercomm mt7621 devices')
  58. parser.add_argument('--kernel-image',
  59. dest='kernel_file',
  60. action='store',
  61. type=str,
  62. help='Path to a Kernel binary image')
  63. parser.add_argument('--kernel-offset',
  64. dest='kernel_offset',
  65. action='store',
  66. type=auto_int,
  67. help='Kernel offset')
  68. parser.add_argument('--rootfs-offset',
  69. dest='rootfs_offset',
  70. action='store',
  71. type=auto_int,
  72. help='RootFS offset')
  73. parser.add_argument('--output-header',
  74. dest='header_file',
  75. action='store',
  76. type=str,
  77. help='Output kernel header file')
  78. parser.add_argument('--rootfs-image',
  79. dest='rootfs_file',
  80. action='store',
  81. type=str,
  82. help='Path to RootFS binary image (optional)')
  83. parser.add_argument('--rootfs-checking-size',
  84. dest='rootfs_checking_size',
  85. action='store',
  86. type=auto_int,
  87. help='Bytes count for CRC calculation (optional)')
  88. args = parser.parse_args()
  89. if ((not args.kernel_file) or
  90. (not args.kernel_offset) or
  91. (not args.rootfs_offset) or
  92. (not args.header_file)):
  93. parser.print_help()
  94. exit()
  95. create_kernel_header(args)
  96. main()