|
@@ -172,9 +172,10 @@ use constant ROM_SIGNATURE => 0xaa55;
|
172
|
172
|
use constant PCI_SIGNATURE => 'PCIR';
|
173
|
173
|
use constant PCI_LAST_IMAGE => 0x80;
|
174
|
174
|
use constant PNP_SIGNATURE => '$PnP';
|
|
175
|
+use constant IPXE_SIGNATURE => 'iPXE';
|
175
|
176
|
|
176
|
177
|
our @EXPORT_OK = qw ( ROM_SIGNATURE PCI_SIGNATURE PCI_LAST_IMAGE
|
177
|
|
- PNP_SIGNATURE );
|
|
178
|
+ PNP_SIGNATURE IPXE_SIGNATURE );
|
178
|
179
|
our %EXPORT_TAGS = ( all => [ @EXPORT_OK ] );
|
179
|
180
|
|
180
|
181
|
use constant JMP_SHORT => 0xeb;
|
|
@@ -232,6 +233,7 @@ sub new {
|
232
|
233
|
init => { offset => 0x03, length => 0x03,
|
233
|
234
|
pack => \&pack_init, unpack => \&unpack_init },
|
234
|
235
|
checksum => { offset => 0x06, length => 0x01, pack => "C" },
|
|
236
|
+ ipxe_header => { offset => 0x10, length => 0x02, pack => "S" },
|
235
|
237
|
bofm_header => { offset => 0x14, length => 0x02, pack => "S" },
|
236
|
238
|
undi_header => { offset => 0x16, length => 0x02, pack => "S" },
|
237
|
239
|
pci_header => { offset => 0x18, length => 0x02, pack => "S" },
|
|
@@ -390,6 +392,25 @@ sub pnp_header {
|
390
|
392
|
|
391
|
393
|
=pod
|
392
|
394
|
|
|
395
|
+=item C<< ipxe_header () >>
|
|
396
|
+
|
|
397
|
+Return a C<Option::ROM::iPXE> object representing the ROM's iPXE
|
|
398
|
+header, if present.
|
|
399
|
+
|
|
400
|
+=cut
|
|
401
|
+
|
|
402
|
+sub ipxe_header {
|
|
403
|
+ my $hash = shift;
|
|
404
|
+ my $self = tied(%$hash);
|
|
405
|
+
|
|
406
|
+ my $offset = $hash->{ipxe_header};
|
|
407
|
+ return undef unless $offset != 0;
|
|
408
|
+
|
|
409
|
+ return Option::ROM::iPXE->new ( $self->{data}, $offset );
|
|
410
|
+}
|
|
411
|
+
|
|
412
|
+=pod
|
|
413
|
+
|
393
|
414
|
=item C<< next_image () >>
|
394
|
415
|
|
395
|
416
|
Return a C<Option::ROM> object representing the next image within the
|
|
@@ -566,4 +587,58 @@ sub product {
|
566
|
587
|
return unpack ( "Z*", $raw );
|
567
|
588
|
}
|
568
|
589
|
|
|
590
|
+##############################################################################
|
|
591
|
+#
|
|
592
|
+# Option::ROM::iPXE
|
|
593
|
+#
|
|
594
|
+##############################################################################
|
|
595
|
+
|
|
596
|
+package Option::ROM::iPXE;
|
|
597
|
+
|
|
598
|
+use strict;
|
|
599
|
+use warnings;
|
|
600
|
+use Carp;
|
|
601
|
+use bytes;
|
|
602
|
+
|
|
603
|
+sub new {
|
|
604
|
+ my $class = shift;
|
|
605
|
+ my $data = shift;
|
|
606
|
+ my $offset = shift;
|
|
607
|
+
|
|
608
|
+ my $hash = {};
|
|
609
|
+ tie %$hash, "Option::ROM::Fields", {
|
|
610
|
+ data => $data,
|
|
611
|
+ offset => $offset,
|
|
612
|
+ length => 0x06,
|
|
613
|
+ fields => {
|
|
614
|
+ signature => { offset => 0x00, length => 0x04, pack => "a4" },
|
|
615
|
+ struct_length => { offset => 0x04, length => 0x01, pack => "C" },
|
|
616
|
+ checksum => { offset => 0x05, length => 0x01, pack => "C" },
|
|
617
|
+ shrunk_length => { offset => 0x06, length => 0x01, pack => "C" },
|
|
618
|
+ build_id => { offset => 0x08, length => 0x04, pack => "L" },
|
|
619
|
+ },
|
|
620
|
+ };
|
|
621
|
+ bless $hash, $class;
|
|
622
|
+
|
|
623
|
+ # Retrieve true length of structure
|
|
624
|
+ my $self = tied ( %$hash );
|
|
625
|
+ $self->{length} = $hash->{struct_length};
|
|
626
|
+
|
|
627
|
+ return $hash;
|
|
628
|
+}
|
|
629
|
+
|
|
630
|
+sub checksum {
|
|
631
|
+ my $hash = shift;
|
|
632
|
+ my $self = tied(%$hash);
|
|
633
|
+
|
|
634
|
+ return $self->checksum();
|
|
635
|
+}
|
|
636
|
+
|
|
637
|
+sub fix_checksum {
|
|
638
|
+ my $hash = shift;
|
|
639
|
+ my $self = tied(%$hash);
|
|
640
|
+
|
|
641
|
+ $hash->{checksum} = ( ( $hash->{checksum} - $hash->checksum() ) & 0xff );
|
|
642
|
+}
|
|
643
|
+
|
569
|
644
|
1;
|