blob: b254d0a8450345072824c4a8bac4e8c699e0a14c [file] [log] [blame]
#!/usr/bin/perl -W
#
# Copyright Statement:
# --------------------
# This software is protected by Copyright and the information contained
# herein is confidential. The software may not be copied and the information
# contained herein may not be used or disclosed except with the written
# permission of MediaTek Inc. (C) 2005
#
# BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
# THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
# RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
# AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
# NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
# SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
# SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
# THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
# NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
# SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
#
# BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
# LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
# AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
# OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
# MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
#
# THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
# WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
# LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
# RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
# THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
#
#
#*****************************************************************************
#use strict;
use Fcntl;
if ($#ARGV != 1) { &Usage; }
#die "Please use 5.8.6 or later Perl interpreter\n" if $] < 5.008005;
#
# NP3R - 0 : (under construction) pre-processing & info gathering from makefile
#
$prefix_path = $ARGV[0];
$themf = $ARGV[1];
die "$themf did NOT exist!\n" if (!-e $themf);
open (FILE_HANDLE, "<$themf") or die "cannot open $themf\n";
while (<FILE_HANDLE>) {
if (/^(\S+)\s*=\s*(\S+)/) {
$keyname = lc($1);
defined($${keyname}) && warn "$1 redefined in $themf!\n";
$${keyname} = uc($2);
}
}
close (FILE_HANDLE);
#
# NP3R - 1 : determine if _NAND_FLASH_BOOTING_ defined
#
if (not defined $nand_flash_booting)
{
exit(0);
}
if ($nand_flash_booting ne "ENFB" and $nand_flash_booting ne "MIXED")
{
exit(0);
}
#
# NP3R - 2 : Global Configuration section
#
my $EnfbOutputfile = "THIRD_ROM";
my %EnfbInputFiles = (
"CustENFBImg\0" => "plutommi\\Customer\\CustResource\\CustENFBImgData",
"CustENFBStr\0" => "plutommi\\Customer\\CustResource\\CustENFBStrData",
);
my $EnfbReservedHearderSize = 256;
my $EnfbAlignToSize = 64;
my $sv5_offset = 0;
#
# NP3R - 3 : read the pre-defined 3rd ROM header content
#
my %EnfbInputKeys; # Key ==> id
my %EnfbInputBegin; # Key ==> begin
my %EnfbInputEnd; # Key ==> end
my %EnfbBinFiles; # Key ==> external bin file length
my $buffer;
$EnfbOutputfile = $prefix_path . $EnfbOutputfile;
sysopen( HANDLE, $EnfbOutputfile, O_RDWR ) or die $!;
binmode(HANDLE);
#SV5 binary has "MMM" tag in its first 3 bytes
sysread(HANDLE, $buffer, 3);
if($buffer eq 'MMM')
{
$sv5_offset = 56;
print "SV5 detected\n";
}
sysseek(HANDLE, $sv5_offset, 0);
while ( sysread(HANDLE, $buffer, 32) )
{
# my (@ID, $cid, $begin, $length, @Desc) = unpack "C11CVVC12", $buffer;
my @buf = unpack "C11CVVC12", $buffer;
my $cid = $buf[11];
my $begin = $buf[12];
my $length = $buf[13];
my $key = pack "C12", splice(@buf, 14, 12);
my $idstring = pack "C7", splice(@buf, 0, 7);
#printf "ID = %x , \t %s \t %x \t %x \n", $cid, $key, $begin, $length;
if ($cid eq 0xff)
{
&AdjustDynamicCodeBeginEnd($begin);
last;
}
if (defined $EnfbInputFiles{$key}) # external binary file ...
{
$EnfbInputKeys{$key} = $cid;
next;
}
if ($length > 0 ) # dynamic code linked ...
{
$EnfbInputKeys{$key} = $cid;
$EnfbInputBegin{$key} = $begin;
$EnfbInputEnd{$key} = $begin + $length - 1;
}
last unless ($idstring eq "ENFB3RD");
}
#
# NP3R - 4 : testing existing of external members in the 3rd rom
#
&ChkAllExternalBehindDynamicCode();
foreach (keys %EnfbInputKeys)
{
next if not defined $EnfbInputFiles{$_};
my $f = $EnfbInputFiles{$_};
if (-e $f)
{
$EnfbBinFiles{$_} = (stat $f )[7];
}
else
{
print "External Binary File $_ ==> $f not found\n";
delete $EnfbInputKeys{$_};
}
}
#
# NP3R - 5 : correct 3RD ROM header , synthetize external content to 3RD ROM
#
&SetupExternalBinOffset();
&DumpInternal3rdRomHeader();
my $read_pos = sysseek(HANDLE, 0, 1); # SEEK_CUR
my @SortedKeyList = sort { $EnfbInputKeys{$a} <=> $EnfbInputKeys{$b} } keys %EnfbInputKeys;
sysseek(HANDLE, $sv5_offset, 0);
foreach my $h (@SortedKeyList)
{
$buffer = &Pack_enfb_header( $EnfbInputKeys{$h},
$EnfbInputBegin{$h},
$EnfbInputEnd{$h},
$h);
syswrite(HANDLE, $buffer, 32);
}
$buffer = &Pack_enfb_header( 0xff, 0, 0, "ENDMARK");
syswrite(HANDLE, $buffer, 32);
# Zero Padding ---
my $write_pos = sysseek(HANDLE, 0, 1); # SEEK_CUR
#print "Read position : $read_pos\n";
#print "Write position : $write_pos\n";
if ($read_pos > $write_pos)
{
$buffer = chr(0) x ($read_pos - $write_pos);
syswrite(HANDLE, $buffer, $read_pos - $write_pos);
}
# External Binary Append
my $cur_pos;
#$cur_pos = sysseek(HANDLE, 0, 2); # SEEK_END
#print "Current position : $cur_pos\n";
foreach my $h (@SortedKeyList)
{
next if not defined $EnfbBinFiles{$h};
# Padding To
$cur_pos = sysseek(HANDLE, 0, 2); # SEEK_END
if ($EnfbInputBegin{$h} > $cur_pos)
{
$buffer = chr(0) x ($EnfbInputBegin{$h} - $cur_pos);
syswrite(HANDLE, $buffer, ($EnfbInputBegin{$h} - $cur_pos));
}
# Append To
sysopen(EXTBIN, $EnfbInputFiles{$h} , O_RDONLY) or die $!;
binmode(EXTBIN);
my $read_len = sysread(EXTBIN, $buffer, 8192);
while ($read_len)
{
syswrite(HANDLE, $buffer, $read_len);
$read_len = sysread(EXTBIN, $buffer, 8192);
}
close(EXTBIN);
}
$cur_pos = sysseek(HANDLE, 0, 2); # SEEK_END
print "Tail position : $cur_pos\n";
close (HANDLE);
exit(0);
#
# NP3R ------ End of MAIN BODY -----------
#
sub Align
{
my ($size, $orig) = @_;
return $size * (int($orig/$size) + 1);
}
sub Pack_enfb_header
{
my ($cid, $begin, $end, $description ) = @_;
my $ID = "ENFB3RDROM!";
my @ID = unpack "C*", $ID;
my $buf;
my @Desc = unpack "C*", $description;
$buf = pack "C11CVVC12", @ID, $cid, $begin, $end, @Desc ;
return $buf;
}
#
# NP3R ------ Shift the being & end ------
#
sub AdjustDynamicCodeBeginEnd
{
my ($base) = @_;
foreach my $k (keys %EnfbInputKeys)
{
next unless defined $EnfbInputBegin{$k};
$EnfbInputBegin{$k} -= $base;
$EnfbInputEnd{$k} -= $base;
}
}
#
# NP3R ------ Debug use ------
#
sub DumpInternal3rdRomHeader
{
foreach my $k (sort { $EnfbInputKeys{$a} <=> $EnfbInputKeys{$b} } keys %EnfbInputKeys)
{
if (defined $EnfbBinFiles{$k}) # external binary files
{
print $k, "\t", $EnfbInputKeys{$k}, "\t", $EnfbInputBegin{$k}, "\t", $EnfbInputEnd{$k}, "\t";
print "External BIN files\t size : ", $EnfbBinFiles{$k} , "\n";
}
else # linked dynamic code on NAND flash
{
print $k, "\t", $EnfbInputKeys{$k}, "\t", $EnfbInputBegin{$k}, "\t", $EnfbInputEnd{$k}, "\n";
}
}
}
#
# NP3R ------ check if external bin cid larger than internal code cid ------
#
sub ChkAllExternalBehindDynamicCode
{
my @codelist = keys %EnfbInputEnd;
#print "CODE LIST at Chk: $#codelist \n";
#map { print "CODE: ", $_, "\n"; } @codelist;
return if ($#codelist == -1);
my @SortedKeyList = sort { $EnfbInputKeys{$a} <=> $EnfbInputKeys{$b} } keys %EnfbInputKeys;
my @SortedCodeList = sort { $EnfbInputKeys{$a} <=> $EnfbInputKeys{$b} } @codelist;
my $lastidx = $#codelist;
die "External BIN cid must behind code cid"
unless ($SortedCodeList[$lastidx] eq $SortedKeyList[$lastidx]);
}
#
# NP3R ------ check if external bin cid larger than internal code cid ------
#
sub SetupExternalBinOffset
{
my @codelist = keys %EnfbInputEnd;
#print "CODE LIST at Setup: $#codelist \n";
#map { print "CODE: ", $_, "\n"; } @codelist;
my $ExtBinBegin;
if ($#codelist == -1)
{
$ExtBinBegin = $EnfbReservedHearderSize + $sv5_offset;
}
elsif ($#codelist == 0)
{
$ExtBinBegin = &Align( $EnfbAlignToSize, $EnfbInputEnd{ $codelist[-1] } );
}
else
{
my @SortedCodeList = sort { $EnfbInputKeys{$a} <=> $EnfbInputKeys{$b} } @codelist;
#print "The Last one : ", $SortedCodeList[-1], "\n";
$ExtBinBegin = &Align( $EnfbAlignToSize, $EnfbInputEnd{ $SortedCodeList[-1] } );
}
# okay , external bin setup begin and offset
foreach my $ebin ( sort { $EnfbInputKeys{$a} <=> $EnfbInputKeys{$b} } keys %EnfbBinFiles)
{
$EnfbInputBegin{$ebin} = $ExtBinBegin;
$EnfbInputEnd{$ebin} = $ExtBinBegin + $EnfbBinFiles{$ebin} - 1;
$ExtBinBegin = &Align( $EnfbAlignToSize, $ExtBinBegin + $EnfbBinFiles{$ebin} );
}
}
sub Usage {
print "perl nfbpack3rdrom.pl <binary path> <Project MakeFile>\n";
}