You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

mergerom.pl 3.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  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. use strict;
  20. use warnings;
  21. use FindBin;
  22. use lib "$FindBin::Bin";
  23. use Option::ROM qw ( :all );
  24. sub merge_entry_points {
  25. my $baserom_entry = \shift;
  26. my $rom_entry = \shift;
  27. my $offset = shift;
  28. if ( $$rom_entry ) {
  29. my $old_entry = $$baserom_entry;
  30. $$baserom_entry = ( $offset + $$rom_entry );
  31. $$rom_entry = $old_entry;
  32. }
  33. }
  34. my @romfiles = @ARGV;
  35. my @roms = map { my $rom = new Option::ROM; $rom->load($_); $rom } @romfiles;
  36. my $baserom = shift @roms;
  37. my $offset = $baserom->length;
  38. foreach my $rom ( @roms ) {
  39. # Merge initialisation entry point
  40. merge_entry_points ( $baserom->{init}, $rom->{init}, $offset );
  41. # Merge BOFM header
  42. merge_entry_points ( $baserom->{bofm_header}, $rom->{bofm_header}, $offset );
  43. # Update PCI header, if present in both
  44. my $baserom_pci = $baserom->pci_header;
  45. my $rom_pci = $rom->pci_header;
  46. if ( $baserom_pci && $rom_pci ) {
  47. # Update PCI lengths
  48. $baserom_pci->{image_length} += $rom_pci->{image_length};
  49. if ( exists $baserom_pci->{runtime_length} ) {
  50. if ( exists $rom_pci->{runtime_length} ) {
  51. $baserom_pci->{runtime_length} += $rom_pci->{runtime_length};
  52. } else {
  53. $baserom_pci->{runtime_length} += $rom_pci->{image_length};
  54. }
  55. }
  56. # Merge CLP entry point
  57. if ( exists ( $baserom_pci->{clp_entry} ) &&
  58. exists ( $rom_pci->{clp_entry} ) ) {
  59. merge_entry_points ( $baserom_pci->{clp_entry}, $rom_pci->{clp_entry},
  60. $offset );
  61. }
  62. }
  63. # Update PnP header, if present in both
  64. my $baserom_pnp = $baserom->pnp_header;
  65. my $rom_pnp = $rom->pnp_header;
  66. if ( $baserom_pnp && $rom_pnp ) {
  67. merge_entry_points ( $baserom_pnp->{bcv}, $rom_pnp->{bcv}, $offset );
  68. merge_entry_points ( $baserom_pnp->{bdv}, $rom_pnp->{bdv}, $offset );
  69. merge_entry_points ( $baserom_pnp->{bev}, $rom_pnp->{bev}, $offset );
  70. }
  71. # Update iPXE header, if present
  72. my $baserom_ipxe = $baserom->ipxe_header;
  73. my $rom_ipxe = $rom->ipxe_header;
  74. if ( $baserom_ipxe ) {
  75. # Update shrunk length
  76. $baserom_ipxe->{shrunk_length} = ( $baserom->{length} +
  77. ( $rom_ipxe ?
  78. $rom_ipxe->{shrunk_length} :
  79. $rom->{length} ) );
  80. # Fix checksum
  81. $baserom_ipxe->fix_checksum();
  82. }
  83. # Update base length
  84. $baserom->{length} += $rom->{length};
  85. # Fix checksum for this ROM segment
  86. $rom->fix_checksum();
  87. # Add this ROM to base ROM
  88. my $data = substr ( $baserom->get(), 0, $baserom->length() );
  89. $data .= $rom->get();
  90. $data .= $baserom->next_image()->get() if $baserom->next_image();
  91. $baserom->set ( $data );
  92. $offset += $rom->length;
  93. }
  94. $baserom->pnp_header->fix_checksum() if $baserom->pnp_header;
  95. $baserom->fix_checksum();
  96. $baserom->save ( "-" );