Kevin O'Connor | 2fda7cb | 2008-07-05 20:41:53 -0400 | [diff] [blame] | 1 | #!/usr/bin/env python |
| 2 | # Script to check a bios image and report info on it. |
| 3 | # |
| 4 | # Copyright (C) 2008 Kevin O'Connor <kevin@koconnor.net> |
| 5 | # |
| 6 | # This file may be distributed under the terms of the GNU GPLv3 license. |
| 7 | |
Kevin O'Connor | e51488c | 2014-05-22 16:59:16 -0400 | [diff] [blame] | 8 | import sys, struct |
| 9 | import layoutrom, buildrom |
Kevin O'Connor | 2fda7cb | 2008-07-05 20:41:53 -0400 | [diff] [blame] | 10 | |
Johannes Krampf | 19f789b | 2014-01-19 16:03:49 +0100 | [diff] [blame] | 11 | from python23compat import as_bytes |
| 12 | |
David Woodhouse | a82be56 | 2013-01-17 21:23:46 +0000 | [diff] [blame] | 13 | def subst(data, offset, new): |
| 14 | return data[:offset] + new + data[offset + len(new):] |
| 15 | |
| 16 | def checksum(data, start, size, csum): |
Kevin O'Connor | e51488c | 2014-05-22 16:59:16 -0400 | [diff] [blame] | 17 | sumbyte = buildrom.checksum(data[start:start+size]) |
| 18 | return subst(data, start+csum, sumbyte) |
David Woodhouse | a82be56 | 2013-01-17 21:23:46 +0000 | [diff] [blame] | 19 | |
Kevin O'Connor | 2fda7cb | 2008-07-05 20:41:53 -0400 | [diff] [blame] | 20 | def main(): |
Kevin O'Connor | 5b8f809 | 2009-09-20 19:47:45 -0400 | [diff] [blame] | 21 | # Get args |
Gerd Hoffmann | 85f8fac | 2013-09-24 10:06:16 +0200 | [diff] [blame] | 22 | objinfo, finalsize, rawfile, outfile = sys.argv[1:] |
Kevin O'Connor | 2fda7cb | 2008-07-05 20:41:53 -0400 | [diff] [blame] | 23 | |
Kevin O'Connor | 5b8f809 | 2009-09-20 19:47:45 -0400 | [diff] [blame] | 24 | # Read in symbols |
Johannes Krampf | 19f789b | 2014-01-19 16:03:49 +0100 | [diff] [blame] | 25 | objinfofile = open(objinfo, 'r') |
Kevin O'Connor | 1a4885e | 2010-09-15 21:28:31 -0400 | [diff] [blame] | 26 | symbols = layoutrom.parseObjDump(objinfofile, 'in')[1] |
Kevin O'Connor | 5b8f809 | 2009-09-20 19:47:45 -0400 | [diff] [blame] | 27 | |
| 28 | # Read in raw file |
| 29 | f = open(rawfile, 'rb') |
| 30 | rawdata = f.read() |
| 31 | f.close() |
| 32 | datasize = len(rawdata) |
Gerd Hoffmann | 85f8fac | 2013-09-24 10:06:16 +0200 | [diff] [blame] | 33 | finalsize = int(finalsize) * 1024 |
| 34 | if finalsize == 0: |
| 35 | finalsize = 64*1024 |
| 36 | if datasize > 64*1024: |
| 37 | finalsize = 128*1024 |
| 38 | if datasize > 128*1024: |
| 39 | finalsize = 256*1024 |
| 40 | if datasize > finalsize: |
Johannes Krampf | 064fd06 | 2014-01-12 11:14:54 -0500 | [diff] [blame] | 41 | print("Error! ROM doesn't fit (%d > %d)" % (datasize, finalsize)) |
Andreas Färber | b458122 | 2015-03-19 17:23:19 +0100 | [diff] [blame] | 42 | print(" You have to either increase the size (CONFIG_ROM_SIZE)") |
Johannes Krampf | 064fd06 | 2014-01-12 11:14:54 -0500 | [diff] [blame] | 43 | print(" or turn off some features (such as hardware support not") |
| 44 | print(" needed) to make it fit. Trying a more recent gcc version") |
| 45 | print(" might work too.") |
Gerd Hoffmann | 85f8fac | 2013-09-24 10:06:16 +0200 | [diff] [blame] | 46 | sys.exit(1) |
Kevin O'Connor | 5b8f809 | 2009-09-20 19:47:45 -0400 | [diff] [blame] | 47 | |
| 48 | # Sanity checks |
Kevin O'Connor | 1a4885e | 2010-09-15 21:28:31 -0400 | [diff] [blame] | 49 | start = symbols['code32flat_start'].offset |
| 50 | end = symbols['code32flat_end'].offset |
Kevin O'Connor | 9ba1dea | 2010-05-01 09:50:13 -0400 | [diff] [blame] | 51 | expend = layoutrom.BUILD_BIOS_ADDR + layoutrom.BUILD_BIOS_SIZE |
| 52 | if end != expend: |
Johannes Krampf | 064fd06 | 2014-01-12 11:14:54 -0500 | [diff] [blame] | 53 | print("Error! Code does not end at 0x%x (got 0x%x)" % ( |
| 54 | expend, end)) |
Kevin O'Connor | 2fda7cb | 2008-07-05 20:41:53 -0400 | [diff] [blame] | 55 | sys.exit(1) |
Kevin O'Connor | 5b8f809 | 2009-09-20 19:47:45 -0400 | [diff] [blame] | 56 | if datasize > finalsize: |
Johannes Krampf | 064fd06 | 2014-01-12 11:14:54 -0500 | [diff] [blame] | 57 | print("Error! Code is too big (0x%x vs 0x%x)" % ( |
| 58 | datasize, finalsize)) |
Kevin O'Connor | 5b8f809 | 2009-09-20 19:47:45 -0400 | [diff] [blame] | 59 | sys.exit(1) |
Kevin O'Connor | 9ba1dea | 2010-05-01 09:50:13 -0400 | [diff] [blame] | 60 | expdatasize = end - start |
| 61 | if datasize != expdatasize: |
Johannes Krampf | 064fd06 | 2014-01-12 11:14:54 -0500 | [diff] [blame] | 62 | print("Error! Unknown extra data (0x%x vs 0x%x)" % ( |
| 63 | datasize, expdatasize)) |
Kevin O'Connor | 871e0a0 | 2009-12-30 12:14:53 -0500 | [diff] [blame] | 64 | sys.exit(1) |
Kevin O'Connor | 2fda7cb | 2008-07-05 20:41:53 -0400 | [diff] [blame] | 65 | |
David Woodhouse | a82be56 | 2013-01-17 21:23:46 +0000 | [diff] [blame] | 66 | # Fix up CSM Compatibility16 table |
| 67 | if 'csm_compat_table' in symbols and 'entry_csm' in symbols: |
| 68 | # Field offsets within EFI_COMPATIBILITY16_TABLE |
| 69 | ENTRY_FIELD_OFS = 14 # Compatibility16CallOffset (UINT16) |
| 70 | SIZE_FIELD_OFS = 5 # TableLength (UINT8) |
| 71 | CSUM_FIELD_OFS = 4 # TableChecksum (UINT8) |
| 72 | |
| 73 | tableofs = symbols['csm_compat_table'].offset - symbols['code32flat_start'].offset |
| 74 | entry_addr = symbols['entry_csm'].offset - layoutrom.BUILD_BIOS_ADDR |
Kevin O'Connor | e51488c | 2014-05-22 16:59:16 -0400 | [diff] [blame] | 75 | entry_addr = struct.pack('<H', entry_addr) |
| 76 | rawdata = subst(rawdata, tableofs+ENTRY_FIELD_OFS, entry_addr) |
David Woodhouse | a82be56 | 2013-01-17 21:23:46 +0000 | [diff] [blame] | 77 | |
Kevin O'Connor | e51488c | 2014-05-22 16:59:16 -0400 | [diff] [blame] | 78 | tsfield = tableofs+SIZE_FIELD_OFS |
| 79 | tablesize = ord(rawdata[tsfield:tsfield+1]) |
David Woodhouse | a82be56 | 2013-01-17 21:23:46 +0000 | [diff] [blame] | 80 | rawdata = checksum(rawdata, tableofs, tablesize, CSUM_FIELD_OFS) |
| 81 | |
Kevin O'Connor | 5b8f809 | 2009-09-20 19:47:45 -0400 | [diff] [blame] | 82 | # Print statistics |
Kevin O'Connor | 6afc6f8 | 2013-02-19 01:02:50 -0500 | [diff] [blame] | 83 | runtimesize = end - symbols['code32init_end'].offset |
Johannes Krampf | 064fd06 | 2014-01-12 11:14:54 -0500 | [diff] [blame] | 84 | print("Total size: %d Fixed: %d Free: %d (used %.1f%% of %dKiB rom)" % ( |
Kevin O'Connor | 94dc9c4 | 2010-09-26 18:32:13 -0400 | [diff] [blame] | 85 | datasize, runtimesize, finalsize - datasize |
Kevin O'Connor | 9ba1dea | 2010-05-01 09:50:13 -0400 | [diff] [blame] | 86 | , (datasize / float(finalsize)) * 100.0 |
Johannes Krampf | 9d7d044 | 2014-01-12 11:19:22 -0500 | [diff] [blame] | 87 | , int(finalsize / 1024))) |
Kevin O'Connor | 5b8f809 | 2009-09-20 19:47:45 -0400 | [diff] [blame] | 88 | |
| 89 | # Write final file |
| 90 | f = open(outfile, 'wb') |
Johannes Krampf | 19f789b | 2014-01-19 16:03:49 +0100 | [diff] [blame] | 91 | f.write((as_bytes("\0") * (finalsize - datasize)) + rawdata) |
Kevin O'Connor | 5b8f809 | 2009-09-20 19:47:45 -0400 | [diff] [blame] | 92 | f.close() |
Kevin O'Connor | 2fda7cb | 2008-07-05 20:41:53 -0400 | [diff] [blame] | 93 | |
| 94 | if __name__ == '__main__': |
| 95 | main() |