diff --git a/scripts/acpi_extract.py b/scripts/acpi_extract.py
index 8975b31..60bbac3 100755
--- a/scripts/acpi_extract.py
+++ b/scripts/acpi_extract.py
@@ -38,9 +38,9 @@
 # 
 # ACPI_EXTRACT is not allowed anywhere else in code, except in comments.
 
-import re;
-import sys;
-import fileinput;
+import re
+import sys
+import fileinput
 
 aml = []
 asl = []
@@ -55,7 +55,7 @@ class asl_line:
 def die(diag):
     sys.stderr.write("Error: %s; %s\n" % (diag, debug))
     sys.exit(1)
-    
+
 #Store an ASL command, matching AML offset, and input line (for debugging)
 def add_asl(lineno, line):
     l = asl_line()
@@ -67,28 +67,28 @@ def add_asl(lineno, line):
 #Store an AML byte sequence
 #Verify that offset output by iasl matches # of bytes so far
 def add_aml(offset, line):
-    o = int(offset, 16);
+    o = int(offset, 16)
     # Sanity check: offset must match size of code so far
     if (o != len(aml)):
         die("Offset 0x%x != 0x%x" % (o, len(aml)))
     # Strip any trailing dots and ASCII dump after "
-    line = re.sub(r'\s*\.*\s*".*$',"", line)
+    line = re.sub(r'\s*\.*\s*".*$', "", line)
     # Strip traling whitespace
-    line = re.sub(r'\s+$',"", line)
+    line = re.sub(r'\s+$', "", line)
     # Strip leading whitespace
-    line = re.sub(r'^\s+',"", line)
+    line = re.sub(r'^\s+', "", line)
     # Split on whitespace
     code = re.split(r'\s+', line)
     for c in code:
         # Require a legal hex number, two digits
         if (not(re.search(r'^[0-9A-Fa-f][0-9A-Fa-f]$', c))):
-            die("Unexpected octet %s" % c);
-        aml.append(int(c, 16));
+            die("Unexpected octet %s" % c)
+        aml.append(int(c, 16))
 
 # Process aml bytecode array, decoding AML
 def aml_pkglen_bytes(offset):
     # PkgLength can be multibyte. Bits 8-7 give the # of extra bytes.
-    pkglenbytes = aml[offset] >> 6;
+    pkglenbytes = aml[offset] >> 6
     return pkglenbytes + 1
 
 def aml_pkglen(offset):
@@ -113,23 +113,23 @@ def aml_method_string(offset):
     #0x14 MethodOp PkgLength NameString MethodFlags TermList
     if (aml[offset] != 0x14):
         die( "Method offset 0x%x: expected 0x14 actual 0x%x" %
-             (offset, aml[offset]));
-    offset += 1;
+             (offset, aml[offset]))
+    offset += 1
     pkglenbytes = aml_pkglen_bytes(offset)
-    offset += pkglenbytes;
-    return offset;
+    offset += pkglenbytes
+    return offset
 
 # Given name offset, find its NameString offset
 def aml_name_string(offset):
     #0x08 NameOp NameString DataRef
     if (aml[offset] != 0x08):
         die( "Name offset 0x%x: expected 0x08 actual 0x%x" %
-             (offset, aml[offset]));
+             (offset, aml[offset]))
     offset += 1
     # Block Name Modifier. Skip it.
     if (aml[offset] == 0x5c or aml[offset] == 0x5e):
         offset += 1
-    return offset;
+    return offset
 
 # Given data offset, find 8 byte buffer offset
 def aml_data_buffer8(offset):
@@ -145,24 +145,24 @@ def aml_data_dword_const(offset):
     #0x08 NameOp NameString DataRef
     if (aml[offset] != 0x0C):
         die( "Name offset 0x%x: expected 0x0C actual 0x%x" %
-             (offset, aml[offset]));
-    return offset + 1;
+             (offset, aml[offset]))
+    return offset + 1
 
 # Given data offset, find word const offset
 def aml_data_word_const(offset):
     #0x08 NameOp NameString DataRef
     if (aml[offset] != 0x0B):
         die( "Name offset 0x%x: expected 0x0B actual 0x%x" %
-             (offset, aml[offset]));
-    return offset + 1;
+             (offset, aml[offset]))
+    return offset + 1
 
 # Given data offset, find byte const offset
 def aml_data_byte_const(offset):
     #0x08 NameOp NameString DataRef
     if (aml[offset] != 0x0A):
         die( "Name offset 0x%x: expected 0x0A actual 0x%x" %
-             (offset, aml[offset]));
-    return offset + 1;
+             (offset, aml[offset]))
+    return offset + 1
 
 # Find name'd buffer8
 def aml_name_buffer8(offset):
@@ -184,7 +184,7 @@ def aml_device_start(offset):
     #0x5B 0x82 DeviceOp PkgLength NameString
     if ((aml[offset] != 0x5B) or (aml[offset + 1] != 0x82)):
         die( "Name offset 0x%x: expected 0x5B 0x82 actual 0x%x 0x%x" %
-             (offset, aml[offset], aml[offset + 1]));
+             (offset, aml[offset], aml[offset + 1]))
     return offset
 
 def aml_device_string(offset):
@@ -206,7 +206,7 @@ def aml_processor_start(offset):
     #0x5B 0x83 ProcessorOp PkgLength NameString ProcID
     if ((aml[offset] != 0x5B) or (aml[offset + 1] != 0x83)):
         die( "Name offset 0x%x: expected 0x5B 0x83 actual 0x%x 0x%x" %
-             (offset, aml[offset], aml[offset + 1]));
+             (offset, aml[offset], aml[offset + 1]))
     return offset
 
 def aml_processor_string(offset):
@@ -229,14 +229,14 @@ def aml_package_start(offset):
     # 0x12 PkgLength NumElements PackageElementList
     if (aml[offset] != 0x12):
         die( "Name offset 0x%x: expected 0x12 actual 0x%x" %
-             (offset, aml[offset]));
+             (offset, aml[offset]))
     offset += 1
     return offset + aml_pkglen_bytes(offset) + 1
 
 lineno = 0
 for line in fileinput.input():
     # Strip trailing newline
-    line = line.rstrip();
+    line = line.rstrip()
     # line number and debug string to output in case of errors
     lineno = lineno + 1
     debug = "input line %d: %s" % (lineno, line)
