summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Albert <albertj@us.ibm.com>2015-03-09 16:20:11 -0500
committerJason Albert <albertj@us.ibm.com>2015-03-09 16:20:11 -0500
commitcef276997a94e687595b0fff81b7be60f21f0e9f (patch)
treec9a3911c4d4f4d5f9ece603f425c9dc4dccd6843
parent44717d64c8d7072ae4bd7db37e22ec63888df7b2 (diff)
downloadvpdtools-cef276997a94e687595b0fff81b7be60f21f0e9f.tar.gz
vpdtools-cef276997a94e687595b0fff81b7be60f21f0e9f.zip
Added support for creating binary keyword files. Also added support for reading back in the record binary files and merging them into a vpd image. Back checkin on my part - two different functions in one checkin
-rwxr-xr-xcreateVpd.py297
1 files changed, 178 insertions, 119 deletions
diff --git a/createVpd.py b/createVpd.py
index 87e1755..1a18f71 100755
--- a/createVpd.py
+++ b/createVpd.py
@@ -51,7 +51,8 @@ def help():
out.setIndent(2)
out.msg("-d|--debug Enables debug printing")
out.msg("-h|--help This help text")
- out.msg("-b|--binary-records Create binary files for each record in the template")
+ out.msg("-r|--binary-records Create binary files for each record in the template")
+ out.msg("-k|--binary-keywords Create binary files for each keyword in the template")
out.setIndent(0)
# Function to Write out the resultant tvpd xml file
@@ -185,7 +186,7 @@ def calcPadFill(record):
pfLength = 0
# The PF keyword must exist
- # The keyword section of record must be at least 40 bytes long, padfill will be used to acheive that
+ # The keyword section of record must be at least 40 bytes long, padfill will be used to achieve that
# If the keyword section is over over 40, it must be aligned on word boundaries and PF accomplishes that
# The record passed in at this point is the keywords + 3 other bytes (LR Tag & Record Length)
@@ -202,8 +203,6 @@ def calcPadFill(record):
# Main - Main - Main - Main - Main - Main - Main - Main
############################################################
rc = 0
-# Get the path the script is being called from
-cwd = os.path.dirname(os.path.abspath(__file__))
################################################
# Command line options
@@ -251,7 +250,10 @@ if (clErrors):
clDebug = cmdline.parseOption("-d", "--debug")
# Create separate binary files for each record
-clBinaryRecords = cmdline.parseOption("-b", "--binary-records")
+clBinaryRecords = cmdline.parseOption("-r", "--binary-records")
+
+# Create separate binary files for each keyword
+clBinaryKeywords = cmdline.parseOption("-k", "--binary-keywords")
# All cmdline args should be processed, so if any left throw an error
if (len(sys.argv) != 1):
@@ -346,112 +348,149 @@ for record in manifest.iter("record"):
out.error("The record name entry \"%s\" is not 4 characters long" % recordName)
errorsFound+=1
- # Track the keywords we come across so we can find duplicate
- keywordNames = dict()
- # Loop through the keywords and verify them
- for keyword in record.iter("keyword"):
- # Pull the keyword name out for use throughout
- keywordName = keyword.attrib.get("name")
+ # --------
+ # Determine if they gave a list of keyword descriptions to convert to binary data of if they gave a binary data record
+ keywordTagFound = False
+ rbinfileTagFound = False
+ if (record.find("keyword") != None):
+ keywordTagFound = True
+ if (record.find("rbinfile") != None):
+ rbinfileTagFound = True
+ # Both given
+ if (keywordTagFound and rbinfileTagFound):
+ out.error("Both <keyword> and <rbinfile> tags were found in record %s. Only one or the other is supported!" % (recordName))
+ errorsFound+=1
+ break
- # Setup a dictionary of the supported tags
- kwTags = {"keyword" : False, "kwdesc" : False, "kwformat" : False, "kwlen" : False, "kwdata" : False}
+ # Neither given
+ if (not keywordTagFound and not rbinfileTagFound):
+ out.error("Neither the <keyword> or <rbinfile> tags were found in record %s. One must be given!" % (recordName))
+ errorsFound+=1
- # --------
- # Make sure we aren't finding a record we haven't already seen
- if (keywordName in keywordNames):
- out.error("The keyword \"%s\" has previously been defined in record %s" % (keywordName, recordName))
- errorsFound+=1
- else:
- keywordNames[keywordName] = 1
+ # Do very basic checking on the rbinfile if found
+ # It is assumed that this file was generated by this tool at an earlier date, so it should be format correct
+ # We'll simply ensure it is actually a record that goes with this record name
+ if (rbinfileTagFound):
+ # Get the name
+ rbinfile = record.find("rbinfile").text
+ # Make sure the file exists
+ if (os.path.exists(rbinfile) != True):
+ out.error("The rbinfile given %s does not exist" % (rbinfile))
+ clErrors+=1
+ break
+
+ # It does, read it in so we can check the record name
+ rbinfileContents = open(rbinfile, mode='rb').read()
# --------
- # We'll loop through all the tags found in this keyword and check for all required and any extra ones
- for kw in keyword.iter():
- if kw.tag in kwTags:
- # Mark that we found a required tag
- kwTags[kw.tag] = True
- # Save the values we'll need into variables for ease of use
- if (kw.tag == "kwformat"):
- kwformat = kw.text.lower() # lower() for ease of compare
-
- if (kw.tag == "kwlen"):
- kwlen = int(kw.text)
-
- if (kw.tag == "kwdata"):
- kwdata = kw.text
-
- else:
- # Flag that we found an unsupported tag. This may help catch typos, etc..
- out.error("The unsupported tag \"<%s>\" was found in keyword %s in record %s" % (kw.tag, keywordName, recordName))
+ # Check the record name
+ # This is just the hard coded offset into any record where the contents of the RT keyword would be found
+ if (recordName != rbinfileContents[6:10].decode()):
+ out.error("The record name found %s in %s, does not match the name of the record %s in the tvpd" % (rbinfileContents[6:10].decode(), rbinfile, recordName))
+ clErrors+=1
+
+ # For the keyword tags we'll do much more extensive checking
+ if (keywordTagFound):
+ # Track the keywords we come across so we can find duplicate
+ keywordNames = dict()
+ # Loop through the keywords and verify them
+ for keyword in record.iter("keyword"):
+ # Pull the keyword name out for use throughout
+ keywordName = keyword.attrib.get("name")
+
+ # Setup a dictionary of the supported tags
+ kwTags = {"keyword" : False, "kwdesc" : False, "kwformat" : False, "kwlen" : False, "kwdata" : False}
+
+ # --------
+ # Make sure we aren't finding a record we haven't already seen
+ if (keywordName in keywordNames):
+ out.error("The keyword \"%s\" has previously been defined in record %s" % (keywordName, recordName))
errorsFound+=1
+ else:
+ keywordNames[keywordName] = 1
+
+ # --------
+ # We'll loop through all the tags found in this keyword and check for all required and any extra ones
+ for kw in keyword.iter():
+ if kw.tag in kwTags:
+ # Mark that we found a required tag
+ kwTags[kw.tag] = True
+ # Save the values we'll need into variables for ease of use
+ if (kw.tag == "kwformat"):
+ kwformat = kw.text.lower() # lower() for ease of compare
+
+ if (kw.tag == "kwlen"):
+ kwlen = int(kw.text)
+
+ if (kw.tag == "kwdata"):
+ kwdata = kw.text
+
+ else:
+ # Flag that we found an unsupported tag. This may help catch typos, etc..
+ out.error("The unsupported tag \"<%s>\" was found in keyword %s in record %s" % (kw.tag, keywordName, recordName))
+ errorsFound+=1
- # --------
- # Make sure all the required kwTags were found
- for kw in kwTags:
- if (kwTags[kw] == False):
- out.error("Required tag \"<%s>\" was not found in keyword %s in record %s" % (kw, keywordName, recordName))
+ # --------
+ # Make sure all the required kwTags were found
+ for kw in kwTags:
+ if (kwTags[kw] == False):
+ out.error("Required tag \"<%s>\" was not found in keyword %s in record %s" % (kw, keywordName, recordName))
+ errorsFound+=1
+
+ # Now we know the basics of the template are correct, now do more indepth checking of length, etc..
+
+ # --------
+ # Make sure the keyword is two characters long
+ if (len(keywordName) != 2):
+ out.error("The length of the keyword %s in record %s is not 2 characters long" % (keywordName, recordName))
errorsFound+=1
- # Now we know the basics of the template are correct, now do more indepth checking of length, etc..
-
- # --------
- # Make sure the keyword is two characters long
- if (len(keywordName) != 2):
- out.error("The length of the keyword %s in record %s is not 2 characters long" % (keywordName, recordName))
- errorsFound+=1
-
- # --------
- # A check to make sure the RT keyword kwdata matches the name of the record we are in
- if ((keywordName == "RT") and (recordName != kwdata)):
- out.error("The value of the RT keyword \"%s\" does not match the record name \"%s\"" % (kwdata, recordName))
- errorsFound+=1
-
- # --------
- # Check that the length specified isn't longer than the keyword supports
- # Keywords that start with # are 2 bytes, others are 1 byte
- if (keywordName[0] == "#"):
- maxlen = 65535
- else:
- maxlen = 255
- if (kwlen > maxlen):
- out.error("The specified length %d is bigger than the max length %d for keyword %s in record %s" % (kwlen, maxlen, keywordName, recordName))
- errorsFound+=1
-
- # --------
- # If the input format is hex, make sure the input data is hex only
- if (kwformat == "hex"):
- # Remove white space and carriage returns from the kwdata
- kwdata = kwdata.replace(" ","")
- kwdata = kwdata.replace("\n","")
- # Now look to see if there are any characters other than 0-9 & a-f
- #match = re.search("([g-zG-Z]+)", kwdata)
- match = re.search("([^0-9a-fA-F]+)", kwdata)
- if (match):
- out.error("A non hex character \"%s\" was found at %s in the kwdata for keyword %s in record %s" % (match.group(), match.span(), keywordName, recordName))
+ # --------
+ # A check to make sure the RT keyword kwdata matches the name of the record we are in
+ if ((keywordName == "RT") and (recordName != kwdata)):
+ out.error("The value of the RT keyword \"%s\" does not match the record name \"%s\"" % (kwdata, recordName))
errorsFound+=1
- # --------
- # Verify that the data isn't longer than the length given
- # Future checks could include making sure hex data is hex
- if (kwformat == "ascii"):
- if (len(kwdata) > kwlen):
- out.error("The length of the value is longer than the given <kwlen> for keyword %s in record %s" % (keywordName, recordName))
- errorsFound+=1
- elif (kwformat == "hex"):
- # Convert hex nibbles to bytes for len compare
- if ((len(kwdata)/2) > kwlen):
- out.error("The length of the value is longer than the given <kwlen> for keyword %s in record %s" % (keywordName, recordName))
+ # --------
+ # Check that the length specified isn't longer than the keyword supports
+ # Keywords that start with # are 2 bytes, others are 1 byte
+ if (keywordName[0] == "#"):
+ maxlen = 65535
+ else:
+ maxlen = 255
+ if (kwlen > maxlen):
+ out.error("The specified length %d is bigger than the max length %d for keyword %s in record %s" % (kwlen, maxlen, keywordName, recordName))
errorsFound+=1
- else:
- out.error("Unknown keyword format \"%s\" given for keyword %s in record %s" % (kwformat, keywordName, recordName))
- errorsFound+=1
- # --------
- # We are done reading the keywords in this record, so make sure we have at least 1 keyword
- if (len(keywordNames) < 1):
- out.error("No keywords were found for record %s" % recordName)
- errorsFound+=1
+ # --------
+ # If the input format is hex, make sure the input data is hex only
+ if (kwformat == "hex"):
+ # Remove white space and carriage returns from the kwdata
+ kwdata = kwdata.replace(" ","")
+ kwdata = kwdata.replace("\n","")
+ # Now look to see if there are any characters other than 0-9 & a-f
+ match = re.search("([^0-9a-fA-F]+)", kwdata)
+ if (match):
+ out.error("A non hex character \"%s\" was found at %s in the kwdata for keyword %s in record %s" % (match.group(), match.span(), keywordName, recordName))
+ errorsFound+=1
+
+ # --------
+ # Verify that the data isn't longer than the length given
+ # Future checks could include making sure hex data is hex
+ if (kwformat == "ascii"):
+ if (len(kwdata) > kwlen):
+ out.error("The length of the value is longer than the given <kwlen> for keyword %s in record %s" % (keywordName, recordName))
+ errorsFound+=1
+ elif (kwformat == "hex"):
+ # Convert hex nibbles to bytes for len compare
+ if ((len(kwdata)/2) > kwlen):
+ out.error("The length of the value is longer than the given <kwlen> for keyword %s in record %s" % (keywordName, recordName))
+ errorsFound+=1
+ else:
+ out.error("Unknown keyword format \"%s\" given for keyword %s in record %s" % (kwformat, keywordName, recordName))
+ errorsFound+=1
+# All done with error check, bailout if we hit something
if (errorsFound):
out.msg("")
out.error("%d error%s found in the tvpd description. Please review the above errors and correct them." % (errorsFound, "s" if (errorsFound > 1) else ""))
@@ -620,33 +659,53 @@ imageSize += len(recordInfo[recordName].record)
for record in manifest.iter("record"):
recordName = record.attrib.get("name")
- # The large resource tag
- recordInfo[recordName].record += bytearray(bytearray.fromhex("84"))
+ # Figure out if we need to create an image from keywords, or just stick a record binary in place
+ # We already did all the check to make sure only a rbinfile or keyword(s) tag was given
+ # Don't error check those cases here. If rbinfile is fine, just go and else the keyword case
+ if (record.find("rbinfile") != None):
+ # Get the name
+ rbinfile = record.find("rbinfile").text
- # The record length, we will come back and update this at the end
- recordInfo[recordName].record += bytearray(bytearray.fromhex("0000"))
+ # Open the file and stick it into the record
+ recordInfo[recordName].record = open(rbinfile, mode='rb').read()
- # The keywords
- keywordsLength = 0
- for keyword in record.iter("keyword"):
- keywordPack = packKeyword(keyword.attrib.get("name"), int(keyword.find("kwlen").text), keyword.find("kwdata").text, keyword.find("kwformat").text)
- recordInfo[recordName].record += keywordPack
- keywordsLength += len(keywordPack)
+ # Create the record image from the xml description
+ else:
+
+ # The large resource tag
+ recordInfo[recordName].record += bytearray(bytearray.fromhex("84"))
- # Calculate the padfill required
- padfillSize = calcPadFill(recordInfo[recordName].record)
+ # The record length, we will come back and update this at the end
+ recordInfo[recordName].record += bytearray(bytearray.fromhex("0000"))
- # Write the PF keyword
- keywordPack = packKeyword("PF", padfillSize, "0", "hex")
- recordInfo[recordName].record += keywordPack
+ # The keywords
+ for keyword in record.iter("keyword"):
+ keywordName = keyword.attrib.get("name")
+
+ keywordPack = packKeyword(keywordName, int(keyword.find("kwlen").text), keyword.find("kwdata").text, keyword.find("kwformat").text)
+ recordInfo[recordName].record += keywordPack
+ # If the user wanted discrete binary files for each keyword writen out, we'll do it here
+ if (clBinaryKeywords):
+ kvpdFileName = clOutputPath + "/" + vpdName + "-" + recordName + "-" + keywordName + ".vpd"
+ out.msg("Wrote record %s keyword %s vpd file: %s" % (recordName, keywordName, kvpdFileName))
+ kvpdFile = open(kvpdFileName, "wb")
+ kvpdFile.write(keywordPack)
+ kvpdFile.close()
+
+ # Calculate the padfill required
+ padfillSize = calcPadFill(recordInfo[recordName].record)
+
+ # Write the PF keyword
+ keywordPack = packKeyword("PF", padfillSize, "0", "hex")
+ recordInfo[recordName].record += keywordPack
- # The small resource tag
- recordInfo[recordName].record += bytearray(bytearray.fromhex("78"))
+ # The small resource tag
+ recordInfo[recordName].record += bytearray(bytearray.fromhex("78"))
- # Update the record length
- # Total length minus 4, LR(1), SR(1), Length (2)
- recordLength = len(recordInfo[recordName].record) - 4
- recordInfo[recordName].record[1:3] = struct.pack('<H', recordLength)
+ # Update the record length
+ # Total length minus 4, LR(1), SR(1), Length (2)
+ recordLength = len(recordInfo[recordName].record) - 4
+ recordInfo[recordName].record[1:3] = struct.pack('<H', recordLength)
# Go back and update all our TOC info now that the record is created
tocName = recordInfo[recordName].tocName
OpenPOWER on IntegriCloud