--- /dev/null
+#!/usr/bin/env python
+"""
+# Copyright (C) 2010 Michael Buesch <mb@bu3sch.de>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2
+# as published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+"""
+
+import sys
+import getopt
+
+def indexToName(index):
+ D11UCODE_NAMETAG_START = 0
+ D11LCN0BSINITVALS24 = 1
+ D11LCN0INITVALS24 = 2
+ D11LCN1BSINITVALS24 = 3
+ D11LCN1INITVALS24 = 4
+ D11LCN2BSINITVALS24 = 5
+ D11LCN2INITVALS24 = 6
+ D11N0ABSINITVALS16 = 7
+ D11N0BSINITVALS16 = 8
+ D11N0INITVALS16 = 9
+ D11UCODE_OVERSIGHT16_MIMO = 10
+ D11UCODE_OVERSIGHT16_MIMOSZ = 11
+ D11UCODE_OVERSIGHT24_LCN = 12
+ D11UCODE_OVERSIGHT24_LCNSZ = 13
+ D11UCODE_OVERSIGHT_BOMMAJOR = 14
+ D11UCODE_OVERSIGHT_BOMMINOR = 15
+
+ namemap = {
+ D11UCODE_NAMETAG_START : "start",
+ D11LCN0BSINITVALS24 : "LCN0 bs initvals 24",
+ D11LCN0INITVALS24 : "LCN0 initvals 24",
+ D11LCN1BSINITVALS24 : "LCN1 bs initvals 24",
+ D11LCN1INITVALS24 : "LCN1 initvals 24",
+ D11LCN2BSINITVALS24 : "LCN2 bs initvals 24",
+ D11LCN2INITVALS24 : "LCN2 initvals 24",
+ D11N0ABSINITVALS16 : "N0A bs initvals 16",
+ D11N0BSINITVALS16 : "N0 bs initvals 16",
+ D11N0INITVALS16 : "N0 initvals 16",
+ D11UCODE_OVERSIGHT16_MIMO : "microcode 16 MIMO",
+ D11UCODE_OVERSIGHT16_MIMOSZ : "microcode 16 MIMO size",
+ D11UCODE_OVERSIGHT24_LCN : "microcode 24 LCN",
+ D11UCODE_OVERSIGHT24_LCNSZ : "microcode 24 LCN size",
+ D11UCODE_OVERSIGHT_BOMMAJOR : "bom major",
+ D11UCODE_OVERSIGHT_BOMMINOR : "bom minor",
+ }
+ try:
+ return namemap[index]
+ except KeyError:
+ return "Unknown"
+
+def parseHeader(hdr_data, sortByOffset):
+ sections = []
+ for i in range(0, len(hdr_data), 3 * 4):
+ offset = ord(hdr_data[i + 0]) | (ord(hdr_data[i + 1]) << 8) |\
+ (ord(hdr_data[i + 2]) << 16) | (ord(hdr_data[i + 3]) << 24)
+ length = ord(hdr_data[i + 4]) | (ord(hdr_data[i + 5]) << 8) |\
+ (ord(hdr_data[i + 6]) << 16) | (ord(hdr_data[i + 7]) << 24)
+ index = ord(hdr_data[i + 8]) | (ord(hdr_data[i + 9]) << 8) |\
+ (ord(hdr_data[i + 10]) << 16) | (ord(hdr_data[i + 11]) << 24)
+
+ sections.append( (offset, length, index) )
+ if sortByOffset:
+ sections.sort(key = lambda x: x[0]) # Sort by offset
+ else:
+ sections.sort(key = lambda x: x[2]) # Sort by index
+ return sections
+
+def generateHeaderData(sections):
+ data = []
+ for section in sections:
+ (offset, length, index) = section
+ data.append(chr(offset & 0xFF))
+ data.append(chr((offset >> 8) & 0xFF))
+ data.append(chr((offset >> 16) & 0xFF))
+ data.append(chr((offset >> 24) & 0xFF))
+ data.append(chr(length & 0xFF))
+ data.append(chr((length >> 8) & 0xFF))
+ data.append(chr((length >> 16) & 0xFF))
+ data.append(chr((length >> 24) & 0xFF))
+ data.append(chr(index & 0xFF))
+ data.append(chr((index >> 8) & 0xFF))
+ data.append(chr((index >> 16) & 0xFF))
+ data.append(chr((index >> 24) & 0xFF))
+ return "".join(data)
+
+def getSectionByIndex(sections, searchIndex):
+ for section in sections:
+ (offset, length, index) = section
+ if searchIndex == index:
+ return section
+ return None
+
+def parseHeaderFile(hdr_filepath, sortByOffset=False):
+ try:
+ hdr_data = file(hdr_filepath, "rb").read()
+ except (IOError), e:
+ print "Failed to read header file: %s" % e.strerror
+ return None
+ if len(hdr_data) % (3 * 4) != 0:
+ print "Invalid header file format"
+ return None
+ return parseHeader(hdr_data, sortByOffset)
+
+def dumpInfo(hdr_filepath):
+ sections = parseHeaderFile(hdr_filepath)
+ if not sections:
+ return 1
+ for section in sections:
+ (offset, length, index) = section
+ print "Index %2d %24s ==> offset:0x%08X length:0x%08X" %\
+ (index, indexToName(index), offset, length)
+ return 0
+
+def extractSection(hdr_filepath, bin_filepath, extractIndex, outfilePath):
+ sections = parseHeaderFile(hdr_filepath)
+ if not sections:
+ return 1
+ section = getSectionByIndex(sections, extractIndex)
+ if not section:
+ print "Did not find a section with index %d" % extractIndex
+ return 1
+ (offset, length, index) = section
+ try:
+ bin_data = file(bin_filepath, "rb").read()
+ except (IOError), e:
+ print "Failed to read bin file: %s" % e.strerror
+ return 1
+ try:
+ outfile = file(outfilePath, "wb")
+ outfile.write(bin_data[offset : offset + length])
+ except IndexError:
+ print "Binfile index error."
+ return 1
+ except (IOError), e:
+ print "Failed to write output file: %s" % e.strerror
+ return 1
+ return 0
+
+def mergeSection(hdr_filepath, bin_filepath, mergeIndex, mergefilePath):
+ sections = parseHeaderFile(hdr_filepath, sortByOffset=True)
+ if not sections:
+ return 1
+ try:
+ bin_data = file(bin_filepath, "rb").read()
+ except (IOError), e:
+ print "Failed to read bin file: %s" % e.strerror
+ return 1
+ try:
+ merge_data = file(mergefilePath, "rb").read()
+ except (IOError), e:
+ print "Failed to open merge output file: %s" % e.strerror
+ return 1
+ newBin = []
+ newSections = []
+ newOffset = 0
+ foundIt = False
+ for section in sections:
+ (offset, length, index) = section
+ if index == mergeIndex:
+ if foundIt:
+ print "Confused. Multiple sections with index %d?" % index
+ return 1
+ foundIt = True
+ # We overwrite this section
+ newBin.append(merge_data)
+ newSections.append( (newOffset, len(merge_data), index) )
+ newOffset += len(merge_data)
+ else:
+ try:
+ newBin.append(bin_data[offset : offset + length])
+ except IndexError:
+ print "Failed to read input data"
+ return 1
+ newSections.append( (newOffset, length, index) )
+ newOffset += length
+ if not foundIt:
+ print "Did not find section with index %d" % mergeIndex
+ return 1
+ newBin = "".join(newBin)
+ newHdr = generateHeaderData(newSections)
+ try:
+ file(bin_filepath, "wb").write(newBin)
+ file(hdr_filepath, "wb").write(newHdr)
+ except (IOError), e:
+ print "Failed to write bin or header file: %s" % e.strerror
+ return 1
+ return 0
+
+def usage():
+ print "BRCM80211 firmware converter tool"
+ print ""
+ print "Usage: %s [OPTIONS]" % sys.argv[0]
+ print ""
+ print " -H|--header FILE Use FILE as header file"
+ print " -B|--bin FILE Use FILE as bin file"
+ print ""
+ print "Actions:"
+ print " -d|--dump Dump general information"
+ print " -x|--extract INDEX:FILE Extract the section with index INDEX to FILE"
+ print " -m|--merge INDEX:FILE Merges FILE into the bin file stream at INDEX"
+ print " A Merge modifies the files specified in -H and -B"
+ print ""
+ print " -h|--help Print this help text"
+
+def main():
+ opt_header = None
+ opt_bin = None
+ opt_action = None
+ opt_index = None
+ opt_outfile = None
+ opt_mergefile = None
+
+ try:
+ (opts, args) = getopt.getopt(sys.argv[1:],
+ "hH:B:dx:m:",
+ [ "help", "header=", "bin=", "dump", "extract=", "merge=", ])
+ except getopt.GetoptError:
+ usage()
+ return 1
+ for (o, v) in opts:
+ if o in ("-h", "--help"):
+ usage()
+ return 0;
+ if o in ("-H", "--header"):
+ opt_header = v
+ if o in ("-B", "--bin"):
+ opt_bin = v
+ if o in ("-d", "--dump"):
+ opt_action = "dump"
+ if o in ("-x", "--extract"):
+ opt_action = "extract"
+ try:
+ v = v.split(':')
+ opt_index = int(v[0])
+ opt_outfile = v[1]
+ except IndexError, ValueError:
+ print "Invalid -x|--extract index number\n"
+ usage()
+ return 1
+ if o in ("-m", "--merge"):
+ opt_action = "merge"
+ try:
+ v = v.split(':')
+ opt_index = int(v[0])
+ opt_mergefile = v[1]
+ except IndexError, ValueError:
+ print "Invalid -m|--merge index and/or merge file name\n"
+ usage()
+ return 1
+ if not opt_action:
+ print "No action specified\n"
+ usage()
+ return 1
+ if opt_action == "dump":
+ if not opt_header:
+ print "No header file specified\n"
+ usage()
+ return 1
+ return dumpInfo(opt_header)
+ elif opt_action == "extract":
+ if not opt_header or not opt_bin:
+ print "No header or bin file specified\n"
+ usage()
+ return 1
+ return extractSection(opt_header, opt_bin, opt_index, opt_outfile)
+ elif opt_action == "merge":
+ if not opt_header or not opt_bin:
+ print "No header or bin file specified\n"
+ usage()
+ return 1
+ return mergeSection(opt_header, opt_bin, opt_index, opt_mergefile)
+ return 1
+
+if __name__ == "__main__":
+ sys.exit(main())
+++ /dev/null
-#!/usr/bin/env python
-"""
-# Copyright (C) 2010 Michael Buesch <mb@bu3sch.de>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 2
-# as published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-"""
-
-import sys
-import getopt
-
-def indexToName(index):
- D11UCODE_NAMETAG_START = 0
- D11LCN0BSINITVALS24 = 1
- D11LCN0INITVALS24 = 2
- D11LCN1BSINITVALS24 = 3
- D11LCN1INITVALS24 = 4
- D11LCN2BSINITVALS24 = 5
- D11LCN2INITVALS24 = 6
- D11N0ABSINITVALS16 = 7
- D11N0BSINITVALS16 = 8
- D11N0INITVALS16 = 9
- D11UCODE_OVERSIGHT16_MIMO = 10
- D11UCODE_OVERSIGHT16_MIMOSZ = 11
- D11UCODE_OVERSIGHT24_LCN = 12
- D11UCODE_OVERSIGHT24_LCNSZ = 13
- D11UCODE_OVERSIGHT_BOMMAJOR = 14
- D11UCODE_OVERSIGHT_BOMMINOR = 15
-
- namemap = {
- D11UCODE_NAMETAG_START : "start",
- D11LCN0BSINITVALS24 : "LCN0 bs initvals 24",
- D11LCN0INITVALS24 : "LCN0 initvals 24",
- D11LCN1BSINITVALS24 : "LCN1 bs initvals 24",
- D11LCN1INITVALS24 : "LCN1 initvals 24",
- D11LCN2BSINITVALS24 : "LCN2 bs initvals 24",
- D11LCN2INITVALS24 : "LCN2 initvals 24",
- D11N0ABSINITVALS16 : "N0A bs initvals 16",
- D11N0BSINITVALS16 : "N0 bs initvals 16",
- D11N0INITVALS16 : "N0 initvals 16",
- D11UCODE_OVERSIGHT16_MIMO : "microcode 16 MIMO",
- D11UCODE_OVERSIGHT16_MIMOSZ : "microcode 16 MIMO size",
- D11UCODE_OVERSIGHT24_LCN : "microcode 24 LCN",
- D11UCODE_OVERSIGHT24_LCNSZ : "microcode 24 LCN size",
- D11UCODE_OVERSIGHT_BOMMAJOR : "bom major",
- D11UCODE_OVERSIGHT_BOMMINOR : "bom minor",
- }
- try:
- return namemap[index]
- except KeyError:
- return "Unknown"
-
-def parseHeader(hdr_data, sortByOffset):
- sections = []
- for i in range(0, len(hdr_data), 3 * 4):
- offset = ord(hdr_data[i + 0]) | (ord(hdr_data[i + 1]) << 8) |\
- (ord(hdr_data[i + 2]) << 16) | (ord(hdr_data[i + 3]) << 24)
- length = ord(hdr_data[i + 4]) | (ord(hdr_data[i + 5]) << 8) |\
- (ord(hdr_data[i + 6]) << 16) | (ord(hdr_data[i + 7]) << 24)
- index = ord(hdr_data[i + 8]) | (ord(hdr_data[i + 9]) << 8) |\
- (ord(hdr_data[i + 10]) << 16) | (ord(hdr_data[i + 11]) << 24)
-
- sections.append( (offset, length, index) )
- if sortByOffset:
- sections.sort(key = lambda x: x[0]) # Sort by offset
- else:
- sections.sort(key = lambda x: x[2]) # Sort by index
- return sections
-
-def generateHeaderData(sections):
- data = []
- for section in sections:
- (offset, length, index) = section
- data.append(chr(offset & 0xFF))
- data.append(chr((offset >> 8) & 0xFF))
- data.append(chr((offset >> 16) & 0xFF))
- data.append(chr((offset >> 24) & 0xFF))
- data.append(chr(length & 0xFF))
- data.append(chr((length >> 8) & 0xFF))
- data.append(chr((length >> 16) & 0xFF))
- data.append(chr((length >> 24) & 0xFF))
- data.append(chr(index & 0xFF))
- data.append(chr((index >> 8) & 0xFF))
- data.append(chr((index >> 16) & 0xFF))
- data.append(chr((index >> 24) & 0xFF))
- return "".join(data)
-
-def getSectionByIndex(sections, searchIndex):
- for section in sections:
- (offset, length, index) = section
- if searchIndex == index:
- return section
- return None
-
-def parseHeaderFile(hdr_filepath, sortByOffset=False):
- try:
- hdr_data = file(hdr_filepath, "rb").read()
- except (IOError), e:
- print "Failed to read header file: %s" % e.strerror
- return None
- if len(hdr_data) % (3 * 4) != 0:
- print "Invalid header file format"
- return None
- return parseHeader(hdr_data, sortByOffset)
-
-def dumpInfo(hdr_filepath):
- sections = parseHeaderFile(hdr_filepath)
- if not sections:
- return 1
- for section in sections:
- (offset, length, index) = section
- print "Index %2d %24s ==> offset:0x%08X length:0x%08X" %\
- (index, indexToName(index), offset, length)
- return 0
-
-def extractSection(hdr_filepath, bin_filepath, extractIndex, outfilePath):
- sections = parseHeaderFile(hdr_filepath)
- if not sections:
- return 1
- section = getSectionByIndex(sections, extractIndex)
- if not section:
- print "Did not find a section with index %d" % extractIndex
- return 1
- (offset, length, index) = section
- try:
- bin_data = file(bin_filepath, "rb").read()
- except (IOError), e:
- print "Failed to read bin file: %s" % e.strerror
- return 1
- try:
- outfile = file(outfilePath, "wb")
- outfile.write(bin_data[offset : offset + length])
- except IndexError:
- print "Binfile index error."
- return 1
- except (IOError), e:
- print "Failed to write output file: %s" % e.strerror
- return 1
- return 0
-
-def mergeSection(hdr_filepath, bin_filepath, mergeIndex, mergefilePath):
- sections = parseHeaderFile(hdr_filepath, sortByOffset=True)
- if not sections:
- return 1
- try:
- bin_data = file(bin_filepath, "rb").read()
- except (IOError), e:
- print "Failed to read bin file: %s" % e.strerror
- return 1
- try:
- merge_data = file(mergefilePath, "rb").read()
- except (IOError), e:
- print "Failed to open merge output file: %s" % e.strerror
- return 1
- newBin = []
- newSections = []
- newOffset = 0
- foundIt = False
- for section in sections:
- (offset, length, index) = section
- if index == mergeIndex:
- if foundIt:
- print "Confused. Multiple sections with index %d?" % index
- return 1
- foundIt = True
- # We overwrite this section
- newBin.append(merge_data)
- newSections.append( (newOffset, len(merge_data), index) )
- newOffset += len(merge_data)
- else:
- try:
- newBin.append(bin_data[offset : offset + length])
- except IndexError:
- print "Failed to read input data"
- return 1
- newSections.append( (newOffset, length, index) )
- newOffset += length
- if not foundIt:
- print "Did not find section with index %d" % mergeIndex
- return 1
- newBin = "".join(newBin)
- newHdr = generateHeaderData(newSections)
- try:
- file(bin_filepath, "wb").write(newBin)
- file(hdr_filepath, "wb").write(newHdr)
- except (IOError), e:
- print "Failed to write bin or header file: %s" % e.strerror
- return 1
- return 0
-
-def usage():
- print "BRCM80211 firmware converter tool"
- print ""
- print "Usage: %s [OPTIONS]" % sys.argv[0]
- print ""
- print " -H|--header FILE Use FILE as header file"
- print " -B|--bin FILE Use FILE as bin file"
- print ""
- print "Actions:"
- print " -d|--dump Dump general information"
- print " -x|--extract INDEX:FILE Extract the section with index INDEX to FILE"
- print " -m|--merge INDEX:FILE Merges FILE into the bin file stream at INDEX"
- print " A Merge modifies the files specified in -H and -B"
- print ""
- print " -h|--help Print this help text"
-
-def main():
- opt_header = None
- opt_bin = None
- opt_action = None
- opt_index = None
- opt_outfile = None
- opt_mergefile = None
-
- try:
- (opts, args) = getopt.getopt(sys.argv[1:],
- "hH:B:dx:m:",
- [ "help", "header=", "bin=", "dump", "extract=", "merge=", ])
- except getopt.GetoptError:
- usage()
- return 1
- for (o, v) in opts:
- if o in ("-h", "--help"):
- usage()
- return 0;
- if o in ("-H", "--header"):
- opt_header = v
- if o in ("-B", "--bin"):
- opt_bin = v
- if o in ("-d", "--dump"):
- opt_action = "dump"
- if o in ("-x", "--extract"):
- opt_action = "extract"
- try:
- v = v.split(':')
- opt_index = int(v[0])
- opt_outfile = v[1]
- except IndexError, ValueError:
- print "Invalid -x|--extract index number\n"
- usage()
- return 1
- if o in ("-m", "--merge"):
- opt_action = "merge"
- try:
- v = v.split(':')
- opt_index = int(v[0])
- opt_mergefile = v[1]
- except IndexError, ValueError:
- print "Invalid -m|--merge index and/or merge file name\n"
- usage()
- return 1
- if not opt_action:
- print "No action specified\n"
- usage()
- return 1
- if opt_action == "dump":
- if not opt_header:
- print "No header file specified\n"
- usage()
- return 1
- return dumpInfo(opt_header)
- elif opt_action == "extract":
- if not opt_header or not opt_bin:
- print "No header or bin file specified\n"
- usage()
- return 1
- return extractSection(opt_header, opt_bin, opt_index, opt_outfile)
- elif opt_action == "merge":
- if not opt_header or not opt_bin:
- print "No header or bin file specified\n"
- usage()
- return 1
- return mergeSection(opt_header, opt_bin, opt_index, opt_mergefile)
- return 1
-
-if __name__ == "__main__":
- sys.exit(main())