Home | History | Annotate | Download | only in hikey960
      1 #!/usr/bin/env python
      2 # Copyright 2017, The Android Open Source Project
      3 #
      4 # Licensed under the Apache License, Version 2.0 (the "License");
      5 # you may not use this file except in compliance with the License.
      6 # You may obtain a copy of the License at
      7 #
      8 #     http://www.apache.org/licenses/LICENSE-2.0
      9 #
     10 # Unless required by applicable law or agreed to in writing, software
     11 # distributed under the License is distributed on an "AS IS" BASIS,
     12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 # See the License for the specific language governing permissions and
     14 # limitations under the License.
     15 from __future__ import print_function
     16 try:
     17 	from os import fstat, stat, remove
     18 	from sys import exit
     19 	from argparse import ArgumentParser, FileType
     20 	from ctypes import sizeof, Structure, c_char, c_int
     21 	from struct import pack, calcsize
     22 	import zlib
     23 except Exception as e:
     24 	print("some module is needed:" + str(e))
     25 	exit(-1)
     26 
     27 dt_head_info_fmt = '4sII'
     28 dt_entry_fmt = 'Q4I2Q'
     29 dtimg_version = 1
     30 dtb_count = 1
     31 
     32 def write32(output, value):
     33 	output.write(chr(value & 255)) ; value=value // 256
     34 	output.write(chr(value & 255)) ; value=value // 256
     35 	output.write(chr(value & 255)) ; value=value // 256
     36 	output.write(chr(value & 255))
     37 
     38 def compress(filename, input, output):
     39 	output.write('\037\213\010')
     40 	output.write(chr(0))
     41 
     42 	statval = stat(filename)
     43 	write32(output, 0)
     44 	output.write('\002')
     45 	output.write('\003')
     46 
     47 	crcval = zlib.crc32("")
     48 	compobj = zlib.compressobj(9, zlib.DEFLATED, -zlib.MAX_WBITS,
     49 		zlib.DEF_MEM_LEVEL, 0)
     50 	while True:
     51 		data = input.read(1024)
     52 		if data == "":
     53 			break
     54 		crcval = zlib.crc32(data, crcval)
     55 		output.write(compobj.compress(data))
     56 	output.write(compobj.flush())
     57 	write32(output, crcval)
     58 	write32(output, statval.st_size)
     59 
     60 def dtb_compress(dtb_file):
     61 	try:
     62 		outputname = dtb_file + '.gz'
     63 		input = open(dtb_file, 'rb')
     64 		output = open(outputname, 'wb')
     65 		compress(dtb_file, input, output)
     66 		input.close()
     67 		output.close()
     68 	except Exception as e:
     69 		print('dtb_compress error:' + str(e))
     70 		exit(-1)
     71 	return outputname
     72 
     73 class dt_head_info(Structure):
     74 	_fields_ = [('magic', c_char * 4),
     75 		    ('version', c_int),
     76 		    ('dt_count', c_int)]
     77 
     78 class dt_entry_t(Structure):
     79 	_fields_ = [('dtb_size', c_int),
     80 		    ('dtb_offset', c_int)]
     81 
     82 def align_page_size(offset, pagesize):
     83 	return (pagesize - (offset % pagesize))
     84 
     85 def write_head_info(head_info, args):
     86 	args.output.write(pack(dt_head_info_fmt,
     87 			       head_info.magic,
     88 			       head_info.version,
     89 			       head_info.dt_count))
     90 
     91 def write_dtb_entry_t(dt_entry, args):
     92 	args.output.write(pack(dt_entry_fmt,
     93 			       0,  # reserved
     94 			       dt_entry.dtb_size,
     95 			       0,  # reserved
     96 			       dt_entry.dtb_offset,
     97 			       0,  # reserved
     98 			       0,  # reserved
     99 			       0)) # reserved
    100 
    101 def write_padding(args, padding):
    102 	for i in range(0, padding):
    103 		args.output.write('\x00')
    104 
    105 def write_dtb(args):
    106 	dtb_file = args.dtb
    107 	out_dtb = dtb_file
    108 	if args.compress == True:
    109 		out_dtb = dtb_compress(dtb_file)
    110 	try:
    111 		dtb_offset = calcsize(dt_head_info_fmt) + \
    112 				      calcsize(dt_entry_fmt) + \
    113 				      4
    114 		padding = align_page_size(dtb_offset, args.pagesize)
    115 		dtb_size = stat(out_dtb).st_size
    116 		dtb_size_padding = align_page_size(dtb_size, args.pagesize)
    117 		dt_entry = dt_entry_t(dtb_size + dtb_size_padding,
    118 				      dtb_offset + padding)
    119 		write_dtb_entry_t(dt_entry, args)
    120 		args.output.write(pack('I', 0)) # SUCCESS code number
    121 		write_padding(args, padding)
    122 		with open(out_dtb, 'rb') as dtb_fd:
    123 			args.output.write(dtb_fd.read(dtb_size))
    124 			write_padding(args, dtb_size_padding)
    125 	except Exception as e:
    126 		print('write dtb error:' + str(e))
    127 		exit(-1)
    128 
    129 def clean_gz_file(args):
    130 	try:
    131 		if args.compress != True:
    132 			return
    133 		remove(args.dtb + '.gz')
    134 	except Exception as e:
    135 		print('clean gz file error:' + str(e))
    136 		exit(-1)
    137 
    138 def parse_cmdline():
    139 	parser = ArgumentParser()
    140 	parser.add_argument('-c', '--compress', help='compress dtb or not',
    141 			    action='store_true')
    142 	parser.add_argument('-d', '--dtb', help='path to the dtb', type=str,
    143 			    required=True)
    144 	parser.add_argument('-s', '--pagesize', help='align page size',
    145 			    type=int, choices=[2**i for i in range(11,15)],
    146 			    default=2048)
    147 	parser.add_argument('-o', '--output', help='output file name',
    148 			    type=FileType('wb'), required=True)
    149 	return parser.parse_args()
    150 
    151 def main():
    152 	args = parse_cmdline()
    153 	dtimg_head_info = dt_head_info('HSDT', dtimg_version, dtb_count)
    154 	write_head_info(dtimg_head_info, args)
    155 	write_dtb(args)
    156 	clean_gz_file(args)
    157 
    158 if __name__ == '__main__':
    159 	main()
    160