def mini_build_path(self, mini_build_path): assert isinstance(mini_build_path, str) mini_build_path = c_path.normalize(mini_build_path) if not c_path.validate_dir_write(mini_build_path): raise RuntimeError('No write access to minimized build directory: ' + mini_build_path) # Update the output dir of each image in image_info_list for image_info in self.image_info_list: image_info.dest_image.image_dir_base = mini_build_path self._mini_build_path = mini_build_path
def output_dir(self, output_dir): assert isinstance(output_dir, str) output_dir = c_path.normalize(output_dir) if not c_path.validate_dir_write(output_dir): raise RuntimeError('No write access to output directory: ' + output_dir) # Update the output dir of each image in image_info_list for image_info in self.image_info_list: image_info.dest_image.image_dir_base = output_dir image_info.dest_image.image_dir_ext = (image_info.chipset + '/' + image_info.sign_id) self._output_dir = output_dir
def output_dir(self, output_dir): assert isinstance(output_dir, str) output_dir = c_path.normalize(output_dir) if not c_path.validate_dir_write(output_dir): raise RuntimeError('No write access to output directory: ' + output_dir) # Update the output dir of each image in image_info_list for image_info in self.image_info_list: self.update_dest_image(image_info, output_dir) self._output_dir = output_dir
def get_scons_targets(input): # initialize target lists integrity_targets = list() sign_targets = list() encrypt_targets = list() sign_and_encrypt_targets = list() scons_targets = [integrity_targets, sign_targets, encrypt_targets, sign_and_encrypt_targets] pilsplit_files_to_clean = list() # get chipset and filename of input file chipset = SecImageConfigParser(input.config).root.metadata.get_chipset() path, filename = os.path.split(input.source) if input.build_policy: for policy in input.build_policy.sec_image_policies: target_list_to_append_to = scons_targets[target_map[policy.cmd_options]] # get path to installed image if input.sectools_install_base_dir: for install_location in policy.install_locations: if input.install_file_name: target = c_path.join(install_location, input.install_file_name) else: target = c_path.join(install_location, filename) logger.debug("Added to-be-installed file \"{0}\" to SCons target list".format(target)) target_list_to_append_to.append(target) # determine pilsplit images to cleanup if input.pilsplitter_target_base_dir: if install_location != input.sectools_install_base_dir: pilsplit_directory = c_path.join(input.pilsplitter_target_base_dir, install_location.replace(os.path.join(input.sectools_install_base_dir, "", ""), "")) else: pilsplit_directory = input.pilsplitter_target_base_dir if c_path.validate_dir_write(pilsplit_directory): pilsplit_filename = input.install_file_name.split(".")[0] if input.install_file_name else filename.split(".")[0] # get all pil files in pilsplit target directory regex = r"^" + re.escape(pilsplit_filename) + r"\.((mdt)|(b[0-9][0-9]))$" pil_files = [c_path.join(pilsplit_directory, f) for f in os.listdir(pilsplit_directory) if re.match(regex, f)] for pil_file in pil_files: logger.debug("Added pilsplit file \"{0}\" to SCons clean list".format(pil_file)) pilsplit_files_to_clean.append(pil_file) # get path to uninstalled image if no installation is requested else: uninstalled_target = c_path.normalize(c_path.join(input.target_base_dir, policy.id, chipset, input.sign_id, filename)) target_list_to_append_to.append(uninstalled_target) logger.debug("Added file \"{0}\" to SCons target list".format(uninstalled_target)) # remove duplicates from lists for i, targets in enumerate(scons_targets): scons_targets[i] = remove_duplicates(targets) pilsplit_files_to_clean = remove_duplicates(pilsplit_files_to_clean) # clean pilsplit files input.environment.Clean(scons_targets, pilsplit_files_to_clean) # return target list return scons_targets
def generateMetaBuild(self, timer=1200, interval=5): """ generate new meta build with given image build :param str meta_build_path: meta build directory, require write access :param str image_build_path: image build directory, require read access """ if self.run: self.retcode = '' # meta build path validation meta_path_val = c_path.normalize(self.meta_build_path) if not c_path.validate_dir_write(meta_path_val): raise RuntimeError('Cannot write at: ' + meta_path_val) # image build path validation image_path_val = c_path.normalize(self.image_build_path) if not c_path.validate_dir(image_path_val): raise RuntimeError('Cannot access: ' + image_path_val) """TODO: Don't know how to check if TZ build has changed and if re-generate NON-HLOS.bin is needed. For now, always re-generate meta build. """ # check if meta build has been generated with the required image build already meta_info = self.getMetainfo(self.meta_build_path) path = meta_info.get_build_path(BUILD) tz_path_in_meta_build_val = c_path.normalize(path) generation_complete_flag = c_path.join(meta_path_val, GENERATION_COMPLETE_STR) """ if tz_path_in_meta_build_val == image_path_val and c_path.validate_file(generation_complete_flag): self.logging_state_info('meta build with required image build is available at: ' + meta_path_val) self.logging_state_info('meta build generation is skipped') logger.debug('meta build path: ' + meta_path_val) logger.debug('image build path: ' + image_path_val) else: """ cmd = ['python', REGENERATE_CMD_TZ + image_path_val] cwd = c_path.join(meta_path_val, BUILD_SCRIPTS_DIR) self.logging_state_info(getCurrentTime() + ' start meta build generation, please wait and do not interrupt ...') self.logging_state_info('Set current working directory: ' + cwd) self.logging_state_info('Generate Meta build command: ' + " ".join(cmd)) self.log = c_path.join(meta_path_val, REGENERATE_BUID_LOG) self.run = False self.retcode = self.execute(cmd, self.log, cwd, timer, interval) self.logging_state_info(getCurrentTime() +' meta build generation return code: ' + str(self.retcode)) self.logging_state_info('meta build generation log can be found at: ' + self.log) if self.retcode == 0: open(generation_complete_flag,'a').close() self.run = True self.logging_state_info(SECTION_BREAK) else: self.logging_state_info('skip meta build regeneration')
def output_dir(self, output_dir): assert isinstance(output_dir, str) output_dir = c_path.normalize(output_dir) if not c_path.validate_dir_write(output_dir): raise RuntimeError('No write access to output directory: ' + output_dir) # Update the output dir of each image in image_info_list for image_info in self.image_info_list: self.update_dest_image(image_info, output_dir) # Update the output dir of Multi-Image Signing and Integrity image if self._multi_image_imageinfo_dict: for target, imageinfo in self._multi_image_imageinfo_dict.items(): self.update_dest_image(imageinfo, output_dir) self._output_dir = output_dir
def loadMetaBuild(self, keyword=None, timer=1200, interval=5): """ load meta build with fastboot_complete.py :param str meta_build_path: meta build directory, require read access """ if self.run: self.retcode = '' # meta build path validation meta_path_val = c_path.normalize(self.meta_build_path) if not c_path.validate_dir_write(meta_path_val): raise RuntimeError('Cannot write at: ' + meta_path_val) # check device status (put device to fastboot mode) if AndroidDevice.checkFastboot(): enable_buildloading = True else: enable_buildloading = AndroidDevice.fastbootDevice() if enable_buildloading: cmd = ['python', BUILDLOAD_PY] cwd = c_path.join(meta_path_val, BUILD_SCRIPTS_DIR) self.logging_state_info(getCurrentTime() + ' start meta build loading, please wait and do not interrupt ...') self.logging_state_info('Set current working directory: ' + cwd) self.logging_state_info('Meta build loading command: ' + " ".join(cmd)) self.log = c_path.join(meta_path_val, FASTBOOT_COMPLETE_LOG) self.run = False self.retcode = self.execute(cmd, self.log, cwd, timer, interval) self.logging_state_info(getCurrentTime() +' meta build loading return code: ' + str(self.retcode)) self.logging_state_info('meta build loading log can be found at: ' + self.log) if self.retcode == 0: self.run = True self.logging_state_info(SECTION_BREAK) if AndroidDevice.restartDevice(): self.logging_state_info('device reboot completed') else: self.logging_state_info('device reboot failed, please reboot the device manually') else: self.retcode = 1 logger.error('device cannot be set in fastboot mode, please set manually') else: self.logging_state_info('skip meta build loading')
def generate(self, args): infile = open(args.input_file, "rb") infile_data = infile.read() infile.close() if self.is_mbn_file(infile_data, args.input_file) is not None: logger.warning( "WARNING! {0} appears to already have an MBN header!".format( args.input_file)) # sectools will update these values when it inputs the cert chain and sig # but in this feature just set them to zero code_size = ALIGNED_IMAGE_SIZE(os.path.getsize(args.input_file)) signature_size = 0 signature_ptr = 0 cert_chain_ptr = 0 cert_chain_size = 0 image_size = code_size + signature_size + cert_chain_size header = None if args.header_length == 40: header = MbnHdr40B() header._unpack_data_list([ args.image_id, args.header_version, args.image_src, args.image_dest_ptr, image_size, code_size, signature_ptr, signature_size, cert_chain_ptr, cert_chain_size ]) elif args.header_length == 80: header = MbnHdr80B() # todo: verify magic and codeword are correct header._unpack_data_list([ MBN_80_CODEWORD, # codeword I pulled from given file MBN_80_MAGIC, # magic I pulled from given file args.image_id, 0xffffffff, 0xffffffff, args.image_src, args.image_dest_ptr, image_size, code_size, signature_ptr, signature_size, cert_chain_ptr, cert_chain_size, 0, # this has a value of 1 in a file I was given. what does it mean? 0, 0, 0, 0, 0, 0 ]) else: raise RuntimeError( "received invalid MBN header length in generate. This should never happen" ) outfile_name = os.path.basename(args.input_file) + ".mbn" if not c_path.validate_dir_write(args.output_dir): os.makedirs(args.output_dir) outfile = open(c_path.join(args.output_dir, outfile_name), "wb") outfile.write(header.pack()) outfile.write(infile_data) outfile.close() infile.close() logger.info("output \"{0}\" has been successfully generated".format( c_path.join(args.output_dir, outfile_name)))