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.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  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. # Update base length
  40. $baserom->{length} += $rom->{length};
  41. # Merge initialisation entry point
  42. merge_entry_points ( $baserom->{init}, $rom->{init}, $offset );
  43. # Merge BOFM header
  44. merge_entry_points ( $baserom->{bofm_header}, $rom->{bofm_header}, $offset );
  45. # Update PCI header, if present in both
  46. my $baserom_pci = $baserom->pci_header;
  47. my $rom_pci = $rom->pci_header;
  48. if ( $baserom_pci && $rom_pci ) {
  49. # Update PCI lengths
  50. $baserom_pci->{image_length} += $rom_pci->{image_length};
  51. if ( exists $baserom_pci->{runtime_length} ) {
  52. if ( exists $rom_pci->{runtime_length} ) {
  53. $baserom_pci->{runtime_length} += $rom_pci->{runtime_length};
  54. } else {
  55. $baserom_pci->{runtime_length} += $rom_pci->{image_length};
  56. }
  57. }
  58. # Merge CLP entry point
  59. if ( exists ( $baserom_pci->{clp_entry} ) &&
  60. exists ( $rom_pci->{clp_entry} ) ) {
  61. merge_entry_points ( $baserom_pci->{clp_entry}, $rom_pci->{clp_entry},
  62. $offset );
  63. }
  64. }
  65. # Update PnP header, if present in both
  66. my $baserom_pnp = $baserom->pnp_header;
  67. my $rom_pnp = $rom->pnp_header;
  68. if ( $baserom_pnp && $rom_pnp ) {
  69. merge_entry_points ( $baserom_pnp->{bcv}, $rom_pnp->{bcv}, $offset );
  70. merge_entry_points ( $baserom_pnp->{bdv}, $rom_pnp->{bdv}, $offset );
  71. merge_entry_points ( $baserom_pnp->{bev}, $rom_pnp->{bev}, $offset );
  72. }
  73. # Fix checksum for this ROM segment
  74. $rom->fix_checksum();
  75. # Add this ROM to base ROM
  76. my $data = substr ( $baserom->get(), 0, $baserom->length() );
  77. $data .= $rom->get();
  78. $data .= $baserom->next_image()->get() if $baserom->next_image();
  79. $baserom->set ( $data );
  80. $offset += $rom->length;
  81. }
  82. $baserom->pnp_header->fix_checksum() if $baserom->pnp_header;
  83. $baserom->fix_checksum();
  84. $baserom->save ( "-" );