home *** CD-ROM | disk | FTP | other *** search
- #!/usr/bin/perl -w
- #
- # dumpdmi 0.2
- # Chip Salzenberg <chip@valinux.com>
- #
-
- use strict;
-
- (my $ME = $0) =~ s#.*/##;
-
- my $DEBUG;
- if (@ARGV && $ARGV[0] eq '-d') {
- ++$DEBUG;
- shift;
- }
-
- my $BIOS;
- open MEM, '/dev/mem'
- or die "$ME: Can't open /dev/mem: $!\n";
- sysseek MEM, 0xE0000, 0;
- sysread MEM, $BIOS, 0x20000
- or die "$ME: Can't read BIOS from /dev/mem?\n";
-
- while ( $BIOS =~ /_DMI_/g
- && (pos($BIOS) & 0x0F) != 5 )
- {}
- die "$ME: Can't find DMI in BIOS\n"
- unless pos($BIOS);
-
- my $info = substr($BIOS, pos($BIOS) + 1, 10);
- my ($DSIZE, $DBASE, $DCOUNT, $DVER) = unpack('v V v C', $info);
- $DVER = ($DVER >> 4) . '.' . ($DVER & 0x0F);
-
- print "DMI Version: $DVER\n";
-
- printf "DMI table at 0x%X contains %d structures occupying %d bytes.\n",
- $DBASE, $DCOUNT, $DSIZE
- if $DEBUG;
-
- sysseek MEM, $DBASE, 0;
- sysread MEM, $_, $DSIZE
- or die "$ME: Can't read DMI table: $!\n";
-
- my $n = 0;
- my $last_type = 0;
- while (my $header = substr($_, 0, 4, '')) {
- my ($type, $dlen, $handle) = unpack('CCv', $header);
- last if $type < $last_type || $dlen < 4;
-
- my $data = substr($_, 0, $dlen - 4, '');
- my @data = unpack 'C*', $data;
- my @str = m{ \G ([^\0]+) \0 }xg;
-
- if ($DEBUG) {
- printf "DMI type=%02X data=%s\n",
- $type,
- join(':', map { sprintf '%02X', $_ } @data);
- if (my @s = @str) {
- for (@s) { s/\\/\\\\/g; s/"/\\"/g; }
- printf " strings={ %s }\n",
- join(', ', map { '"'.$_.'"' } @s);
- }
- }
-
- my $str = sub {
- my $n = $data[+shift];
- (defined($n) && $n > 0 && $n <= @str)
- or return '<ERROR>';
- local $_ = $str[$n - 1];
- s/^\s+//;
- s/\s+$//;
- $_;
- };
-
- if ($type == 0) {
- print "BIOS Vendor: ", $str->(0), "\n";
- print "BIOS Version: ", $str->(1), "\n";
- print "BIOS Release: ", $str->(4), "\n";
- }
- elsif ($type == 1) {
- print "System Vendor: ", $str->(0), "\n";
- print "System Name: ", $str->(1), "\n";
- print "System Version: ", $str->(2), "\n";
- print "System Serial Number: ", $str->(3), "\n";
- }
- elsif ($type == 2) {
- print "Board Vendor: ", $str->(0), "\n";
- print "Board Name: ", $str->(1), "\n";
- print "Board Version: ", $str->(2), "\n";
- print "Board Serial Number: ", $str->(3), "\n";
- }
- elsif ($type == 3) {
- print "Asset Tag: ", $str->(4), "\n";
- }
-
- last unless s/^.*?\0\0//;
- last if ++$n >= $DCOUNT;
-
- $last_type = $type;
- }
-