blob: 7d48cb587cdf7126842fece9b8cf601a051145a7 [file] [log] [blame]
Kevin O'Connorf076a3e2008-02-25 22:25:15 -05001#!/usr/bin/env python
2# Script to merge a rom32.bin file into a rom16.bin file.
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
8import sys
9import struct
Kevin O'Connor4b39b822008-05-08 21:47:33 -040010import os
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050011
12ROM16='out/rom16.bin'
13ROM32='out/rom32.bin'
14OFFSETS16='out/rom16.offset.auto.h'
15OFFSETS32='out/rom32.offset.auto.h'
Kevin O'Connor59fead62008-05-10 15:49:20 -040016OUT='out/bios.bin'
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050017
18def align(v, a):
19 return (v + a - 1) // a * a
20
21def scanconfig(file):
22 f = open(file, 'rb')
23 opts = {}
24 for l in f.readlines():
25 parts = l.split()
26 if len(parts) != 3:
27 continue
28 if parts[0] != '#define':
29 continue
30 opts[parts[1]] = parts[2]
31 return opts
32
33def alteraddr(data, offset, ptr):
34 rel = struct.pack("<i", ptr)
35 return data[:offset] + rel + data[offset+4:]
36
37
38def main():
39 # Read in files
40 f = open(ROM16, 'rb')
41 data16 = f.read()
42 f = open(ROM32, 'rb')
43 data32 = f.read()
44
45 if len(data16) != 65536:
46 print "16bit code is not 65536 bytes long"
47 sys.exit(1)
48
49 # Get config options
50 o16 = scanconfig(OFFSETS16)
51 o32 = scanconfig(OFFSETS32)
52
53 # Inject 32bit code
54 spos = align(int(o16['OFFSET_bios16c_end'], 16), 16)
55 epos = int(o16['OFFSET_post16'], 16)
56 size32 = len(data32)
57 freespace = epos - spos
58 if size32 > freespace:
59 print "32bit code too large (%d vs %d)" % (size32, freespace)
60 sys.exit(1)
Kevin O'Connorbdce35f2008-02-26 21:33:14 -050061 if data16[spos:spos+size32] != '\0'*size32:
62 print "Non zero data in 16bit freespace (%d to %d)" % (
63 spos, spos+size32)
64 sys.exit(1)
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050065 outrom = data16[:spos] + data32 + data16[spos+size32:]
66
67 # Fixup initial jump to 32 bit code
68 jmppos = int(o16['OFFSET_set_entry32'], 16)
69 start32 = int(o32['OFFSET__start'], 16)
70 outrom = alteraddr(outrom, jmppos+2, start32)
71
Kevin O'Connorbdce35f2008-02-26 21:33:14 -050072 print "Writing output rom %s" % OUT
73 print " 16bit C-code size: %d" % spos
74 print " 32bit C-code size: %d" % size32
75 print " Total C-code size: %d" % (spos+size32)
76
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050077 # Write output rom
78 f = open(OUT, 'wb')
79 f.write(outrom)
80 f.close()
81
Kevin O'Connor4b39b822008-05-08 21:47:33 -040082 # Build elf file with 32bit entry point
83 os.system(
Kevin O'Connor59fead62008-05-10 15:49:20 -040084 "ld -melf_i386 -e %s -Ttext 0xf0000 -b binary %s -o %s" % (
85 int(o32['OFFSET_post32'], 16), OUT, OUT+".elf"))
Kevin O'Connor4b39b822008-05-08 21:47:33 -040086
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050087if __name__ == '__main__':
88 main()