pack_app_image.py 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. #!/usr/bin/env python3
  2. #
  3. # Build Actions NVRAM config binary file
  4. #
  5. # Copyright (c) 2017 Actions Semiconductor Co., Ltd
  6. #
  7. # SPDX-License-Identifier: Apache-2.0
  8. #
  9. import os
  10. import sys
  11. import struct
  12. import array
  13. import argparse
  14. import zlib
  15. import configparser
  16. from ctypes import *;
  17. BINARY_BLOCK_SIZE_ALIGN = 512
  18. IMAGE_HEAD_SIZE = 512
  19. def boot_padding(filename, align = BINARY_BLOCK_SIZE_ALIGN):
  20. fsize = os.path.getsize(filename)
  21. if fsize % align:
  22. padding_size = align - (fsize % align)
  23. print('fsize %d, padding_size %d' %(fsize, padding_size))
  24. with open(filename, 'rb+') as f:
  25. f.seek(fsize, 0)
  26. buf = (c_byte * padding_size)();
  27. f.write(buf)
  28. f.close()
  29. def img_header_add(img_bin_f):
  30. """
  31. check img header, and add h_img_size
  32. """
  33. img_len = os.path.getsize(img_bin_f)
  34. print('img origin length %d' %(img_len))
  35. if img_len % 4:
  36. boot_padding(img_bin_f, 4)
  37. img_len = os.path.getsize(img_bin_f)
  38. print('img align 4 length %d' %(img_len))
  39. with open(img_bin_f, 'rb+') as f:
  40. f.seek(IMAGE_HEAD_SIZE, 0)
  41. data = f.read(8)
  42. i_sp,i_run_addr = struct.unpack('II',data)
  43. print('i_run_addr 0x%x.' %i_run_addr)
  44. f.seek(0, 0)
  45. f.write(struct.pack('<I', 0x48544341))
  46. f.seek(4, 0)
  47. f.write(struct.pack('<I', 0x41435448))
  48. f.seek(8, 0)
  49. f.write(struct.pack('<I', i_run_addr))
  50. f.seek(0xc, 0)
  51. f.write(struct.pack('<s', b'boot'))
  52. f.seek(0x14, 0)
  53. f.write(struct.pack('<I', i_run_addr))
  54. h_img_size = img_len - IMAGE_HEAD_SIZE
  55. f.seek(0x18, 0)
  56. f.write(struct.pack('<I', h_img_size))
  57. f.seek(0x20, 0)
  58. f.write(struct.pack('<I', 0x0))
  59. f.seek(0x24, 0)
  60. f.write(struct.pack('<I', IMAGE_HEAD_SIZE))
  61. """
  62. h_ptlv_size = 0;
  63. """
  64. f.seek(0x26, 0)
  65. f.write(struct.pack('<h', 0))
  66. f.close()
  67. def image_calc_checksum(data):
  68. s = sum(array.array('I',data))
  69. s = s & 0xffffffff
  70. return s
  71. def image_add_cksum(filename, tlv_size):
  72. with open(filename, 'rb+') as f:
  73. f.seek(0, 0)
  74. data = f.read(48)
  75. h_magic0,h_magic1,h_load_addr,h_name,h_run_addr,h_img_size,h_img_chksum, h_hdr_chksum, \
  76. h_header_size,h_ptlv_size,h_tlv_size,h_version,h_flags \
  77. = struct.unpack('III8sIIIIHHHHI',data)
  78. if(h_magic0 != 0x48544341 or h_magic1 != 0x41435448):
  79. print('magic header check fail.')
  80. sys.exit(1)
  81. print('img header_size %d, img size=%d, ptlv_size=%d' %(h_header_size,h_img_size, h_ptlv_size))
  82. f.seek(h_header_size, 0)
  83. data = f.read(h_img_size)
  84. checksum = image_calc_checksum(data)
  85. checksum = 0xffffffff - checksum
  86. f.seek(0x1c, 0)
  87. f.write(struct.pack('<I', checksum))
  88. print('img checksum 0x%x.' %checksum)
  89. f.seek(0x28, 0)
  90. f.write(struct.pack('<H', tlv_size))
  91. f.seek(0x0, 0)
  92. data = f.read(h_header_size)
  93. checksum = image_calc_checksum(data)
  94. checksum = 0xffffffff - checksum
  95. f.seek(0x20, 0)
  96. f.write(struct.pack('<I', checksum))
  97. print('header checksum 0x%x.' %checksum)
  98. f.close()
  99. print('boot loader add cksum pass.')
  100. def bootloader_img_post_build(imge_name):
  101. print('bootloader image %s add header' % imge_name)
  102. with open(imge_name, 'rb+') as f:
  103. f.seek(0x0, 0)
  104. data = f.read(8)
  105. f.close()
  106. h_magic0,h_magic1= struct.unpack('II',data)
  107. if(h_magic0 == 0x48544341 and h_magic1 == 0x41435448) or (h_magic0 == 0x0 and h_magic1 == 0x0) :
  108. img_header_add(imge_name)
  109. image_add_cksum(imge_name, 0)
  110. boot_padding(imge_name)
  111. else:
  112. boot_padding(imge_name)
  113. print('bootloader %s not have header' % imge_name)
  114. sys.exit(1)
  115. def app_header_add(img_bin_f):
  116. """
  117. check img header, and add h_img_size
  118. """
  119. img_len = os.path.getsize(img_bin_f)
  120. print('app origin length %d' %(img_len))
  121. if img_len % 4:
  122. boot_padding(img_bin_f, 4)
  123. img_len = os.path.getsize(img_bin_f)
  124. print('img align 4 length %d' %(img_len))
  125. with open(img_bin_f, 'rb+') as f:
  126. f.seek(0, 0)
  127. data = f.read(8)
  128. i_sp,i_run_addr = struct.unpack('II',data)
  129. print('i_run_addr 0x%x.' %i_run_addr)
  130. f.seek(0x208, 0)
  131. f.write(struct.pack('<I', i_run_addr))
  132. f.seek(0x214, 0)
  133. f.write(struct.pack('<I', i_run_addr))
  134. f.seek(0x218, 0)
  135. f.write(struct.pack('<I', img_len))
  136. f.seek(0x21c, 0)
  137. f.write(struct.pack('<I', 0x0))
  138. f.seek(0x220, 0)
  139. f.write(struct.pack('<I', 0x0))
  140. f.seek(0x226, 0)
  141. f.write(struct.pack('<h', 0))
  142. f.seek(0x228, 0)
  143. f.write(struct.pack('<H', 0))
  144. f.close()
  145. def app_add_cksum(filename):
  146. with open(filename, 'rb+') as f:
  147. f.seek(0x200, 0)
  148. data = f.read(48)
  149. h_magic0,h_magic1,h_load_addr,h_name,h_run_addr,h_img_size,h_img_chksum, h_hdr_chksum, \
  150. h_header_size,h_ptlv_size,h_tlv_size,h_version,h_flags \
  151. = struct.unpack('III8sIIIIHHHHI',data)
  152. if(h_magic0 != 0x48544341 or h_magic1 != 0x41435448):
  153. print('app magic header check fail.')
  154. sys.exit(1)
  155. print('app header_size %d, img size=%d, ptlv_size=%d' %(h_header_size,h_img_size, h_ptlv_size))
  156. f.seek(0, 0)
  157. data = f.read(h_img_size)
  158. checksum = image_calc_checksum(data)
  159. checksum = 0xffffffff - checksum
  160. f.seek(0x21c, 0)
  161. f.write(struct.pack('<I', checksum))
  162. print('img checksum 0x%x.' %checksum)
  163. f.seek(0x200, 0)
  164. data = f.read(h_header_size)
  165. checksum = image_calc_checksum(data)
  166. checksum = 0xffffffff - checksum
  167. f.seek(0x220, 0)
  168. f.write(struct.pack('<I', checksum))
  169. print('app header checksum 0x%x.' %checksum)
  170. f.close()
  171. print('app add cksum pass.')
  172. def app_img_post_build(imge_name):
  173. print('app image %s add header' % imge_name)
  174. app_header_add(imge_name)
  175. app_add_cksum(imge_name)
  176. #boot_padding(imge_name)
  177. def boot_post_build(imge_name):
  178. with open(imge_name, 'rb+') as f:
  179. f.seek(0x200, 0)
  180. data = f.read(8)
  181. f.close()
  182. h_magic0,h_magic1= struct.unpack('II',data)
  183. if(h_magic0 != 0x48544341 or h_magic1 != 0x41435448):
  184. bootloader_img_post_build(imge_name)
  185. else:
  186. app_img_post_build(imge_name)
  187. def main(argv):
  188. boot_post_build(argv[1])
  189. if __name__ == "__main__":
  190. main(sys.argv)