@@ -244,7 +244,7 @@ for line in fileinput.input():
     pasl = re.compile('^\s+([0-9]+)(:\s\s|\.\.\.\.)\s*')
     m = pasl.search(line)
     if (m):
-        add_asl(lineno, pasl.sub("", line));
+        add_asl(lineno, pasl.sub("", line))
     # AML listing: offset in hex, then ...., then code
     paml = re.compile('^([0-9A-Fa-f]+)(:\s\s|\.\.\.\.)\s*')
     m = paml.search(line)
@@ -267,7 +267,7 @@ for i in range(len(asl)):
         # Ignore any non-words for the purpose of this test.
         m = re.search(r'\w+', l)
         if (m):
-                prev_aml_offset = asl[i].aml_offset
+            prev_aml_offset = asl[i].aml_offset
         continue
 
     if (a > 1):
@@ -337,11 +337,11 @@ debug = "at end of file"
 def get_value_type(maxvalue):
     #Use type large enough to fit the table
     if (maxvalue >= 0x10000):
-            return "int"
+        return "int"
     elif (maxvalue >= 0x100):
-            return "short"
+        return "short"
     else:
-            return "char"
+        return "char"
 
 # Pretty print output
 for array in output.keys():
@@ -351,4 +351,4 @@ for array in output.keys():
         odata.append("0x%x" % value)
     sys.stdout.write("static unsigned %s %s[] = {\n" % (otype, array))
     sys.stdout.write(",\n".join(odata))
-    sys.stdout.write('\n};\n');
+    sys.stdout.write('\n};\n')
diff --git a/scripts/acpi_extract_preprocess.py b/scripts/acpi_extract_preprocess.py
index 4ae364e..6ef7df0 100755
--- a/scripts/acpi_extract_preprocess.py
+++ b/scripts/acpi_extract_preprocess.py
@@ -8,9 +8,9 @@
 # We also put each directive on a new line, the machinery
 # in tools/acpi_extract.py requires this.
 
-import re;
-import sys;
-import fileinput;
+import re
+import sys
+import fileinput
 
 def die(diag):
     sys.stderr.write("Error: %s\n" % (diag))
