File: microcode_extract.pl

package info (click to toggle)
em8300 0.14.0-2
  • links: PTS
  • area: contrib
  • in suites: sarge
  • size: 2,828 kB
  • ctags: 1,660
  • sloc: ansic: 11,095; sh: 8,892; perl: 1,338; makefile: 479
file content (75 lines) | stat: -rwxr-xr-x 1,957 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#!/usr/bin/perl

sub sanehead {
  my $blocktype = shift;
  my $offset = shift;
  my $dlen = shift;
  my $count = shift;

  if($blocktype > 0x300) { return 0 };
  if($offset > 0x10000) { return 0 };
  if($dlen > 20000) { return 0}
  return 1;
}

if($#ARGV < 0) {
  print "EM8300 microcode extractor\n";
  print "Written by Henrik Johansson 2000-04-10\n\n";
  print "Usage:\n\tmicrocode_extract.pl FILE [DESTDIR] [NAMEBASE]\n\n";
  print "FILE refers to the VXD file which comes with the Windows drivers
and is found in the Windows\\System folder. The file is usually called 
rmquasar.vxd (H+) or enc2dev.vxd (Creative Labs). \n\n";
  print "DESTDIR is the dir where the microcode should be stored.\n\n";
  print "NAMEBASE is the prefix of the saved microcode files.\n\n";
}

open(VXD,"<$ARGV[0]");
undef $/;
$vxd = <VXD>;
close(VXD);

$path=$ARGV[1];
$namebase=$ARGV[2];
if(length($namebase) == 0) { $namebase="microcode" };

$ucnt = 0;

for($i=0; $i < length($vxd); $i++) 
{
  if(unpack('v',substr($vxd,$i,2)) == 2) {
    $savei = $i;
    $ok = 1;
    $blocktype = -1;
    $count=0;
    while($blocktype != 0) {
      ($blocktype, $offset, $dlen) = unpack('vVV',substr($vxd,$i,11));
      
      if($blocktype == 0) { last; }
      
      if(($blocktype == 2) && (($lastblocktype&0xf00) == 0x200)) { $i--; last; }
      
      $dlen *= 2;
      if(!sanehead($blocktype,$offset,$dlen,$count)) {
	$ok = 0;
	last;
      }
      $i+=10+$dlen;
      $lastblocktype = $blocktype;
      $count++;
    }
    $lastblocktype = -1;      
    if($ok && $count > 20) {
      $ucodelen =  $i - $savei;
      $filename = "$path/$namebase$ucnt.bin";
      open UCODE,">$filename" or die("Can't open microcode file");
      print UCODE substr($vxd,$savei,$ucodelen);
      print pack('SII',(0,0,0));
      close UCODE;
      print "Found microcode block (length=$ucodelen), ";
      print "saving to $filename \n";
      $ucnt++;
    } else {
      $i = $savei;
    }
  }
}