blob: b254d0a8450345072824c4a8bac4e8c699e0a14c [file] [log] [blame]
rjw6c1fd8f2022-11-30 14:33:01 +08001#!/usr/bin/perl -W
2#
3# Copyright Statement:
4# --------------------
5# This software is protected by Copyright and the information contained
6# herein is confidential. The software may not be copied and the information
7# contained herein may not be used or disclosed except with the written
8# permission of MediaTek Inc. (C) 2005
9#
10# BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
11# THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
12# RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
13# AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
14# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
15# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
16# NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
17# SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
18# SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
19# THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
20# NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
21# SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
22#
23# BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
24# LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
25# AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
26# OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
27# MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
28#
29# THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
30# WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
31# LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
32# RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
33# THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
34#
35#
36#*****************************************************************************
37
38#use strict;
39use Fcntl;
40
41if ($#ARGV != 1) { &Usage; }
42#die "Please use 5.8.6 or later Perl interpreter\n" if $] < 5.008005;
43
44#
45# NP3R - 0 : (under construction) pre-processing & info gathering from makefile
46#
47$prefix_path = $ARGV[0];
48$themf = $ARGV[1];
49
50die "$themf did NOT exist!\n" if (!-e $themf);
51open (FILE_HANDLE, "<$themf") or die "cannot open $themf\n";
52while (<FILE_HANDLE>) {
53 if (/^(\S+)\s*=\s*(\S+)/) {
54 $keyname = lc($1);
55 defined($${keyname}) && warn "$1 redefined in $themf!\n";
56 $${keyname} = uc($2);
57 }
58}
59close (FILE_HANDLE);
60
61#
62# NP3R - 1 : determine if _NAND_FLASH_BOOTING_ defined
63#
64
65if (not defined $nand_flash_booting)
66{
67 exit(0);
68}
69
70if ($nand_flash_booting ne "ENFB" and $nand_flash_booting ne "MIXED")
71{
72 exit(0);
73}
74#
75# NP3R - 2 : Global Configuration section
76#
77my $EnfbOutputfile = "THIRD_ROM";
78my %EnfbInputFiles = (
79"CustENFBImg\0" => "plutommi\\Customer\\CustResource\\CustENFBImgData",
80"CustENFBStr\0" => "plutommi\\Customer\\CustResource\\CustENFBStrData",
81);
82my $EnfbReservedHearderSize = 256;
83my $EnfbAlignToSize = 64;
84my $sv5_offset = 0;
85#
86# NP3R - 3 : read the pre-defined 3rd ROM header content
87#
88my %EnfbInputKeys; # Key ==> id
89my %EnfbInputBegin; # Key ==> begin
90my %EnfbInputEnd; # Key ==> end
91my %EnfbBinFiles; # Key ==> external bin file length
92my $buffer;
93$EnfbOutputfile = $prefix_path . $EnfbOutputfile;
94
95sysopen( HANDLE, $EnfbOutputfile, O_RDWR ) or die $!;
96binmode(HANDLE);
97
98#SV5 binary has "MMM" tag in its first 3 bytes
99sysread(HANDLE, $buffer, 3);
100
101if($buffer eq 'MMM')
102{
103 $sv5_offset = 56;
104 print "SV5 detected\n";
105}
106
107sysseek(HANDLE, $sv5_offset, 0);
108
109while ( sysread(HANDLE, $buffer, 32) )
110{
111# my (@ID, $cid, $begin, $length, @Desc) = unpack "C11CVVC12", $buffer;
112 my @buf = unpack "C11CVVC12", $buffer;
113 my $cid = $buf[11];
114 my $begin = $buf[12];
115 my $length = $buf[13];
116 my $key = pack "C12", splice(@buf, 14, 12);
117 my $idstring = pack "C7", splice(@buf, 0, 7);
118 #printf "ID = %x , \t %s \t %x \t %x \n", $cid, $key, $begin, $length;
119 if ($cid eq 0xff)
120 {
121 &AdjustDynamicCodeBeginEnd($begin);
122 last;
123 }
124 if (defined $EnfbInputFiles{$key}) # external binary file ...
125 {
126 $EnfbInputKeys{$key} = $cid;
127 next;
128 }
129 if ($length > 0 ) # dynamic code linked ...
130 {
131 $EnfbInputKeys{$key} = $cid;
132 $EnfbInputBegin{$key} = $begin;
133 $EnfbInputEnd{$key} = $begin + $length - 1;
134 }
135 last unless ($idstring eq "ENFB3RD");
136}
137#
138# NP3R - 4 : testing existing of external members in the 3rd rom
139#
140&ChkAllExternalBehindDynamicCode();
141foreach (keys %EnfbInputKeys)
142{
143 next if not defined $EnfbInputFiles{$_};
144 my $f = $EnfbInputFiles{$_};
145 if (-e $f)
146 {
147 $EnfbBinFiles{$_} = (stat $f )[7];
148 }
149 else
150 {
151 print "External Binary File $_ ==> $f not found\n";
152 delete $EnfbInputKeys{$_};
153 }
154}
155#
156# NP3R - 5 : correct 3RD ROM header , synthetize external content to 3RD ROM
157#
158&SetupExternalBinOffset();
159&DumpInternal3rdRomHeader();
160my $read_pos = sysseek(HANDLE, 0, 1); # SEEK_CUR
161my @SortedKeyList = sort { $EnfbInputKeys{$a} <=> $EnfbInputKeys{$b} } keys %EnfbInputKeys;
162sysseek(HANDLE, $sv5_offset, 0);
163
164foreach my $h (@SortedKeyList)
165{
166 $buffer = &Pack_enfb_header( $EnfbInputKeys{$h},
167 $EnfbInputBegin{$h},
168 $EnfbInputEnd{$h},
169 $h);
170 syswrite(HANDLE, $buffer, 32);
171}
172$buffer = &Pack_enfb_header( 0xff, 0, 0, "ENDMARK");
173syswrite(HANDLE, $buffer, 32);
174 # Zero Padding ---
175my $write_pos = sysseek(HANDLE, 0, 1); # SEEK_CUR
176#print "Read position : $read_pos\n";
177#print "Write position : $write_pos\n";
178if ($read_pos > $write_pos)
179{
180 $buffer = chr(0) x ($read_pos - $write_pos);
181 syswrite(HANDLE, $buffer, $read_pos - $write_pos);
182}
183 # External Binary Append
184my $cur_pos;
185#$cur_pos = sysseek(HANDLE, 0, 2); # SEEK_END
186#print "Current position : $cur_pos\n";
187foreach my $h (@SortedKeyList)
188{
189 next if not defined $EnfbBinFiles{$h};
190 # Padding To
191 $cur_pos = sysseek(HANDLE, 0, 2); # SEEK_END
192 if ($EnfbInputBegin{$h} > $cur_pos)
193 {
194 $buffer = chr(0) x ($EnfbInputBegin{$h} - $cur_pos);
195 syswrite(HANDLE, $buffer, ($EnfbInputBegin{$h} - $cur_pos));
196 }
197 # Append To
198 sysopen(EXTBIN, $EnfbInputFiles{$h} , O_RDONLY) or die $!;
199 binmode(EXTBIN);
200 my $read_len = sysread(EXTBIN, $buffer, 8192);
201 while ($read_len)
202 {
203 syswrite(HANDLE, $buffer, $read_len);
204 $read_len = sysread(EXTBIN, $buffer, 8192);
205 }
206 close(EXTBIN);
207}
208$cur_pos = sysseek(HANDLE, 0, 2); # SEEK_END
209print "Tail position : $cur_pos\n";
210
211close (HANDLE);
212exit(0);
213#
214# NP3R ------ End of MAIN BODY -----------
215#
216
217sub Align
218{
219 my ($size, $orig) = @_;
220
221 return $size * (int($orig/$size) + 1);
222}
223
224sub Pack_enfb_header
225{
226 my ($cid, $begin, $end, $description ) = @_;
227 my $ID = "ENFB3RDROM!";
228 my @ID = unpack "C*", $ID;
229 my $buf;
230 my @Desc = unpack "C*", $description;
231
232 $buf = pack "C11CVVC12", @ID, $cid, $begin, $end, @Desc ;
233 return $buf;
234}
235
236#
237# NP3R ------ Shift the being & end ------
238#
239sub AdjustDynamicCodeBeginEnd
240{
241 my ($base) = @_;
242 foreach my $k (keys %EnfbInputKeys)
243 {
244 next unless defined $EnfbInputBegin{$k};
245 $EnfbInputBegin{$k} -= $base;
246 $EnfbInputEnd{$k} -= $base;
247 }
248}
249
250#
251# NP3R ------ Debug use ------
252#
253sub DumpInternal3rdRomHeader
254{
255 foreach my $k (sort { $EnfbInputKeys{$a} <=> $EnfbInputKeys{$b} } keys %EnfbInputKeys)
256 {
257 if (defined $EnfbBinFiles{$k}) # external binary files
258 {
259 print $k, "\t", $EnfbInputKeys{$k}, "\t", $EnfbInputBegin{$k}, "\t", $EnfbInputEnd{$k}, "\t";
260 print "External BIN files\t size : ", $EnfbBinFiles{$k} , "\n";
261 }
262 else # linked dynamic code on NAND flash
263 {
264 print $k, "\t", $EnfbInputKeys{$k}, "\t", $EnfbInputBegin{$k}, "\t", $EnfbInputEnd{$k}, "\n";
265 }
266 }
267}
268
269#
270# NP3R ------ check if external bin cid larger than internal code cid ------
271#
272sub ChkAllExternalBehindDynamicCode
273{
274 my @codelist = keys %EnfbInputEnd;
275 #print "CODE LIST at Chk: $#codelist \n";
276 #map { print "CODE: ", $_, "\n"; } @codelist;
277 return if ($#codelist == -1);
278 my @SortedKeyList = sort { $EnfbInputKeys{$a} <=> $EnfbInputKeys{$b} } keys %EnfbInputKeys;
279 my @SortedCodeList = sort { $EnfbInputKeys{$a} <=> $EnfbInputKeys{$b} } @codelist;
280 my $lastidx = $#codelist;
281 die "External BIN cid must behind code cid"
282 unless ($SortedCodeList[$lastidx] eq $SortedKeyList[$lastidx]);
283}
284
285#
286# NP3R ------ check if external bin cid larger than internal code cid ------
287#
288sub SetupExternalBinOffset
289{
290 my @codelist = keys %EnfbInputEnd;
291 #print "CODE LIST at Setup: $#codelist \n";
292 #map { print "CODE: ", $_, "\n"; } @codelist;
293 my $ExtBinBegin;
294 if ($#codelist == -1)
295 {
296 $ExtBinBegin = $EnfbReservedHearderSize + $sv5_offset;
297 }
298 elsif ($#codelist == 0)
299 {
300 $ExtBinBegin = &Align( $EnfbAlignToSize, $EnfbInputEnd{ $codelist[-1] } );
301 }
302 else
303 {
304 my @SortedCodeList = sort { $EnfbInputKeys{$a} <=> $EnfbInputKeys{$b} } @codelist;
305 #print "The Last one : ", $SortedCodeList[-1], "\n";
306 $ExtBinBegin = &Align( $EnfbAlignToSize, $EnfbInputEnd{ $SortedCodeList[-1] } );
307 }
308 # okay , external bin setup begin and offset
309 foreach my $ebin ( sort { $EnfbInputKeys{$a} <=> $EnfbInputKeys{$b} } keys %EnfbBinFiles)
310 {
311 $EnfbInputBegin{$ebin} = $ExtBinBegin;
312 $EnfbInputEnd{$ebin} = $ExtBinBegin + $EnfbBinFiles{$ebin} - 1;
313 $ExtBinBegin = &Align( $EnfbAlignToSize, $ExtBinBegin + $EnfbBinFiles{$ebin} );
314 }
315}
316
317sub Usage {
318 print "perl nfbpack3rdrom.pl <binary path> <Project MakeFile>\n";
319}
320