@@ -22,7 +22,7 @@ psplit = re.compile(r''' (
                           ACPI_EXTRACT_\w+ # directive
                           \s+ # some whitespace
                           \w+ # array name
-                         )''', re.VERBOSE);
+                         )''', re.VERBOSE)
 
 lineno = 0
 for line in fileinput.input():
@@ -30,7 +30,7 @@ for line in fileinput.input():
     lineno = lineno + 1
     debug = "input line %d: %s" % (lineno, line.rstrip())
 
-    s = psplit.split(line);
+    s = psplit.split(line)
     # The way split works, each odd item is the matching ACPI_EXTRACT directive.
     # Put each in a comment, and on a line by itself.
     for i in range(len(s)):
diff --git a/scripts/buildrom.py b/scripts/buildrom.py
index f2228ab..8e56d33 100755
--- a/scripts/buildrom.py
+++ b/scripts/buildrom.py
@@ -7,6 +7,8 @@
 
 import sys
 
+from python23compat import as_bytes
+
 def alignpos(pos, alignbytes):
     mask = alignbytes - 1
     return (pos + mask) & ~mask
@@ -26,16 +28,16 @@ def main():
     count = len(data)
 
     # Pad to a 512 byte boundary
-    data += "\0" * (alignpos(count, 512) - count)
+    data += as_bytes("\0" * (alignpos(count, 512) - count))
     count = len(data)
 
     # Check if a pci header is present
     pcidata = ord(data[24:25]) + (ord(data[25:26]) << 8)
     if pcidata != 0:
-        data = data[:pcidata + 16] + chr(count/512) + chr(0) + data[pcidata + 18:]
+        data = data[:pcidata + 16] + chr(int(count/512)) + chr(0) + data[pcidata + 18:]
 
     # Fill in size field; clear checksum field
-    data = data[:2] + chr(count/512) + data[3:6] + "\0" + data[7:]
+    data = data[:2] + chr(int(count/512)) + data[3:6] + as_bytes("\0") + data[7:]
 
     # Checksum rom
     newsum = (256 - checksum(data)) & 0xff
diff --git a/scripts/checkrom.py b/scripts/checkrom.py
index aa3dd0d..0a164f0 100755
--- a/scripts/checkrom.py
+++ b/scripts/checkrom.py
@@ -8,6 +8,8 @@
 import sys
 import layoutrom
 
+from python23compat import as_bytes
+
 def subst(data, offset, new):
     return data[:offset] + new + data[offset + len(new):]
 
@@ -25,7 +27,7 @@ def main():
 
     # Read in symbols
     objinfofile = open(objinfo, 'rb')
-    symbols = layoutrom.parseObjDump(objinfofile, 'in')[1]
+    symbols = layoutrom.parseObjDump(objinfofile, as_bytes('in'))[1]
 
     # Read in raw file
     f = open(rawfile, 'rb')
@@ -40,40 +42,40 @@ def main():
             if datasize > 128*1024:
                 finalsize = 256*1024
     if datasize > finalsize:
-        print "Error!  ROM doesn't fit (%d > %d)" % (datasize, finalsize)
-        print "   You have to either increate the size (CONFIG_ROM_SIZE)"
-        print "   or turn off some features (such as hardware support not"
-        print "   needed) to make it fit.  Trying a more recent gcc version"
-        print "   might work too."
+        print("Error!  ROM doesn't fit (%d > %d)" % (datasize, finalsize))
+        print("   You have to either increate the size (CONFIG_ROM_SIZE)")
+        print("   or turn off some features (such as hardware support not")
+        print("   needed) to make it fit.  Trying a more recent gcc version")
+        print("   might work too.")
         sys.exit(1)
 
     # Sanity checks
-    start = symbols['code32flat_start'].offset
-    end = symbols['code32flat_end'].offset
+    start = symbols[as_bytes('code32flat_start')].offset
+    end = symbols[as_bytes('code32flat_end')].offset
     expend = layoutrom.BUILD_BIOS_ADDR + layoutrom.BUILD_BIOS_SIZE
     if end != expend:
-        print "Error!  Code does not end at 0x%x (got 0x%x)" % (
-            expend, end)
+        print("Error!  Code does not end at 0x%x (got 0x%x)" % (
+            expend, end))
         sys.exit(1)
     if datasize > finalsize:
-        print "Error!  Code is too big (0x%x vs 0x%x)" % (
-            datasize, finalsize)
+        print("Error!  Code is too big (0x%x vs 0x%x)" % (
+            datasize, finalsize))
         sys.exit(1)
     expdatasize = end - start
     if datasize != expdatasize:
-        print "Error!  Unknown extra data (0x%x vs 0x%x)" % (
-            datasize, expdatasize)
+        print("Error!  Unknown extra data (0x%x vs 0x%x)" % (
+            datasize, expdatasize))
         sys.exit(1)
 
     # Fix up CSM Compatibility16 table
-    if 'csm_compat_table' in symbols and 'entry_csm' in symbols:
+    if as_bytes('csm_compat_table') in symbols and as_bytes('entry_csm') in symbols:
         # Field offsets within EFI_COMPATIBILITY16_TABLE
         ENTRY_FIELD_OFS = 14 # Compatibility16CallOffset (UINT16)
         SIZE_FIELD_OFS = 5   # TableLength (UINT8)
         CSUM_FIELD_OFS = 4   # TableChecksum (UINT8)
 
-        tableofs = symbols['csm_compat_table'].offset - symbols['code32flat_start'].offset
-        entry_addr = symbols['entry_csm'].offset - layoutrom.BUILD_BIOS_ADDR
+        tableofs = symbols[as_bytes('csm_compat_table')].offset - symbols[as_bytes('code32flat_start')].offset
+        entry_addr = symbols[as_bytes('entry_csm')].offset - layoutrom.BUILD_BIOS_ADDR
         byte1 = chr(entry_addr & 0xff)
         byte2 = chr(entry_addr >> 8)
         rawdata = subst(rawdata, tableofs+ENTRY_FIELD_OFS, byte1+byte2)
@@ -82,15 +84,15 @@ def main():
         rawdata = checksum(rawdata, tableofs, tablesize, CSUM_FIELD_OFS)
 
     # Print statistics
-    runtimesize = end - symbols['code32init_end'].offset
-    print "Total size: %d  Fixed: %d  Free: %d (used %.1f%% of %dKiB rom)" % (
+    runtimesize = end - symbols[as_bytes('code32init_end')].offset
+    print("Total size: %d  Fixed: %d  Free: %d (used %.1f%% of %dKiB rom)" % (
         datasize, runtimesize, finalsize - datasize
         , (datasize / float(finalsize)) * 100.0
-        , finalsize / 1024)
+        , int(finalsize / 1024)))
 
     # Write final file
     f = open(outfile, 'wb')
-    f.write(("\0" * (finalsize - datasize)) + rawdata)
+    f.write(as_bytes(("\0" * (finalsize - datasize))) + rawdata)
     f.close()
 
 if __name__ == '__main__':
diff --git a/scripts/checkstack.py b/scripts/checkstack.py
index 23b7c8e..62fef36 100755
--- a/scripts/checkstack.py
+++ b/scripts/checkstack.py
@@ -182,12 +182,12 @@ def calc():
                 elif insn.startswith('calll'):
                     noteCall(cur, subfuncs, insnaddr, calladdr, stackusage + 4)
                 else:
-                    print "unknown call", ref
+                    print("unknown call", ref)
                     noteCall(cur, subfuncs, insnaddr, calladdr, stackusage)
             # Reset stack usage to preamble usage
             stackusage = cur[1]
 
-        #print "other", repr(line)
+        #print("other", repr(line))
 
     # Calculate maxstackusage
     for funcaddr, info in funcs.items():
@@ -199,7 +199,7 @@ def calc():
     funcaddrs = orderfuncs(funcs.keys(), funcs.copy())
 
     # Show all functions
-    print OUTPUTDESC
+    print(OUTPUTDESC)
     for funcaddr in funcaddrs:
         name, basicusage, maxusage, yieldusage, maxyieldusage, count, calls = \
             funcs[funcaddr]
@@ -208,15 +208,15 @@ def calc():
         yieldstr = ""
         if maxyieldusage is not None:
             yieldstr = ",%d" % maxyieldusage
-        print "\n%s[%d,%d%s]:" % (name, basicusage, maxusage, yieldstr)
+        print("\n%s[%d,%d%s]:" % (name, basicusage, maxusage, yieldstr))
         for insnaddr, calladdr, stackusage in calls:
             callinfo = funcs.get(calladdr, ("<unknown>", 0, 0, 0, None))
             yieldstr = ""
             if callinfo[4] is not None:
                 yieldstr = ",%d" % (stackusage + callinfo[4])
-            print "    %04s:%-40s [%d+%d,%d%s]" % (
+            print("    %04s:%-40s [%d+%d,%d%s]" % (
                 insnaddr, callinfo[0], stackusage, callinfo[1]
-                , stackusage+callinfo[2], yieldstr)
+                , stackusage+callinfo[2], yieldstr))
 
 def main():
     calc()
diff --git a/scripts/checksum.py b/scripts/checksum.py
index 8c7665d..773fa7a 100755
--- a/scripts/checksum.py
+++ b/scripts/checksum.py
@@ -10,7 +10,7 @@ import sys
 def main():
     data = sys.stdin.read()
     ords = map(ord, data)
-    print "sum=%x\n" % sum(ords)
+    print("sum=%x\n" % sum(ords))
 
 if __name__ == '__main__':
     main()
diff --git a/scripts/layoutrom.py b/scripts/layoutrom.py
index 24cd7a4..5e3e7f9 100755
--- a/scripts/layoutrom.py
+++ b/scripts/layoutrom.py
@@ -5,17 +5,20 @@
 #
 # This file may be distributed under the terms of the GNU GPLv3 license.
 
+import operator
 import sys
 
+from python23compat import as_bytes, as_str
+
 # LD script headers/trailers
-COMMONHEADER = """
+COMMONHEADER = as_bytes("""
 /* DO NOT EDIT!  This is an autogenerated file.  See tools/layoutrom.py. */
 OUTPUT_FORMAT("elf32-i386")
 OUTPUT_ARCH("i386")
 SECTIONS
 {
-"""
-COMMONTRAILER = """
+""")
+COMMONTRAILER = as_bytes("""
 
         /* Discard regular data sections to force a link error if
          * code attempts to access data not marked with VAR16 (or other
@@ -26,7 +29,7 @@ COMMONTRAILER = """
                 *(COMMON) *(.discard*) *(.eh_frame) *(.note*)
                 }
 }
-"""
+""")
 
 
 ######################################################################
@@ -46,7 +49,7 @@ def setSectionsStart(sections, endaddr, minalign=1, segoffset=0):
         if section.align > minalign:
             minalign = section.align
         totspace = alignpos(totspace, section.align) + section.size
-    startaddr = (endaddr - totspace) / minalign * minalign
+    startaddr = int((endaddr - totspace) / minalign) * minalign
     curaddr = startaddr
     for section in sections:
         curaddr = alignpos(curaddr, section.align)
@@ -70,16 +73,16 @@ def fitSections(sections, fillsections):
     # fixedsections = [(addr, section), ...]
     fixedsections = []
     for section in sections:
-        if section.name.startswith('.fixedaddr.'):
+        if section.name.startswith(as_bytes('.fixedaddr.')):
             addr = int(section.name[11:], 16)
             section.finalloc = addr + BUILD_BIOS_ADDR
             section.finalsegloc = addr
             fixedsections.append((addr, section))
             if section.align != 1:
-                print "Error: Fixed section %s has non-zero alignment (%d)" % (
-                    section.name, section.align)
+                print("Error: Fixed section %s has non-zero alignment (%d)" % (
+                    as_str(section.name), section.align))
                 sys.exit(1)
-    fixedsections.sort()
+    fixedsections.sort(key=operator.itemgetter(0))
     firstfixed = fixedsections[0][0]
 
     # Find freespace in fixed address area
@@ -94,7 +97,7 @@ def fitSections(sections, fillsections):
             nextaddr = fixedsections[i+1][0]
         avail = nextaddr - addr - section.size
         fixedAddr.append((avail, section))
-    fixedAddr.sort()
+    fixedAddr.sort(key=operator.itemgetter(0))
 
     # Attempt to fit other sections into fixed area
     canrelocate = [(section.size, section.align, section.name, section)
@@ -106,8 +109,8 @@ def fitSections(sections, fillsections):
         addpos = fixedsection.finalsegloc + fixedsection.size
         totalused += fixedsection.size
         nextfixedaddr = addpos + freespace
-#        print "Filling section %x uses %d, next=%x, available=%d" % (
-#            fixedsection.finalloc, fixedsection.size, nextfixedaddr, freespace)
+#        print("Filling section %x uses %d, next=%x, available=%d" % (
+#            fixedsection.finalloc, fixedsection.size, nextfixedaddr, freespace))
         while 1:
             canfit = None
             for fitsection in canrelocate:
@@ -115,8 +118,8 @@ def fitSections(sections, fillsections):
                     # Can't fit and nothing else will fit.
                     break
                 fitnextaddr = alignpos(addpos, fitsection.align) + fitsection.size
-#                print "Test %s - %x vs %x" % (
-#                    fitsection.name, fitnextaddr, nextfixedaddr)
+#                print("Test %s - %x vs %x" % (
+#                    fitsection.name, fitnextaddr, nextfixedaddr))
                 if fitnextaddr > nextfixedaddr:
                     # This item can't fit.
                     continue
@@ -130,9 +133,9 @@ def fitSections(sections, fillsections):
             fitsection.finalsegloc = addpos
             addpos = fitnextaddr
             totalused += fitsection.size
-#            print "    Adding %s (size %d align %d) pos=%x avail=%d" % (
+#            print("    Adding %s (size %d align %d) pos=%x avail=%d" % (
 #                fitsection[2], fitsection[0], fitsection[1]
-#                , fitnextaddr, nextfixedaddr - fitnextaddr)
+#                , fitnextaddr, nextfixedaddr - fitnextaddr))
 
     # Report stats
     total = BUILD_BIOS_SIZE-firstfixed
@@ -172,14 +175,14 @@ def doLayout(sections, config, genreloc):
     li = LayoutInfo()
     li.genreloc = genreloc
     # Determine 16bit positions
-    li.sections16 = getSectionsCategory(sections, '16')
-    textsections = getSectionsPrefix(li.sections16, '.text.')
+    li.sections16 = getSectionsCategory(sections, as_bytes('16'))
+    textsections = getSectionsPrefix(li.sections16, as_bytes('.text.'))
     rodatasections = (
-        getSectionsPrefix(li.sections16, '.rodata.str1.1')
-        + getSectionsPrefix(li.sections16, '.rodata.__func__.')
-        + getSectionsPrefix(li.sections16, '.rodata.__PRETTY_FUNCTION__.'))
-    datasections = getSectionsPrefix(li.sections16, '.data16.')
-    fixedsections = getSectionsPrefix(li.sections16, '.fixedaddr.')
+        getSectionsPrefix(li.sections16, as_bytes('.rodata.str1.1'))
+        + getSectionsPrefix(li.sections16, as_bytes('.rodata.__func__.'))
+        + getSectionsPrefix(li.sections16, as_bytes('.rodata.__PRETTY_FUNCTION__.')))
+    datasections = getSectionsPrefix(li.sections16, as_bytes('.data16.'))
+    fixedsections = getSectionsPrefix(li.sections16, as_bytes('.fixedaddr.'))
 
     firstfixed = fitSections(fixedsections, textsections)
     remsections = [s for s in textsections+rodatasections+datasections
@@ -188,42 +191,42 @@ def doLayout(sections, config, genreloc):
         remsections, firstfixed, segoffset=BUILD_BIOS_ADDR)
 
     # Determine 32seg positions
-    li.sections32seg = getSectionsCategory(sections, '32seg')
-    textsections = getSectionsPrefix(li.sections32seg, '.text.')
+    li.sections32seg = getSectionsCategory(sections, as_bytes('32seg'))
+    textsections = getSectionsPrefix(li.sections32seg, as_bytes('.text.'))
     rodatasections = (
-        getSectionsPrefix(li.sections32seg, '.rodata.str1.1')
-        + getSectionsPrefix(li.sections32seg, '.rodata.__func__.')
-        + getSectionsPrefix(li.sections32seg, '.rodata.__PRETTY_FUNCTION__.'))
-    datasections = getSectionsPrefix(li.sections32seg, '.data32seg.')
+        getSectionsPrefix(li.sections32seg, as_bytes('.rodata.str1.1'))
+        + getSectionsPrefix(li.sections32seg, as_bytes('.rodata.__func__.'))
+        + getSectionsPrefix(li.sections32seg, as_bytes('.rodata.__PRETTY_FUNCTION__.')))
+    datasections = getSectionsPrefix(li.sections32seg, as_bytes('.data32seg.'))
 
     li.sec32seg_start, li.sec32seg_align = setSectionsStart(
         textsections + rodatasections + datasections, li.sec16_start
         , segoffset=BUILD_BIOS_ADDR)
 
     # Determine "fseg memory" data positions
-    li.sections32fseg = getSectionsCategory(sections, '32fseg')
+    li.sections32fseg = getSectionsCategory(sections, as_bytes('32fseg'))
 
     li.sec32fseg_start, li.sec32fseg_align = setSectionsStart(
         li.sections32fseg, li.sec32seg_start, 16
         , segoffset=BUILD_BIOS_ADDR)
 
     # Determine 32flat runtime positions
-    li.sections32flat = getSectionsCategory(sections, '32flat')
-    textsections = getSectionsPrefix(li.sections32flat, '.text.')
-    rodatasections = getSectionsPrefix(li.sections32flat, '.rodata')
-    datasections = getSectionsPrefix(li.sections32flat, '.data.')
-    bsssections = getSectionsPrefix(li.sections32flat, '.bss.')
+    li.sections32flat = getSectionsCategory(sections, as_bytes('32flat'))
+    textsections = getSectionsPrefix(li.sections32flat, as_bytes('.text.'))
+    rodatasections = getSectionsPrefix(li.sections32flat, as_bytes('.rodata'))
+    datasections = getSectionsPrefix(li.sections32flat, as_bytes('.data.'))
+    bsssections = getSectionsPrefix(li.sections32flat, as_bytes('.bss.'))
 
     li.sec32flat_start, li.sec32flat_align = setSectionsStart(
         textsections + rodatasections + datasections + bsssections
         , li.sec32fseg_start, 16)
 
     # Determine 32flat init positions
-    li.sections32init = getSectionsCategory(sections, '32init')
-    init32_textsections = getSectionsPrefix(li.sections32init, '.text.')
-    init32_rodatasections = getSectionsPrefix(li.sections32init, '.rodata')
-    init32_datasections = getSectionsPrefix(li.sections32init, '.data.')
-    init32_bsssections = getSectionsPrefix(li.sections32init, '.bss.')
+    li.sections32init = getSectionsCategory(sections, as_bytes('32init'))
+    init32_textsections = getSectionsPrefix(li.sections32init, as_bytes('.text.'))
+    init32_rodatasections = getSectionsPrefix(li.sections32init, as_bytes('.rodata'))
+    init32_datasections = getSectionsPrefix(li.sections32init, as_bytes('.data.'))
+    init32_bsssections = getSectionsPrefix(li.sections32init, as_bytes('.bss.'))
 
     li.sec32init_start, li.sec32init_align = setSectionsStart(
         init32_textsections + init32_rodatasections
@@ -251,9 +254,9 @@ def doLayout(sections, config, genreloc):
         li.final_readonly_start = min(BUILD_BIOS_ADDR, li.sec32init_start)
 
     # Determine "low memory" data positions
-    li.sections32low = getSectionsCategory(sections, '32low')
+    li.sections32low = getSectionsCategory(sections, as_bytes('32low'))
     sec32low_end = li.sec32init_start
-    if config.get('CONFIG_MALLOC_UPPERMEMORY'):
+    if config.get(as_bytes('CONFIG_MALLOC_UPPERMEMORY')):
         final_sec32low_end = li.final_readonly_start
         zonelow_base = final_sec32low_end - 64*1024
         li.zonelow_base = max(BUILD_ROM_START, alignpos(zonelow_base, 2*1024))
@@ -273,12 +276,12 @@ def doLayout(sections, config, genreloc):
     size32flat = li.sec32fseg_start - li.sec32flat_start
     size32init = li.sec32flat_start - li.sec32init_start
     sizelow = sec32low_end - li.sec32low_start
-    print "16bit size:           %d" % size16
-    print "32bit segmented size: %d" % size32seg
-    print "32bit flat size:      %d" % size32flat
-    print "32bit flat init size: %d" % size32init
-    print "Lowmem size:          %d" % sizelow
-    print "f-segment var size:   %d" % size32fseg
+    print("16bit size:           %d" % size16)
+    print("32bit segmented size: %d" % size32seg)
+    print("32bit flat size:      %d" % size32flat)
+    print("32bit flat init size: %d" % size32init)
+    print("Lowmem size:          %d" % sizelow)
+    print("f-segment var size:   %d" % size32fseg)
     return li
 
 
@@ -289,7 +292,7 @@ def doLayout(sections, config, genreloc):
 # Write LD script includes for the given cross references
 def outXRefs(sections, useseg=0, exportsyms=[], forcedelta=0):
     xrefs = dict([(symbol.name, symbol) for symbol in exportsyms])
-    out = ""
+    out = as_bytes("")
     for section in sections:
         for reloc in section.relocs:
             symbol = reloc.symbol
@@ -301,32 +304,32 @@ def outXRefs(sections, useseg=0, exportsyms=[], forcedelta=0):
         loc = symbol.section.finalloc
         if useseg:
             loc = symbol.section.finalsegloc
-        out += "%s = 0x%x ;\n" % (symbolname, loc + forcedelta + symbol.offset)
+        out += as_bytes("%s = 0x%x ;\n" % (as_str(symbolname), loc + forcedelta + symbol.offset))
     return out
 
 # Write LD script includes for the given sections using relative offsets
 def outRelSections(sections, startsym, useseg=0):
     sections = [(section.finalloc, section) for section in sections
                 if section.finalloc is not None]
-    sections.sort()
-    out = ""
+    sections.sort(key=operator.itemgetter(0))
+    out = as_bytes("")
     for addr, section in sections:
         loc = section.finalloc
         if useseg:
             loc = section.finalsegloc
-        out += ". = ( 0x%x - %s ) ;\n" % (loc, startsym)
-        if section.name == '.rodata.str1.1':
-            out += "_rodata = . ;\n"
-        out += "*(%s)\n" % (section.name,)
+        out += as_bytes(". = ( 0x%x - %s ) ;\n" % (loc, as_str(startsym)))
+        if section.name == as_bytes('.rodata.str1.1'):
+            out += as_bytes("_rodata = . ;\n")
+        out += as_bytes("*(%s)\n" % (as_str(section.name),))
     return out
 
 # Build linker script output for a list of relocations.
 def strRelocs(outname, outrel, relocs):
     relocs.sort()
-    return ("        %s_start = ABSOLUTE(.) ;\n" % (outname,)
-            + "".join(["LONG(0x%x - %s)\n" % (pos, outrel)
+    return (as_bytes("        %s_start = ABSOLUTE(.) ;\n" % (as_str(outname),)
+            + "".join(["LONG(0x%x - %s)\n" % (pos, as_str(outrel))
                        for pos in relocs])
-            + "        %s_end = ABSOLUTE(.) ;\n" % (outname,))
+            + "        %s_end = ABSOLUTE(.) ;\n" % (as_str(outname),)))
 
 # Find all relocations in the given sections with the given attributes
 def getRelocs(sections, type=None, category=None, notcategory=None):
@@ -350,7 +353,7 @@ def getSectionsStart(sections, defaddr=0):
 # Output the linker scripts for all required sections.
 def writeLinkerScripts(li, out16, out32seg, out32flat):
     # Write 16bit linker script
-    out = outXRefs(li.sections16, useseg=1) + """
+    out = outXRefs(li.sections16, useseg=1) + as_bytes("""
     zonelow_base = 0x%x ;
     _zonelow_seg = 0x%x ;
 
@@ -359,21 +362,21 @@ def writeLinkerScripts(li, out16, out32seg, out32flat):
 %s
     }
 """ % (li.zonelow_base,
-       li.zonelow_base / 16,
+       int(li.zonelow_base / 16),
        li.sec16_start - BUILD_BIOS_ADDR,
-       outRelSections(li.sections16, 'code16_start', useseg=1))
+       as_str(outRelSections(li.sections16, as_bytes('code16_start'), useseg=1))))
     outfile = open(out16, 'wb')
     outfile.write(COMMONHEADER + out + COMMONTRAILER)
     outfile.close()
 
     # Write 32seg linker script
-    out = outXRefs(li.sections32seg, useseg=1) + """
+    out = outXRefs(li.sections32seg, useseg=1) + as_bytes("""
     code32seg_start = 0x%x ;
     .text32seg code32seg_start : {
 %s
     }
 """ % (li.sec32seg_start - BUILD_BIOS_ADDR,
-       outRelSections(li.sections32seg, 'code32seg_start', useseg=1))
+       as_str(outRelSections(li.sections32seg, as_bytes('code32seg_start'), useseg=1))))
     outfile = open(out32seg, 'wb')
     outfile.write(COMMONHEADER + out + COMMONTRAILER)
     outfile.close()
@@ -381,24 +384,24 @@ def writeLinkerScripts(li, out16, out32seg, out32flat):
     # Write 32flat linker script
     sections32all = (li.sections32flat + li.sections32init + li.sections32fseg)
     sec32all_start = li.sec32low_start
-    relocstr = ""
+    relocstr = as_bytes("")
     if li.genreloc:
         # Generate relocations
         absrelocs = getRelocs(
-            li.sections32init, type='R_386_32', category='32init')
+            li.sections32init, type=as_bytes('R_386_32'), category=as_bytes('32init'))
         relrelocs = getRelocs(
-            li.sections32init, type='R_386_PC32', notcategory='32init')
+            li.sections32init, type=as_bytes('R_386_PC32'), notcategory=as_bytes('32init'))
         initrelocs = getRelocs(
             li.sections32flat + li.sections32low + li.sections16
-            + li.sections32seg + li.sections32fseg, category='32init')
-        relocstr = (strRelocs("_reloc_abs", "code32init_start", absrelocs)
-                    + strRelocs("_reloc_rel", "code32init_start", relrelocs)
-                    + strRelocs("_reloc_init", "code32flat_start", initrelocs))
+            + li.sections32seg + li.sections32fseg, category=as_bytes('32init'))
+        relocstr = (strRelocs(as_bytes("_reloc_abs"), as_bytes("code32init_start"), absrelocs)
+                    + strRelocs(as_bytes("_reloc_rel"), as_bytes("code32init_start"), relrelocs)
+                    + strRelocs(as_bytes("_reloc_init"), as_bytes("code32flat_start"), initrelocs))
         numrelocs = len(absrelocs + relrelocs + initrelocs)
         sec32all_start -= numrelocs * 4
     out = outXRefs(li.sections32low, exportsyms=li.varlowsyms
                    , forcedelta=li.final_sec32low_start-li.sec32low_start)
-    out += outXRefs(sections32all, exportsyms=li.exportsyms) + """
+    out += outXRefs(sections32all, exportsyms=li.exportsyms) + as_bytes("""
     _reloc_min_align = 0x%x ;
     zonefseg_start = 0x%x ;
     zonefseg_end = 0x%x ;
@@ -430,20 +433,20 @@ def writeLinkerScripts(li, out16, out32seg, out32flat):
        li.final_sec32low_start,
        li.final_readonly_start,
        sec32all_start,
-       relocstr,
-       outRelSections(li.sections32low, 'code32flat_start'),
-       outRelSections(li.sections32init, 'code32flat_start'),
-       outRelSections(li.sections32flat, 'code32flat_start'),
-       outRelSections(li.sections32fseg, 'code32flat_start'),
+       as_str(relocstr),
+       as_str(outRelSections(li.sections32low, as_bytes('code32flat_start'))),
+       as_str(outRelSections(li.sections32init, as_bytes('code32flat_start'))),
+       as_str(outRelSections(li.sections32flat, as_bytes('code32flat_start'))),
+       as_str(outRelSections(li.sections32fseg, as_bytes('code32flat_start'))),
        li.sec32seg_start,
-       li.sec16_start)
-    out = COMMONHEADER + out + COMMONTRAILER + """
+       li.sec16_start))
+    out = COMMONHEADER + out + COMMONTRAILER + as_bytes("""
 ENTRY(entry_elf)
 PHDRS
 {
         text PT_LOAD AT ( code32flat_start ) ;
 }
-"""
+""")
     outfile = open(out32flat, 'wb')
     outfile.write(out)
     outfile.close()
@@ -455,13 +458,13 @@ PHDRS
 
 def markRuntime(section, sections, chain=[]):
     if (section is None or not section.keep or section.category is not None
-        or '.init.' in section.name or section.fileid != '32flat'):
+        or as_bytes('.init.') in section.name or section.fileid != as_bytes('32flat')):
         return
-    if '.data.varinit.' in section.name:
-        print "ERROR: %s is VARVERIFY32INIT but used from %s" % (
-            section.name, chain)
+    if as_bytes('.data.varinit.') in section.name:
+        print("ERROR: %s is VARVERIFY32INIT but used from %s" % (
+            as_str(section.name), chain))
         sys.exit(1)
-    section.category = '32flat'
+    section.category = as_bytes('32flat')
     # Recursively mark all sections this section points to
     for reloc in section.relocs:
         markRuntime(reloc.symbol.section, sections, chain + [section.name])
@@ -469,14 +472,14 @@ def markRuntime(section, sections, chain=[]):
 def findInit(sections):
     # Recursively find and mark all "runtime" sections.
     for section in sections:
-        if ('.data.varlow.' in section.name or '.data.varfseg.' in section.name
-            or '.runtime.' in section.name or '.export.' in section.name):
+        if (as_bytes('.data.varlow.') in section.name or as_bytes('.data.varfseg.') in section.name
+            or as_bytes('.runtime.') in section.name or as_bytes('.export.') in section.name):
             markRuntime(section, sections)
     for section in sections:
         if section.category is not None:
             continue
-        if section.fileid == '32flat':
-            section.category = '32init'
+        if section.fileid == as_bytes('32flat'):
+            section.category = as_bytes('32init')
         else:
             section.category = section.fileid
 
@@ -485,7 +488,7 @@ def findInit(sections):
 # Section garbage collection
 ######################################################################
 
-CFUNCPREFIX = [('_cfunc16_', 0), ('_cfunc32seg_', 1), ('_cfunc32flat_', 2)]
+CFUNCPREFIX = [(as_bytes('_cfunc16_'), 0), (as_bytes('_cfunc32seg_'), 1), (as_bytes('_cfunc32flat_'), 2)]
 
 # Find and keep the section associated with a symbol (if available).
 def keepsymbol(reloc, infos, pos, isxref):
@@ -500,10 +503,10 @@ def keepsymbol(reloc, infos, pos, isxref):
             break
     symbol = infos[pos][1].get(symbolname)
     if (symbol is None or symbol.section is None
-        or symbol.section.name.startswith('.discard.')):
+        or symbol.section.name.startswith(as_bytes('.discard.'))):
         return -1
-    isdestcfunc = (symbol.section.name.startswith('.text.')
-                   and not symbol.section.name.startswith('.text.asm.'))
+    isdestcfunc = (symbol.section.name.startswith(as_bytes('.text.'))
+                   and not symbol.section.name.startswith(as_bytes('.text.asm.')))
     if ((mustbecfunc and not isdestcfunc)
         or (not mustbecfunc and isdestcfunc and isxref)):
         return -1
@@ -540,7 +543,7 @@ def gc(info16, info32seg, info32flat):
     infos = (info16, info32seg, info32flat)
     # Start by keeping sections that are globally visible.
     for section in info16[0]:
-        if section.name.startswith('.fixedaddr.') or '.export.' in section.name:
+        if section.name.startswith(as_bytes('.fixedaddr.')) or as_bytes('.export.') in section.name:
             keepsection(section, infos)
     return [section for section in info16[0]+info32seg[0]+info32flat[0]
             if section.keep]
@@ -569,15 +572,15 @@ def parseObjDump(file, fileid):
     state = None
     for line in file.readlines():
         line = line.rstrip()
-        if line == 'Sections:':
+        if line == as_bytes('Sections:'):
             state = 'section'
             continue
-        if line == 'SYMBOL TABLE:':
+        if line == as_bytes('SYMBOL TABLE:'):
             state = 'symbol'
             continue
-        if line.startswith('RELOCATION RECORDS FOR ['):
+        if line.startswith(as_bytes('RELOCATION RECORDS FOR [')):
             sectionname = line[24:-2]
-            if sectionname.startswith('.debug_'):
+            if sectionname.startswith(as_bytes('.debug_')):
                 # Skip debugging sections (to reduce parsing time)
                 state = None
                 continue
@@ -588,7 +591,7 @@ def parseObjDump(file, fileid):
         if state == 'section':
             try:
                 idx, name, size, vma, lma, fileoff, align = line.split()
-                if align[:3] != '2**':
+                if align[:3] != as_bytes('2**'):
                     continue
                 section = Section()
                 section.name = name
@@ -606,7 +609,7 @@ def parseObjDump(file, fileid):
                 parts = line[17:].split()
                 if len(parts) == 3:
                     sectionname, size, name = parts
-                elif len(parts) == 4 and parts[2] == '.hidden':
+                elif len(parts) == 4 and parts[2] == as_bytes('.hidden'):
                     sectionname, size, hidden, name = parts
                 else:
                     continue
@@ -649,10 +652,10 @@ def scanconfig(file):
         parts = l.split()
         if len(parts) != 3:
             continue
-        if parts[0] != '#define':
+        if parts[0] != as_bytes('#define'):
             continue
         value = parts[2]
-        if value.isdigit() or (value.startswith('0x') and value[2:].isdigit()):
+        if value.isdigit() or (value.startswith(as_bytes('0x')) and value[2:].isdigit()):
             value = int(value, 0)
         opts[parts[1]] = value
     return opts
@@ -667,9 +670,9 @@ def main():
     infile32flat = open(in32flat, 'rb')
 
     # infoX = (sections, symbols)
-    info16 = parseObjDump(infile16, '16')
-    info32seg = parseObjDump(infile32seg, '32seg')
-    info32flat = parseObjDump(infile32flat, '32flat')
+    info16 = parseObjDump(infile16, as_bytes('16'))
+    info32seg = parseObjDump(infile32seg, as_bytes('32seg'))
+    info32flat = parseObjDump(infile32flat, as_bytes('32flat'))
 
     # Read kconfig config file
     config = scanconfig(cfgfile)
@@ -681,24 +684,24 @@ def main():
     findInit(sections)
 
     # Note "low memory" and "fseg memory" parts
-    for section in getSectionsPrefix(sections, '.data.varlow.'):
-        section.category = '32low'
-    for section in getSectionsPrefix(sections, '.data.varfseg.'):
-        section.category = '32fseg'
+    for section in getSectionsPrefix(sections, as_bytes('.data.varlow.')):
+        section.category = as_bytes('32low')
+    for section in getSectionsPrefix(sections, as_bytes('.data.varfseg.')):
+        section.category = as_bytes('32fseg')
 
     # Determine the final memory locations of each kept section.
-    genreloc = '_reloc_abs_start' in info32flat[1]
+    genreloc = as_bytes('_reloc_abs_start') in info32flat[1]
     li = doLayout(sections, config, genreloc)
 
     # Exported symbols
     li.exportsyms = [symbol for symbol in info16[1].values()
                      if (symbol.section is not None
-                         and '.export.' in symbol.section.name
+                         and as_bytes('.export.') in symbol.section.name
                          and symbol.name != symbol.section.name)]
     li.varlowsyms = [symbol for symbol in info32flat[1].values()
                      if (symbol.section is not None
                          and symbol.section.finalloc is not None
-                         and '.data.varlow.' in symbol.section.name
+                         and as_bytes('.data.varlow.') in symbol.section.name
                          and symbol.name != symbol.section.name)]
 
     # Write out linker script files.
diff --git a/scripts/python23compat.py b/scripts/python23compat.py
new file mode 100644
index 0000000..6169072
--- /dev/null
+++ b/scripts/python23compat.py
@@ -0,0 +1,18 @@
+# Helper code for compatibility of the code with both Python 2 and Python 3
+#
+# Copyright (C) 2014 Johannes Krampf <johannes.krampf@gmail.com>
+#
+# This file may be distributed under the terms of the GNU GPLv3 license.
+
+import sys
+
+if (sys.version_info > (3, 0)):
+    def as_bytes(str):
+        return bytes(str, "ASCII")
+    def as_str(bytes):
+        return str(bytes, "ASCII")
+else:
+    def as_bytes(str):
+        return str
+    def as_str(bytes):
+        return bytes
diff --git a/scripts/readserial.py b/scripts/readserial.py
index d85392e..4f29648 100755
--- a/scripts/readserial.py
+++ b/scripts/readserial.py
@@ -13,6 +13,8 @@ import time
 import select
 import optparse
 
+from python23compat import as_bytes
+
 # Reset time counter after this much idle time.
 RESTARTINTERVAL = 60
 # Number of bits in a transmitted byte - 8N1 is 1 start bit + 8 data
@@ -25,7 +27,7 @@ def calibrateserialwrite(outfile, byteadjust):
     data = data * 80
     while 1:
         st = time.time()
-        outfile.write(data)
+        outfile.write(as_bytes(data))
         outfile.flush()
         et = time.time()
         sys.stdout.write(
@@ -85,11 +87,11 @@ def readserial(infile, logfile, byteadjust):
             msg = "\n\n======= %s (adjust=%.1fus)\n" % (
                 time.asctime(time.localtime(datatime)), byteadjust * 1000000)
             sys.stdout.write(msg)
-            logfile.write(msg)
+            logfile.write(as_bytes(msg))
         lasttime = datatime
 
         # Translate unprintable chars; add timestamps
-        out = ""
+        out = as_bytes("")
         for c in d:
             if isnewline:
                 delta = datatime - starttime - (charcount * byteadjust)
@@ -113,7 +115,10 @@ def readserial(infile, logfile, byteadjust):
                 continue
             out += c
 
-        sys.stdout.write(out)
+        if (sys.version_info > (3, 0)):
+            sys.stdout.buffer.write(out)
+        else:
+            sys.stdout.write(out)
         sys.stdout.flush()
         logfile.write(out)
         logfile.flush()
@@ -156,11 +161,11 @@ def main():
         try:
             import serial
         except ImportError:
-            print """
+            print("""
 Unable to find pyserial package ( http://pyserial.sourceforge.net/ ).
 On Linux machines try: yum install pyserial
 Or: apt-get install python-serial
-"""
+""")
             sys.exit(1)
         ser = serial.Serial(serialport, baud, timeout=0)
     else:
diff --git a/scripts/transdump.py b/scripts/transdump.py
index 4caaeb7..665f04a 100755
--- a/scripts/transdump.py
+++ b/scripts/transdump.py
@@ -44,7 +44,10 @@ def main():
         filehdl = open(filename, 'r')
     mem = parseMem(filehdl)
     for i in mem:
-        sys.stdout.write(struct.pack("<I", i))
+        if (sys.version_info > (3, 0)):
+            sys.stdout.buffer.write(struct.pack("<I", i))
+        else:
+            sys.stdout.write(struct.pack("<I", i))
 
 if __name__ == '__main__':
     main()
diff --git a/scripts/vgafixup.py b/scripts/vgafixup.py
index 2493f35..726f7bf 100644
--- a/scripts/vgafixup.py
+++ b/scripts/vgafixup.py
@@ -18,23 +18,25 @@
 
 import sys
 
+from python23compat import as_bytes
+
 def main():
     infilename, outfilename = sys.argv[1:]
     infile = open(infilename, 'rb')
     out = []
     for line in infile:
         sline = line.strip()
-        if sline == 'ret':
-            out.append('retw $2\n')
-        elif sline == 'leave':
-            out.append('movl %ebp, %esp ; popl %ebp\n')
-        elif sline.startswith('call'):
-            out.append('pushw %ax ; callw' + sline[4:] + '\n')
+        if sline == as_bytes('ret'):
+            out.append(as_bytes('retw $2\n'))
+        elif sline == as_bytes('leave'):
+            out.append(as_bytes('movl %ebp, %esp ; popl %ebp\n'))
+        elif sline.startswith(as_bytes('call')):
+            out.append(as_bytes('pushw %ax ; callw') + sline[4:] + as_bytes('\n'))
         else:
             out.append(line)
     infile.close()
     outfile = open(outfilename, 'wb')
-    outfile.write(''.join(out))
+    outfile.write(as_bytes('').join(out))
     outfile.close()
 
 if __name__ == '__main__':
