[process] Include process name in debug messages
[ipxe.git] / src / util / mergerom.pl
1 #!/usr/bin/perl -w
2 #
3 # Copyright (C) 2008 Michael Brown <mbrown@fensystems.co.uk>.
4 #
5 # This program is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU General Public License as
7 # published by the Free Software Foundation; either version 2 of the
8 # License, or any later version.
9 #
10 # This program is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 # General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 # 02110-1301, USA.
19
20 use strict;
21 use warnings;
22
23 use FindBin;
24 use lib "$FindBin::Bin";
25 use Option::ROM qw ( :all );
26
27 sub merge_entry_points {
28 my $baserom_entry = \shift;
29 my $rom_entry = \shift;
30 my $offset = shift;
31
32 if ( $$rom_entry ) {
33 my $old_entry = $$baserom_entry;
34 $$baserom_entry = ( $offset + $$rom_entry );
35 $$rom_entry = $old_entry;
36 }
37 }
38
39 my @romfiles = @ARGV;
40 my @roms = map { my $rom = new Option::ROM; $rom->load($_); $rom } @romfiles;
41
42 my $baserom = shift @roms;
43 my $offset = $baserom->length;
44
45 foreach my $rom ( @roms ) {
46
47 # Merge initialisation entry point
48 merge_entry_points ( $baserom->{init}, $rom->{init}, $offset );
49
50 # Merge BOFM header
51 merge_entry_points ( $baserom->{bofm_header}, $rom->{bofm_header}, $offset );
52
53 # Update PCI header, if present in both
54 my $baserom_pci = $baserom->pci_header;
55 my $rom_pci = $rom->pci_header;
56 if ( $baserom_pci && $rom_pci ) {
57
58 # Update PCI lengths
59 $baserom_pci->{image_length} += $rom_pci->{image_length};
60 if ( exists $baserom_pci->{runtime_length} ) {
61 if ( exists $rom_pci->{runtime_length} ) {
62 $baserom_pci->{runtime_length} += $rom_pci->{runtime_length};
63 } else {
64 $baserom_pci->{runtime_length} += $rom_pci->{image_length};
65 }
66 }
67
68 # Merge CLP entry point
69 if ( exists ( $baserom_pci->{clp_entry} ) &&
70 exists ( $rom_pci->{clp_entry} ) ) {
71 merge_entry_points ( $baserom_pci->{clp_entry}, $rom_pci->{clp_entry},
72 $offset );
73 }
74 }
75
76 # Update PnP header, if present in both
77 my $baserom_pnp = $baserom->pnp_header;
78 my $rom_pnp = $rom->pnp_header;
79 if ( $baserom_pnp && $rom_pnp ) {
80 merge_entry_points ( $baserom_pnp->{bcv}, $rom_pnp->{bcv}, $offset );
81 merge_entry_points ( $baserom_pnp->{bdv}, $rom_pnp->{bdv}, $offset );
82 merge_entry_points ( $baserom_pnp->{bev}, $rom_pnp->{bev}, $offset );
83 }
84
85 # Update iPXE header, if present
86 my $baserom_ipxe = $baserom->ipxe_header;
87 my $rom_ipxe = $rom->ipxe_header;
88 if ( $baserom_ipxe ) {
89
90 # Update shrunk length
91 $baserom_ipxe->{shrunk_length} = ( $baserom->{length} +
92 ( $rom_ipxe ?
93 $rom_ipxe->{shrunk_length} :
94 $rom->{length} ) );
95
96 # Fix checksum
97 $baserom_ipxe->fix_checksum();
98 }
99
100 # Update base length
101 $baserom->{length} += $rom->{length};
102
103 # Fix checksum for this ROM segment
104 $rom->fix_checksum();
105
106 # Add this ROM to base ROM
107 my $data = substr ( $baserom->get(), 0, $baserom->length() );
108 $data .= $rom->get();
109 $data .= $baserom->next_image()->get() if $baserom->next_image();
110 $baserom->set ( $data );
111
112 $offset += $rom->length;
113 }
114
115 $baserom->pnp_header->fix_checksum() if $baserom->pnp_header;
116 $baserom->fix_checksum();
117 $baserom->save ( "-" );