$sudo fastboot getvar version-bootloader; #Bootloader的版本号; product,产品名称; serialno,产品序列号;
$adb reboot [bootloader|recovery];#reboots the device, optionally into the bootloader or recovery program;#负责进入不同的模式;
$fastboot update update.zip #reflash device from update.zip;将update.zip刷入;
$./mk prj new; $./mk prj otapackage; #编译完,将在\out\target\product\prj\目录下生成prj-ota-eng.root.zip,这个zip将是我们升级用的包,我们要把他改名为update.zip;
$./build/tools/releasetools/ota_from_target_files -i old.zip new.zip diff.zip; #产生new.zip到old.zip 的增量包diff.zip;修改diff.zip名字为update.zip#源码目录下;
系统更新,在aosp源码中没有;服务器存储一个增量包,下载完成后,客户端执行升级命令;#otaUpdateApp是厂商自己实现的;
OTA升级apk内部调用函数为RecoverySystem.installPackage(mContext, mUpdateFile);
android.os包下,public class RecoverySystem{ *** }
fastboot是AndroidSDK里面的一个小工具,它能够还原你的设备的分区,它是替代安装和更新的恢复模式。
android.os.RecoverySystem这是AndroidFramework所提供的标准API,用來驗證與安裝 update image。以 OTA 方式更新Android的话,就是使用这个API来驗證 update image;
在下载UpdateImage后,要先利用android.os.RecoverySystem將RC command files 寫至 /cache/recovery,再將手機重開機至 Recovery mode。
RC是RecoveryConsole的意思,这其实是一個精簡的開機環境,有點像以往的EmbeddedLinux的InitialRootFilesystem;进入RecoveryConsole后,它会自動驗證 updateimage,接著執行更新命令;
RC command files采用一个称为Edify的语言撰寫。请注意,RC的command file并不是使用典型的shell script语法撰寫
$make target-files-package; #利用mkbookimg来制作;
$make clean-libwebcore; $make -j4 libwebcore; #clean某一类库;编译某一类库;
$sudo flashboot -w update zip_self.zip; #直接把img文件和android-info.txt打成zip_self.zip;-w,erase userdata and cache (and format if supported by partition type);
$make otapackage -j4; #首先编译整个系统生成对应img文件,并生成zip包;zip是签过名的;\out\*\flo\用于recovery模式下的ota升级;\out\*\flo\obj\PACKAGING\target_files_intermediates\用于RecoverySystem的ota升级;
$adb sideload aosp_flo-ota-eng.intelgb.zip; #外部载入.zip升级包(上一步生成的zip包);即运行RecoverySystem.installPackage(*)程序后选择apply update from ADB;
RecoverySystem.installPackage(*);/system/app/*.app会还原;/vendor/*会还原;安装的第三方app不会被覆盖;/data/ota-old.zip不会被覆盖;
三种启动模式:正常启动;bootlaoder模式,可以使用fastboot命令;recovery模式;
bootloader又有三种方式,按照BCB(Bootloader Control Block)中command分类:command=='boot-recovery',启动recovery.img;recovery模式;command=='update-radio/hboot',更新firmware(bootloader);其他,启动boot.img;
两种recoveryCase:FACTORY RESET(恢复出厂设置);OTA INSTALL(OTA升级);
signature verification failed;原因是recovery的签名认证问题;源码位置bootable/recovery/install.cpp中;
ota升级中还涉及到包的数字签名,签名方式和普通JAR文件签名差不错。公钥会被硬编译入recovery,编译时生成在:out/target/product/XX/obj/PACKAGING/ota_keys_inc_intermediates/keys.inc
android上主要有六个分区:cache,misc,recovery,boot,system,userdata;
cache是缓存空间,程序和系统用到的缓存数据和指令就存放在这,CPU在调用和执行命令是会优先调用这里的数据;misc分区中有BCB(Bootloader Control Block),主要是用于存放Recovery引导信息;
linux中misc来命名,表示该文件目前还没归类好,不知道将它归到哪个方面或者放置在哪个地方比较好,所以暂时用misc;
recovery_api_version的错误,原因调用WriteIncrementalOTAPackage会zip包的META/misc_info.txt;生成的原始的zip包在out/target/product/flo/obj/PACKAGING/target_files_intermediates/目录下,它是中间生产物;
$./*/ota_from_target_files -p out/host/linux-x86 -k build/target/product/security/testkey -n out/*/obj/PACKAGING/target_files_intermediates/target.zip {output_zip} #签名;
$./*/ota_from_target_files -i ota_orignal_1.zip ota_orignal_2.zip diff.zip; #生成差量包;
Updater是updater.Google的代码架构,设计非常好,各部分尽量松耦合;Updater可以作为学习解释器/编译器的同学一个很好的实例;源码位置bootable/recovery/updater/*;两种脚本类型,amend和edify格式的脚本;
如果ota增量包中包含recovery内容,则之前重新刷入的recovery会被还原;ota增量包没有recovery内容,则recovery会是重新刷入的recovery,不会改变;
升级的应用程序必须是系统应用:"需要重新启动权限,写入recovery/command/目录权限"
安装系统应用直接push进入,系统会监测该目录,并显示到桌面;
系统属性文件在/out/*/flo/system/build.prop;手动删除就会被重新编译,生成build包;
recovery模式下通过创建一个新的进程读取并执行脚本文件META-INF/com/google/android/updater-script;
linux中函数fork与execv的用法:
fork创建新的进程,fork调用的一个奇妙之处就是它仅仅被调用一次,却能够返回两次,它可能有三种不同的返回值1)在父进程中,fork返回新创建子进程的进程ID;2)在子进程中,fork返回0;3)如果出现错误,fork返回一个负值;
execv会停止执行当前的进程,并且以progname应用进程替换被停止执行的进程,进程ID没有改变。
updater主要由bootable/recovery/updater目录下的install.c和updater.c编译而成,主函数位于updater.c。
其中,在install.c中定义了读写系统存储区的操作函数(这才是重写系统数据的真正代码)并将这些函数与updater-script中的指令映射起来。而在updater.c会首先装载install.c定义的函数,之后便解析升级脚本updater-script,执行其对应的操作命令。与此同时,执行updater的进程还会与父进程通信,通知父进程进行UI的相关操作(代码见bootable/recovery/install.c中的try_update_binary函数)。
OTA升级包路径META-INF\com\google\android中,存在着两个关键的文件:update-script和update-binary;在这两个脚本文件中,update-script记载着系统升级所需要执行的命令,而update-binary则是对于每条命令的解析;
./bootable/recovery/install.c中的try_update_binary函数,是真正实现读取升级包中的脚本文件并执行相应的函数的地方;在此函数中,通过调用fork函数创建出一个子进程,在子进程中开始读取并执行升级脚本文件;
子进程创建成功后,开始执行升级代码,并通过管道与父进程交互(代码27-28,创建管道,并将pipefd[1]作为参数传递给子进程,子进程则将相关信息写入到此管道描述符中);而父进程则通过读取子进程传递过来的信息更新UI;
forkDemo
int main(void){
int i=0;
printf("i son/pa ppid pid fpid/n");
//ppid指当前进程的父进程pid
//pid指当前进程的pid,
//fpid指fork返回给当前进程的值
for(i=0;i<2;i++){
pid_t fpid=fork();
if(fpid==0)
printf("%d child %4d %4d %4d/n",i,getppid(),getpid(),fpid);
else
printf("%d parent %4d %4d %4d/n",i,getppid(),getpid(),fpid);
}
return 0;
}
运行结果是:
i son/pa ppid pid fpid
0 parent 2043 3224 3225
0 child 3224 3225 0
1 parent 2043 3224 3226
1 parent 3224 3225 3227
1 child 1 3227 0
1 child 1 3226 0
shell权限是shell权限; root权限是root权限; systemApp权限是systemApp权限; android.uid.system权限是android.uid.system权限;
ota增量升级,整体上,验证/system/build.prop的属性;局部上,40位校验值来表示该文件没有被修改过;
android恢复出厂设置,系统一共做了两件事:往/cache/recovery/command文件中写入命令字段;重启系统;
进入recovery模式有两种(需要blob的支持):通过读取/cache分区中文件/cache/recovery/command内容进入;通过按键操作进入(同时按Power和VolumeUp);
升级程序运行升级包中update-script脚本来执行各种不同的自定义升级,脚本中是一组recovery模式下系统能识别的UI控制命令和文件系统操作命令,如write_raw_image(烧写FLASH分区)/copy_dir(复制目录)等等。
恢复出厂设置的时候/cache/recovery/command的内容为--wipe-data;
Setting中的开发选项功能:
SystemProperties类,位置/frameworks/base/core/java/android/os;
SystemProperties.set("debug_layout",*);//设置系统属性;eg显示View边界信息等等属性;内部调用native_set()方法;
String[] services = ServiceManager.listServices();//获取存活的Service名称;
IBinder obj = ServiceManager.checkService(service);//获取对应Service;
Parcel data = Parcel.obtain();//
obj.transact(IBinder.SYSPROPS_TRANSACTION, data, null, 0);//