同学,仍需努力啊!
2015年(23)
分类: LINUX
2015-04-14 12:10:25
0-前言:
第一个任务是screencast抓屏花屏的问题完了之后,头儿又给了一个新任务:
QFIT转Img时出现了问题。
1-何为QFIT:
这个我之前还从来没听过,反正就是一个工具,BP代码编出来的一个工具,它用于将多个IMG合成为一个img,然后工厂将这个img烧写到flash芯片
中,再将flash芯片焊在手机上。
我们编出来的Img总共有6
个:boot.img,system.img,userdata.img,splash.img,persist.img,recovery.img,要
将这6个转在一个名叫:factoryimage2.mbn的文件。可现在只能正常转换boot.img,system.img,userdata.img,这三个,其它三个就有warning:
Use of uninitialized value in subroutine entry at Add_Spare_Area.pm line 410
Use of uninitialized value in pack at Calc_Spare_Area.pm line 185
让我分析这个warning是如何产生的,还有就是会对我们的img产生什么样的影响。
2-我的分析:
一:现象
上面图(1)是在windows的dos下执行qfit.cmd后的效果,图(2)便是与之相对应的Log文件。从图(1)中可以看到在操作splash.img时与boot.img,system.img不同的是在 Converting ..\..\build\ms\bin\TSNCJOLY\splash.img
to Local/splash.ecc之后出现了下面两个warnings
Use of uninitialized value in subroutine entry at Add_Spare_Area.pm line 410.
Use of uninitialized value in pack at Calc_Spare_Area.pm line 185.
根据提示很容易找到代码所在地:at Calc_Spare_Area.pm line 185
main::rs_encoder(\@buffer_temp,\@ecc,$ECC_BUFFER_BYTES_516,$ECC_10_BYTES);
从语法上来讲是传给函数rs_encoder的第二个参数\@ecc表示一个地址,用来让参数作为返回值,其具体的意义就不太清楚了。其所在的函数为:sub add_ctrl_7500_page_2048_width_16_main_and_spare_ecc_10。下面就分析这个函数是怎么被调用到的。这个可以根据Log文件来查找,因为代码所执行的所有打印信息都在log文件中会有显示出来。将图(1)和图(2)结合来看提示的warning是在打印语句Converting ..\..\build\ms\bin\TSNCJOLY\splash.img to Local/splash.ecc和File= Local/splash.ecc之间。
所在文件 :行数:所在函数
Make_Factory_Image.pm:107:make_factory_image
——》(表示调用) Make_Factory_Image.pm:797:process_data_file_ecc
Make_Factory_Image.pm:1164: process_data_file_ecc
{
.
.
Tools::print_log(0," Converting $data_file_name \n to $ecc_file \n");
Calc_Spare_Area::add_ecc_to_file
my $error = Calc_Spare_Area::add_ecc_to_file()
Tools::print_log(0, " File = $ecc_file ");
.
.
}
从这个process_data_file_ecc函数里面的上面粘出来的代码可以看出来,warning就出在
add_ecc_to_file这个函数中,下面看add_ecc_to_file函数
Calc_Spare_Area.pm:60:add_ecc_to_file
{
Add_Spare_Area::calc_ecc({
array_ref => \@Buffer,
cfg_ref => $cfg_ref,
page_layout => $page_layout,
});
$string = pack('C*',@Buffer);
print {$ECCFILE} $string;
Tools::print_log(5, ".");
}
log中所提示的
Use of uninitialized value in pack at Calc_Spare_Area.pm line 185.
便是add_ecc_to_file函数中的$string = pack('C*',@Buffer);这条语句。而
Use of uninitialized value in subroutine entry at Add_Spare_Area.pm line 410.先于
Use of uninitialized value in pack at Calc_Spare_Area.pm line 185.所以
Use of uninitialized value in subroutine entry at Add_Spare_Area.pm line 410.便是在
Add_Spare_Area::calc_ecc()中的,下面看Add_Spare_Area::calc_ecc()
Add_Spare_Area.pm:92:sub calc_ecc{
my ($arg_ref) = @_;
my $page_layout = $arg_ref->{page_layout};
#$DB::single=1;
#Tools::printf_log(10,"\ngaomaolin:calc_eec:page_layout= 0x%04d",$page_layout);
if(defined $dispatch_add_spare{$page_layout}) {
&{$dispatch_add_spare{$page_layout}}($arg_ref); #this is a function call
return 0;
}
else {
main::popup_msg_ok_error('Add_Spare_Area::calc_ecc',"Unsupported page_layout = $page_layout ");
#Tools::print_log(0, "Unsupported page_layout = $page_layout \n");
return 1;
}
}
可以看到这里面调用了
&{$dispatch_add_spare{$page_layout}}($arg_ref); #this is a function call
可以看到
Add_Spare_Area.pm:69:sub dispatch_init{
%dispatch_add_spare = Calc_Spare_Area::dispatch_add_init;
for my $index (0..15) {
$array_16_0xFF_bytes[$index] = 0xFF;
}
}调用Calc_Spare_Area::dispatch_add_init对dispatch_add_spare进行了初始化。
仔细去看一下Calc_Spare_Area:1119:dispatch_add_init函数的实现便可以知道dispatch_add_init将总共24个计算ecc的函数装在一个数组,然后根据传进的索引值进行调用。其中第0x12个函数的调用就是导致warnings:Use of uninitialized value in subroutine entry at Add_Spare_Area.pm line 410.的函数:
$CTRL_7500_PAGE_2048_WIDTH_16_MAIN_AND_SPARE_ECC_10 => 'add_ctrl_7500_page_2048_width_16_main_and_spare_ecc_10',
再回到
Add_Spare_Area.pm:92:sub calc_ecc{
my ($arg_ref) = @_;
my $page_layout = $arg_ref->{page_layout};
#$DB::single=1;
#Tools::printf_log(10,"\ngaomaolin:calc_eec:page_layout= 0x%04d",$page_layout);
if(defined $dispatch_add_spare{$page_layout}) {
&{$dispatch_add_spare{$page_layout}}($arg_ref); #this is a function call
这里可以看到&{$dispatch_add_spare{$page_layout}} 是根据page_layout来选择不同的ecc计算函数来实现的。下面我们就追踪这个page_layout的来源。
二:page_layout出于何处:
QFIT.pl:3867:sub show_no_target_connected{}
——》my $cfg_ref = Tools::get_config_data();
——》display_configuration($cfg_ref)
——》my $page_layout = Calc_Spare_Area::calc_page_layout
仔细查看calc_page_layout这个函数的实现
my $found_page_layout = $page_layout{$nand_controller}{$device_type}{$page_bytes_user}{$flash_width}{$ecc_over_main_spare}{$partition_file};
#all other partition files
$found_page_layout = $page_layout{$nand_controller}{$device_type}{$page_bytes_user}{$flash_width}{$ecc_over_main_spare};
就是通过上面这 两句话来对page_layout进行计算的,在这里面加上打印语句将,$found_page_layout打印出来在log里面有如下信息:
calc_page_layout in Make_Factory_Image 409
gaomaolin0:page_layout= 0x0017 8 0:BOOT 0x00000227 0x00000028 main_and_spare_ecc_10 1x_pages ..\..\build\ms\bin\TSNCJOLY\boot.img
calc_page_layout in Make_Factory_Image 409
gaomaolin0:page_layout= 0x0018 9 0:SYSTEM 0x0000024F 0x00000640 main_and_spare_ecc_10 1x_pages ..\..\build\ms\bin\TSNCJOLY\system.img
calc_page_layout in Make_Factory_Image 409
gaomaolin1:page_layout= 0x001210 0:SPLASH 0x0000088F 0x00000008 main_and_spare_ecc_10 1x_pages ..\..\build\ms\bin\TSNCJOLY\splash.img
11 0:CACHE 0x00000897 0x00000140 main_and_spare_ecc_10 1x_pages
calc_page_layout in Make_Factory_Image 409
gaomaolin0:page_layout= 0x001812 0:USERDATA 0x000009D7 0x000005F5 main_and_spare_ecc_10 1x_pages ..\..\build\ms\bin\TSNCJOLY\userdata.img
calc_page_layout in Make_Factory_Image 409
gaomaolin1:page_layout= 0x001213 0:PERSIST 0x00000FCC 0x0000000C main_and_spare_ecc_10 1x_pages ..\..\build\ms\bin\TSNCJOLY\persist.img
calc_page_layout in Make_Factory_Image 409
gaomaolin1:page_layout= 0x001214 0:RECOVERY 0x00000FD8 0x00000028 main_and_spare_ecc_10 1x_pages ..\..\build\ms\bin\TSNCJOLY\recovery.img
从上面的打印信息可以看出出warning的三个Img(splash.img,persist.img,recovery.img)的page_layout都是0x12。
下面是我们组长写的:
在使用qfit生成factoryimage2.mbn时,转换splash.img persist.imgh和recovery.img会有一些warning信息出现:
Use of uninitialized value in subroutine entry at Add_Spare_Area.pm line 410
Use of uninitialized value in pack at Calc_Spare_Area.pm line 185
经查第一条信息出现在文件Add_Spare_Area.pm 中 add_ctrl_7500_page_2048_width_16_main_and_spare_ecc_10中。
但我们boot,system,userdata走的是add_ctrl7500_page2048_width16_main512_spare4_ecc10_G1。
所以感觉这是两种不同的生成ecc的方式。但对于同一个flash来说,应该是一种。
所以最终我在Calc_Spare_Area.pm中加了一下代码,使所有生成ecc的函数都走add_ctrl7500_page2048_width16_main512_spare4_ecc10_G1,不知这样是否正确?
(主要是不清楚你们编译深成img中的格式)
$page_layout{'nand_controller_7500' }{'SLC'}{2048}{16}{'main_and_spare_ecc_10'}{'splash.img'}
= $Ctrl7500_page2048_width16_main512_spare4_ecc10_G1;
$page_layout{'nand_controller_7500' }{'SLC'}{2048}{16}{'main_and_spare_ecc_10'}{'persist.img'}
= $Ctrl7500_page2048_width16_main512_spare4_ecc10_G2;
$page_layout{'nand_controller_7500' }{'SLC'}{2048}{16}{'main_and_spare_ecc_10'}{'recovery.img'}
= $Ctrl7500_page2048_width16_main512_spare4_ecc10_G2;
我们nand的信息是:
Page:2048,block:64page, block num:4096, bus width:16 ,block size:128K flash size:512M