1# SPDX-License-Identifier: Apache-2.0 2# 3# Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 4# Author: Dylan Hsieh <dylan.hsieh@realtek.com> 5 6""" 7The RTS5912 specific image header shows the bootROM how to 8load the image from flash to internal SRAM, this script obtains 9the header to original BIN and output a new BIN file. 10""" 11 12import argparse 13import os 14import struct 15 16IMAGE_MAGIC = 0x524C544B # ASCII 'RLTK' 17IMAGE_HDR_SIZE = 32 18RAM_LOAD = 0x0000020 19FREQ_50M = 0 20FREQ_25M = 1 21FREQ_12P5M = 2 22FREQ_6P25M = 3 23NORMAL_read = "0x03" 24DUAL_read = "0x3B" 25QUAD_read = "0x6B" 26 27 28def parse_args(): 29 """ 30 Parsing the arguments 31 """ 32 parser = argparse.ArgumentParser(allow_abbrev=False) 33 34 parser.add_argument( 35 "-L", 36 "--load-addr", 37 type=int, 38 dest="load_addr", 39 help="Load address for image when it should run from RAM.", 40 ) 41 42 parser.add_argument( 43 "-I", 44 "--input", 45 type=str, 46 dest="original_bin", 47 default="zephyr.bin", 48 help="Input bin file path", 49 ) 50 51 parser.add_argument( 52 "-O", 53 "--output", 54 type=str, 55 dest="signed_bin", 56 default="zephyr.rts5912.bin", 57 help="Output bin file path", 58 ) 59 60 parser.add_argument( 61 "-F", 62 "--spi-freq", 63 type=int, 64 dest="spi_freq", 65 choices=[FREQ_50M, FREQ_25M, FREQ_12P5M, FREQ_6P25M], 66 default=FREQ_6P25M, 67 help="Specify the frequency of SPI I/F.", 68 ) 69 70 parser.add_argument( 71 "-R", 72 "--spi-rdcmd", 73 type=str, 74 dest="spi_rdcmd", 75 choices=[NORMAL_read, DUAL_read, QUAD_read], 76 default=NORMAL_read, 77 help="Specify the command for flash read.", 78 ) 79 80 parser.add_argument("-V", "--verbose", action="count", default=0, help="Verbose Output") 81 82 ret_args = parser.parse_args() 83 return ret_args 84 85 86def img_gen(load_addr, spi_freq, spi_rdcmd, original_bin, signed_bin): 87 """ 88 To obtain the RTS5912 image header and output a new BIN file 89 """ 90 img_size = os.path.getsize(original_bin) 91 payload = bytearray(0) 92 img_size = os.path.getsize(original_bin) 93 94 fmt = ( 95 "<" 96 + 97 # type ImageHdr struct { 98 "I" # Magic uint32 99 + "I" # LoadAddr uint32 100 + "H" # HdrSz uint16 101 + "H" # reserved uint16 102 + "I" # ImgSz uint32 103 + "I" # Flags uint32 104 + "I" # reserved uint32 105 + "I" # reserved uint32 106 + "B" # SpiFmt uint8 107 + "B" # SpiRdCmd uint8 108 + "H" # reserved uint16 109 ) # } 110 111 header = struct.pack( 112 fmt, 113 IMAGE_MAGIC, 114 load_addr, 115 IMAGE_HDR_SIZE, 116 0, 117 img_size, 118 RAM_LOAD, 119 0, 120 0, 121 0 + (int(spi_freq) << 2), 122 int(spi_rdcmd, 0), 123 0, 124 ) 125 126 payload[: len(header)] = header 127 128 with open(signed_bin, "wb") as signed: 129 signed.write(payload) 130 signed.flush() 131 signed.close() 132 133 with open(signed_bin, "ab") as signed, open(original_bin, "rb") as original: 134 signed.write(original.read()) 135 signed.flush() 136 signed.close() 137 original.close() 138 139 140def main(): 141 """ 142 Image generateor tool entry point 143 """ 144 args = parse_args() 145 if args.verbose: 146 print(f" Input = {args.original_bin}") 147 print(f" Output = {args.signed_bin}") 148 print(f" Load Address = {hex(args.load_addr)}") 149 print(f" SPI Frequency = {args.spi_freq}") 150 print(f" SPI Read Command = {args.spi_rdcmd}") 151 img_gen( 152 args.load_addr, 153 args.spi_freq, 154 args.spi_rdcmd, 155 args.original_bin, 156 args.signed_bin, 157 ) 158 159 160if __name__ == "__main__": 161 main() 162