kerneltest/e32utils/hcrscripts/hcrdat.pm
branchanywhere
changeset 20 d63d727ee0a6
parent 19 f6d3d9676ee4
parent 16 6d8ad5bee44b
child 21 af091391d962
equal deleted inserted replaced
19:f6d3d9676ee4 20:d63d727ee0a6
     1 #!perl -w
       
     2 #
       
     3 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 # All rights reserved.
       
     5 # This component and the accompanying materials are made available
       
     6 # under the terms of the License "Eclipse Public License v1.0"
       
     7 # which accompanies this distribution, and is available
       
     8 # at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     9 #
       
    10 # Initial Contributors:
       
    11 # Nokia Corporation - initial contribution.
       
    12 #
       
    13 # Contributors:
       
    14 #
       
    15 # Description:
       
    16 #
       
    17 use strict;
       
    18 
       
    19 #use Math::BigInt;
       
    20 
       
    21 #
       
    22 # Perl module to create and maintain feature manager data files.
       
    23 # You can either set up the information programmatically or else load up
       
    24 # information from a pre-existing feature data file and then modify it. You
       
    25 # can also save the information to a file (in feature manager dataset format).
       
    26 #
       
    27 # This class maintains header information plus two arrays, one containing
       
    28 # feature flag information and the other containing default supported range
       
    29 # information. Those are themselves objects and have their own accessor
       
    30 # methods.
       
    31 #
       
    32 
       
    33 package HCRdat;
       
    34 
       
    35 use HCRrec;
       
    36 
       
    37 
       
    38 #
       
    39 # n e w
       
    40 #
       
    41 # Create a new HCRdat object. For example 'my $hd = HCRdat->new("filea");
       
    42 #
       
    43 sub new
       
    44 {
       
    45 	my $arg = shift;
       
    46 	my $fn = shift;
       
    47 	my $class = ref($arg) || $arg;
       
    48 	my $self = {
       
    49 			        fingerprint => "HCRf",  # 4 bytes wide.
       
    50 					fileversion => 1,       # 2 bytes.
       
    51 					fileflags => 0x0001,  # 2 bytes.
       
    52 					numrecords => 0,      # 4 bytes. 
       
    53 					lsdoffset => 0,       # 4 bytes. 
       
    54 					lsdsize => 0,         # 4 bytes.
       
    55 				    packprefix => "V",    # Changed with endian-ness.
       
    56 					                      # Used to create binary strings.
       
    57 
       
    58 					settingrecords => [],  # Array of objects
       
    59 					lsd => [],             # Array of bytes
       
    60 	           };
       
    61     bless $self, $class;
       
    62 	return $self;
       
    63 }
       
    64 
       
    65 
       
    66 # Print to STDOUT the header information we have.
       
    67 sub ShowHeader
       
    68 {
       
    69 	my $self = shift;
       
    70 	return undef unless(ref($self));
       
    71 
       
    72 	# Get header information..
       
    73 	my $typefield = $self->TypeField();
       
    74 	my $fileversion = $self->FileVersion();
       
    75 	my $fileflags = $self->FileFlags();
       
    76 	my $numrecords = $self->NumRecords();
       
    77 	my $lsdoffset = $self->LsdOffset();
       
    78 	my $lsdsize = $self->LsdSize();
       
    79 	
       
    80 	# Display it in English.
       
    81 	print "  FINGERPRINTF: '$typefield'\n";
       
    82 	print "  FILEVERSION: '$fileversion'\n";
       
    83 	print "  FILEFLAGS: '$fileflags'\n";
       
    84 	print "  NUMRECORDS: '$numrecords'\n";
       
    85 	print "  LSDOFFSET: '$lsdoffset'\n";
       
    86     print "  LSDSIZE: '$lsdsize'\n";
       
    87 
       
    88 	return(0);
       
    89 }
       
    90 
       
    91 # Get/Set the endian-ness we want. Changes the 'packprefix' member which is
       
    92 # used in the creation of binary data.
       
    93 sub Endian
       
    94 {
       
    95 	my $self = shift;
       
    96 	return undef unless(ref($self));
       
    97 	my $arg = shift;
       
    98 	return $self->{endian} unless(defined($arg));
       
    99 	if($arg =~ m/(LE|BE)/i)
       
   100 	{
       
   101 		my $endian = uc($1);
       
   102 		$self->{endian} = $endian;
       
   103 		# Used by 'pack' to generate binary strings.
       
   104 		$self->{packprefix} = "V" if($endian eq "LE");
       
   105 		$self->{packprefix} = "N" if($endian eq "BE");
       
   106 	}
       
   107 	return $self->{endian};
       
   108 }
       
   109 
       
   110 # This is the fingerprint.
       
   111 sub TypeField
       
   112 {
       
   113 	my $self = shift;
       
   114 	return undef unless(ref($self));
       
   115 	my $arg = shift;
       
   116 	$self->{fingerprint} = $arg if(defined($arg));
       
   117 	return $self->{fingerprint};
       
   118 }
       
   119 
       
   120 sub FileVersion
       
   121 {
       
   122 	my $self = shift;
       
   123 	return undef unless(ref($self));
       
   124 	my $arg = shift;
       
   125 	# Should we be testing for a numeric value?
       
   126 	$self->{fileversion} = $arg if(defined($arg));
       
   127 	return $self->{fileversion};
       
   128 }
       
   129 
       
   130 sub FileFlags
       
   131 {
       
   132 	my $self = shift;
       
   133 	return undef unless(ref($self));
       
   134 	my $arg = shift;
       
   135 	$self->{fileflags} = $arg if(defined($arg));
       
   136 	return $self->{fileflags};
       
   137 }
       
   138 
       
   139 # How many feature flag objects have we got?
       
   140 sub NumRecords
       
   141 {
       
   142 	my $self = shift;
       
   143 	return undef unless(ref($self));
       
   144 	my $arg = shift;
       
   145 	$self->{numrecords} += $arg if(defined($arg));
       
   146 	return $self->{numrecords};
       
   147 }
       
   148 
       
   149 
       
   150 sub LsdOffset
       
   151 {
       
   152 	my $self = shift;
       
   153 	return undef unless(ref($self));
       
   154 	my $arg = shift;
       
   155 	$self->{lsdoffset} = $arg if(defined($arg));
       
   156 	return $self->{lsdoffset};
       
   157 }
       
   158 
       
   159 sub LsdSize
       
   160 {
       
   161 	my $self = shift;
       
   162 	return undef unless(ref($self));
       
   163 	my $arg = shift;
       
   164 	$self->{lsdsize} = $arg if(defined($arg));
       
   165 	return $self->{lsdsize};
       
   166 }
       
   167 
       
   168 # Create a binary string containing the header information for the
       
   169 # feature manager data file based on the various fields in this object.
       
   170 sub CreateBinaryHeader
       
   171 {
       
   172 	my $self = shift;
       
   173 	return undef unless(ref($self));
       
   174 	my $hdrstring;
       
   175 
       
   176 	# Get the letter for packing information with 'pack' into a binary form.
       
   177 	my $pack16 = lc($self->{packprefix});
       
   178 	my $pack32 = uc($self->{packprefix});
       
   179 	
       
   180 	# Get header information..
       
   181 	my $typefield = $self->TypeField();
       
   182 	my $fileversion = $self->FileVersion();
       
   183 	my $fileflags = $self->FileFlags();
       
   184 	my $numrecords = $self->NumRecords();
       
   185 	my $lsdoffset = $self->LsdOffset();
       
   186 	my $lsdsize = $self->LsdSize();
       
   187 
       
   188 	# Write the 'type' field out. This is 'feat'. Would this be different on
       
   189 	# big-endian systems?
       
   190 	$hdrstring = $typefield;
       
   191 
       
   192 	# Now the file version number. A 16-bit value.. Will this cause trouble
       
   193 	# if the shifted value is signed?
       
   194 	$hdrstring .= pack($pack16 . "1", $fileversion);
       
   195 
       
   196 	# Now the file flags. Another 16-bit value..
       
   197 	$hdrstring .= pack($pack16 . "1", $fileflags);
       
   198 
       
   199 	# Now the number of listed features - a 32-bit value.
       
   200 	$hdrstring .= pack($pack32 . "1", $numrecords);
       
   201 
       
   202 	# Now the number of listed features - a 32-bit value.
       
   203 	$hdrstring .= pack($pack32 . "1", $lsdoffset);
       
   204 
       
   205 	# Now the number of listed features - a 32-bit value.
       
   206 	$hdrstring .= pack($pack32 . "1", $lsdsize);
       
   207 
       
   208 	# Now the 3 reserved words
       
   209 	$hdrstring .= pack($pack32 . "3", (0, 0, 0));
       
   210 
       
   211 	return $hdrstring;
       
   212 }
       
   213 
       
   214 sub CreateImageHdr
       
   215 {
       
   216 	my $self = shift;
       
   217 	return undef unless(ref($self));
       
   218 	#my $partid = shift;
       
   219 	#return -1 unless(defined($partid));
       
   220 
       
   221 	# Add fingerprint, 1st reserved word and format version
       
   222 	my $imghdr = pack "V4", (0x5F524348, 0x54524150, 0x00000000, 0x00000001);
       
   223 	# Add space for image size, timestamp, 2nd reserved word
       
   224 	$imghdr .= pack "V3", (0x00000000, time, 0x00000000);
       
   225 	# Add space for payload checksum, HCR Payload constants: UID and 0x0 flags
       
   226     $imghdr .= pack "V3", (0x00000000, 0x10286AB8, 0x00000000);
       
   227     #Reserved space
       
   228     $imghdr .= pack "x216", (0x00000000);
       
   229  
       
   230     return $imghdr;
       
   231 }
       
   232 
       
   233 sub WriteToImage
       
   234 {
       
   235 	my $self = shift;
       
   236 	return undef unless(ref($self));
       
   237 	my $imgfile = shift;
       
   238 	return -1 unless(defined($imgfile));
       
   239 	my $datfile = shift;
       
   240 	return -1 unless(defined($datfile));
       
   241 	#my $partid = shift;
       
   242 	#return -1 unless(defined($partid));
       
   243 	my $rc = 0;
       
   244 	
       
   245     open IMGFILE, "> $imgfile" or die "Couldn't open file '$imgfile' for writing.\n";
       
   246 	binmode IMGFILE;
       
   247    
       
   248  	syswrite(IMGFILE, $self->CreateImageHdr(), 256);	
       
   249  	
       
   250     open DATFILE, "$datfile" or die "Couldn't open file '$datfile' for reading.\n";
       
   251 	binmode DATFILE;
       
   252 	# print FILE $self->BinaryContent();
       
   253 	
       
   254     #my $wordsum = 0x1200000000;
       
   255     #my $wordsum = Math::BigInt->new("0x0220100123");
       
   256     #printf("test: %x\n", $wordsum->external();
       
   257 
       
   258 	my $imgsize = 256;
       
   259 	my $word;
       
   260 	printf("-reading image:\n")  if ($mhd::otrace);
       
   261 	while (sysread (DATFILE, $word, 4)) {
       
   262 	    #printf ("%08x ",$word)  if ($mhd::otrace);
       
   263         my $iword = unpack("V" , $word);
       
   264 	    printf ("%08x ",$iword)  if ($mhd::otrace);
       
   265         $rc = syswrite (IMGFILE, $word, 4);
       
   266         die "error: ($rc) failed to write datfile word into imgfile.\n" if ($rc != 4);
       
   267 	    #$wordsum->badd($iword);
       
   268         $imgsize += 4;
       
   269 	    print "\n" if (($mhd::otrace) && ($imgsize%16==0));
       
   270         }
       
   271     print "\n" if ($mhd::otrace);
       
   272     # ordsum: 0x". $wordsum ."\n" if ($mhd::otrace);
       
   273 	my $checksum = 0x12345678;
       
   274 	close DATFILE;
       
   275 	
       
   276 	printf("-image size: %d, checksum: 0x%08x", $imgsize, $checksum) if ($mhd::otrace);
       
   277 	
       
   278 	$rc = sysseek(IMGFILE, 16, 0);
       
   279 	die "error: ($rc) failed to seek in image to write header.\n" if ($rc != 16);
       
   280 
       
   281 	# Write out the image size	
       
   282 	my $imginfo1 = pack "V1", ($imgsize);
       
   283 	$rc = syswrite(IMGFILE, $imginfo1, 4);
       
   284 	die "error: ($rc) failed to write image size/checksum to image header.\n" if ($rc != 4);
       
   285 
       
   286 	$rc = sysseek(IMGFILE, 28, 0);
       
   287 	die "error: ($rc) failed to seek in image to write header.\n" if ($rc != 28);
       
   288 	
       
   289 	# Write out the image checksum 
       
   290 	my $imginfo2 = pack "V1", ($checksum);
       
   291 	$rc = syswrite(IMGFILE, $imginfo2, 4);
       
   292 	die "error: ($rc) failed to write image size/checksum to image header.\n" if ($rc != 4);
       
   293   
       
   294 	close IMGFILE; 	
       
   295 	
       
   296     return 0;
       
   297 }
       
   298 
       
   299 # Writes the binary file specified as an argument with the content of this
       
   300 # and contained feature flag and dsr objects.
       
   301 sub WriteToFile
       
   302 {
       
   303 	my $self = shift;
       
   304 	return undef unless(ref($self));
       
   305 	my $file = shift;
       
   306 	return undef unless(defined($file));
       
   307     open FILE, "> $file" or die "Couldn't open file '$file' for writing.\n";
       
   308 	binmode FILE;
       
   309 	print FILE $self->BinaryContent();
       
   310 	
       
   311 	close FILE;
       
   312 	return 0;
       
   313 }
       
   314 
       
   315 
       
   316 # Create the binary equivalent of the internal data and return it as a
       
   317 # string.
       
   318 sub BinaryContent
       
   319 {
       
   320 	my $self = shift;
       
   321 	return undef unless(ref($self));
       
   322 
       
   323     # Get the feature flag entries.. This is an array reference.
       
   324 	# For each one append the binary representation of the information
       
   325 	# contained.
       
   326 	my $records = "";
       
   327     my $lsd = "";
       
   328    	my $ffs_ref = $self->SettingRecords();
       
   329 	my $ff;
       
   330 
       
   331     my $count = 0;
       
   332 	foreach $ff (@$ffs_ref)
       
   333 	{
       
   334 	    $count++;
       
   335 	    printf("-encoding record: %04d (0x%08x:%04d)\n", $count, $ff->CUID(), $ff->EID());
       
   336 		$records .= $ff->GetRecHdrBinary(length ($lsd));
       
   337 	    my $stype = $ff->Type();
       
   338     	if (($stype & 0xffff0000) && ($ff->Length() > 0)) {
       
   339 		    $lsd .= $ff->GetRecLsdBinary();
       
   340             }
       
   341 	}
       
   342 
       
   343     $self->LsdOffset(32+length ($records));     # header size 32
       
   344     $self->LsdSize(length ($lsd));
       
   345     
       
   346 	my $header = $self->CreateBinaryHeader();
       
   347 
       
   348 	return $header . $records . $lsd;
       
   349 }
       
   350 
       
   351 # Return a reference to the 'feature flags' array.
       
   352 sub SettingRecords
       
   353 {
       
   354 	my $self = shift;
       
   355 	return undef unless(ref($self));
       
   356 	return $self->{settingrecords};
       
   357 }
       
   358 
       
   359 # Add a Feature Flag object. Perhaps there should be code to check if we
       
   360 # already know about this feature flag. (i.e check the uid against the ones
       
   361 # we have).
       
   362 sub AddSettingRecord
       
   363 {
       
   364 	my $self = shift;
       
   365 	return undef unless(ref($self));
       
   366 	my $arg = shift;
       
   367 	die "panic: method 'AddSettingRecord' requires a 'HCRrec' object as argument.\n"
       
   368    	    unless(ref($arg) eq  "HCRrec");
       
   369    	
       
   370 	push @{$self->SettingRecords()}, $arg;
       
   371 	$self->NumRecords(1);
       
   372 	
       
   373     return 0;
       
   374 }
       
   375 
       
   376 
       
   377 1;
       
   378