def parse_cmdline(): """ Parsing and validating input arguments.""" visible_ip_list = list(IP_OPTIONS.keys()) visible_ip_list.remove("obb_digest") epilog = "Supported Sub-Region Names: {}\n".format(visible_ip_list) parser = argparse.ArgumentParser(prog=__prog__, description=__doc__, epilog=epilog) parser.add_argument( "IFWI_IN", type=argparse.FileType("rb+"), help= "Input BIOS Binary file(Ex: IFWI.bin) to be updated with the given input IP firmware", ) parser.add_argument( "IPNAME_IN", type=argparse.FileType("rb"), help= "Input IP firmware Binary file(Ex: PseFw.Bin to be replaced in the IFWI.bin", ) parser.add_argument( "-ip", "--ipname", help= "The name of the IP in the IFWI_IN file to be replaced. This is required.", metavar="ipname", required=True, choices=visible_ip_list, ) parser.add_argument( "-k", "--private-key", type=check_key, help= "Private RSA key in PEM format. Note: Key is required for stitching GOP features", ) parser.add_argument( "-v", "--version", help="Shows the current version of the BIOS Stitching Tool", action="version", version="%(prog)s {version}".format(version=__version__), ) parser.add_argument( "-o", "--outputfile", dest="OUTPUT_FILE", type=file_not_exist, help="IFWI binary file with the IP replaced with the IPNAME_IN", metavar="FileName", default="BIOS_OUT.bin", ) return parser
def search_for_fv(inputfile, ipname): """Search for the firmware volume.""" # use to find the name of the firmware to locate the firmware volume build_list = IP_OPTIONS.get(ipname) ui_name = build_list[0][1] logger.info("\nFinding the Firmware Volume") fw_vol = None command = [FMMT, "-v", os.path.abspath(inputfile), ">", "tmp.fmmt.txt"] try: os.environ["PATH"] += os.pathsep + TOOLS_DIR logger.info("\n{}".format(" ".join(command))) subprocess.check_call(" ".join(command), shell=True, timeout=60) except subprocess.CalledProcessError as status: logger.warning("\nError using FMMT: {}".format(status)) return 1, fw_vol except subprocess.TimeoutExpired: logger.warning( "\nFMMT timed out viewing {}! Check input file for correct format". format(inputfile)) if sys.platform == 'win32': result = os.system("taskkill /f /im FMMT.exe") elif sys.platform == 'linux': result = os.system("killall FMMT") if result == 0: return 1, fw_vol sys.exit("\nError Must kill process") # search FFS by name in firmware volumes fwvol_found = False with open("tmp.fmmt.txt", "r") as searchfile: for line in searchfile: match_fv = re.match(r"(^FV\d+) :", line) if match_fv: fwvol_found = True fw_vol = match_fv.groups()[0] continue if fwvol_found: match_name = re.match(r'File "(%s)"' % ui_name, line.lstrip()) if match_name: break else: fw_vol = None # firmware volume was not found. logger.warning("\nCould not find file {} in {}".format( ui_name, inputfile)) return 0, fw_vol
def create_commands(filenames, ipname, fwvol): """Create Commands for the merge and replace of firmware section.""" inputfiles, num_replace_files = sbrgn_image.ip_inputfiles( filenames, ipname) build_list = IP_OPTIONS.get(ipname) # get the file name to be used to replace firmware volume ui_name = build_list[0][1] cmd_list = sbrgn_image.build_command_list(build_list, inputfiles, num_replace_files) cmd = replace_ip(filenames[len(filenames) - 1], fwvol, ui_name, filenames[0]) cmd_list.append(cmd) return cmd_list
"pe32": ["tmp.pe32", "-s", "EFI_SECTION_PE32"], "depex": ["tmp.dpx", "-s", "EFI_SECTION_PEI_DEPEX"], "cmprs": ["tmp.cmps", "-s", "EFI_SECTION_COMPRESSION", "-c"] } # gets the firmware file system type needed for genFFs FFS_FILETYPE = { "free": "EFI_FV_FILETYPE_FREEFORM", "gop": "EFI_FV_FILETYPE_DRIVER", "peim": "EFI_FV_FILETYPE_PEIM", } # Translate IP_OPTIONS dict into a GUID-to-NAME lookup dict section_name_lookup_table = { option[-1][1]: option[0][1] for option in IP_OPTIONS.values() } def ip_info_from_guid(lookup_val): """ returns the key and corresponding value """ return get_key_and_value(IP_OPTIONS, lookup_val, [-1, 1]) def guid_section(sec_type, guid, guid_attrib, inputfile): """ generates the GUID defined section """ cmd = ["tmp.guid", "-s", "EFI_SECTION_GUID_DEFINED", "-g"] cmd += [guid, "-r", guid_attrib, inputfile] return cmd
"guid": ["tmp.guid", "-s", "EFI_SECTION_GUID_DEFINED", "-g"], "pe32": ["tmp.pe32", "-s", "EFI_SECTION_PE32"], "depex": ["tmp.dpx", "-s", "EFI_SECTION_PEI_DEPEX"], "cmprs": ["tmp.cmps", "-s", "EFI_SECTION_COMPRESSION", "-c"] } # gets the firmware file system type needed for genFFs FFS_FILETYPE = { "free": "EFI_FV_FILETYPE_FREEFORM", "gop": "EFI_FV_FILETYPE_DRIVER", "peim": "EFI_FV_FILETYPE_PEIM", } # Translate IP_OPTIONS dict into a GUID-to-NAME lookup dict section_name_lookup_table = { option[-1][1]: option[0][1] for option in IP_OPTIONS.values()} def ip_info_from_guid(lookup_val): """ returns the key and corresponding value """ return get_key_and_value(IP_OPTIONS, lookup_val, [-1, 1]) def guid_section(sec_type, guid, guid_attrib, inputfile): """ generates the GUID defined section """ cmd = ["tmp.guid", "-s", "EFI_SECTION_GUID_DEFINED", "-g"] cmd += [guid, "-r", guid_attrib, inputfile] return cmd def generate_section(inputfiles, align_sizes):