分类 Android 下的文章

转自: https://blog.csdn.net/gangjindianzi/article/details/100554482?utm_medium=distribute.pc_relevant.none-task-blog-2~default~BlogCommendFromMachineLearnPai2~default-1.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2~default~BlogCommendFromMachineLearnPai2~default-1.control

一定要对源码体系有足够的认知,才能对刷机有深刻的理解。现在只能概述了

最底层各种硬件设备略过不提

Bootloader:PC主板上一小段程序叫BIOS,主板加电跑起来的第一个程序,负责初始化硬件,OS启动,嵌入式设备里也有类似的程序,不叫BIOS,叫Bootloader。使用最广泛的是一个叫uboot的程序,编译后生成uboot.bin镜像,烧到特定分区,就可以作为Bootloader使用。

Bootloader支持交互式启动,也就是初始化硬件完成后,不是马上启动OS,而是停留在当前状态。等待用户输入命令告诉他接下来干什么,这种启动模式叫Fastboot模式。 adb reboot bootloader 进入Fastboot模式。

进入Fastboot之前,先了解ROM结构。一个能够正常启动的ROM包含以下四个分区。

  1. Bootloader,存放uboot.bin的分区
  2. Bootloader用来保存环境变量的分区
  3. Kernel,存放os内核的分区
  4. Rootfs,存入系统第一个进程init对应的程序的分区

Fastboot模式下,可以通过另外一个工具fastboot来让设备执行指定的命令,对于刷机者来说,最常用的就是刷入各种镜像文件。例如,Kernel分区和Rootfs分区刷入指定的镜像。

android设备上,处于Fastboot模式时(就是烧写了Bootloader),我们可以把一个包含Kernel和Rootfs的Recovery.img镜像通过fastboot工具刷入到设备上一个叫Revovery的分区去,就是刷Recovery,属于刷ROM的一种,Recovery包含有Kerne和Rootfs,因此Recovery刷入设备后可以让设备正常的启动起来,这个启动方式叫Recovery模式 adb reboot recovery

总结一下,Bootloader程序即uboot.bin启动完毕,进入Fastboot模式,用fastboot工具刷入Recovery.img镜像后,进入Recovery模式。

当设备处于Recovery模式时,我们可以做些什么呢?答案是取决于刷入的Recovery.img所包含的Rootfs所包含的程序。更确切地说,是取决于Rootfs镜像里面的init程序都做了些什么事情。不过顾名思义,Recovery就是用来恢复系统的意思,也包含有更新系统的意思。这里所说的系统,是用户正常使用的系统,里面包含有Android运行时框架,使得我们可以在上面安装和使用各种APP

用户正常使用Android设备时的系统,主要是包含有两个分区:System分区和Boot分区。System分区包含有Android运行时框架、系统APP以及预装的第三方APP等,而Boot分区包含有Kernel和Rootfs。刷入到System分区和Boot分区的两个镜像称为system.img和boot.img,我们通常将它们打包和压缩为一个zip文件,例如update.zip,并且将它上传到Android设备上的sdcard上去。这样当我们进入到Recovery模式时,就可以在Recovery界面上用我们之前上传到sdcard的zip包来更新用户正常使用Android设备时所用的系统了。这个过程就是通常所说的刷ROM了。

广义上的刷ROM,实际上包含更新Recovery(Kernel和Rootfs)和更新用户正常使用的系统两个意思;而狭义上的刷ROM,只是更新用户正常使用的那个系统。更新Recovery需要进入到Fastboot模式中,而更新用户正常使用的那个系统需要进入到Recovery模式中。Android设备在启动的过程中,在默认情况下,一旦Bootloader启动完成,就会直接启动用户正常使用的那个系统,而不会进入到Recovery模式,或者停留在Bootloader中,也就是停留在Fastboot模式中。只有通过特定的命令,例如adb reboot recoveryadb reboot bootloader,或者特定的按键,例如在设备启动过程中同时按住音量减小键和电源开关键,才能让设备进入到Recovery模式或者Fastboot模式中。

一个完整的刷Rom过程有两个步骤

进入FastBoot模式,输入recovery.img镜像 进入Recovery模式,刷入包含system.img和boot.img镜像的zip包 注意:system.img和boot.img在Fastboot模式下也可以刷入,只不过Recovery模式更友好一些,这里需要提到一个Bootloader锁的概念,在锁定Bootloader的情况下,无法刷入非官方的recovery.img,system.img,boot.img镜像。这是跟厂商的Bootloader有相关的。可以通过一定的算法(例如签名)来验证要刷入的镜像是否是官方发布的。在这种情况下必须对Booloader解锁,才可以刷入非官方的镜像。

所谓定制自己的系统,就是自己制作recovery.img和system.img,boot.img。 从aosp源码中编译出能在自己使用的手机上运行的系统,并非易事,好在有很多基于aosp第三方开源项目,最著名的就是CyanogenMod,简称CM,MIUI,锤子 ,一加 ,都是基于CM开发的。

以上就是刷机概念和过程,至于原理。

打好源码底子再来补充

fastboot 解锁

开发者选项中的oem unlocking打开

adb reboot bootloader
fastboot flashing unlock

按音量上键

adb fastboot reboot
adb disable-verity
adb reboot
adb root
adb remount

替换boot.img

A: 先将整个版本烧写到手机,烧写完后启动手机进入开发者模式查看OEM是否已解锁(必须解锁,不然替换boot.img会失败) B:烧写boot.img

  1. 将boot.img放到电脑上(比如D盘),启动DOS终端,进入D盘(要和boot.img同目录)
  2. 手机连接电脑,在DOS端输入:adb reboot bootloader 进入fastboot模式
  3. 等待手机进入fastboot模式后输入:fastboot flash boot boot.img
  4. 等待烧写完成后输入fastboot reboot重启手机

fastboot刷机

先执行: adb reboot-bootloader 进入 fastboot模式

fastboot flash system system. img
fastboot flash dtbo dtbo.img
fastboot flash vendor vendor.i
fastboot flash userdata userdata.img
fastboot flash boot boot.img
fastboot reboot
fastboot flash system system.img && fastboot flash vendor 8. vendor.img && fastboot flash userdata userdata.img && fastboot flash boot boot.img && fastboot reboot
data_collect: update data collect app source
this updatedata collect app and add faceDataCollect upload app source code
fastboot flash system system.img && fastboot reboot

编译模块

./mk_android.sh -t userdebug -i bootimage -j 32
./mk_android.sh -t userdebug -i dtboimage -j 32

开机流程

android开机启动流程

手机开机后,引导芯片启动,引导芯片开始从固化再rom里的预设代码执行,加载引导程序到ram,bootloader检查ram,初始化硬件参数等功能。 硬件参数初始化完成后,进入到kernel层,kernel层主要加载一些硬件设备驱动,初始化进程管理等操作,再kernerl中首先启动swapper进程(pid=0),用于初始化进程管理,内存管理,加载Driver等操作,再启动kthread进程(pid=2),这些linux系统的内核进程,kthread是所有内核进程的鼻祖。 Kernel加载完毕后,硬件设备驱动与hal层交互,初始化进程管理等操作会启动init进程,这些在native中 init进程pid=1,init是所有进程的吧izhu,第一个启动,启动后,会启动adbd,logd等用户守护进程,并且会启动servicemanager(binder服务管家)等重要服务,同时孵化出zygote进程,c++ framework, zygote进程是有init进程解析init.rc文件后for生成,他会加载虚拟机,启动system server,(zygote 孵化的第一个进程)System server负责启动和管理整个java framework,包含activitymanager,windowmanager,packagemanager,powermanager等服务 zygote同时会启动app进程,启动的第一个进程是launcher,然后启动email,sms等进程,所有的app都是zygote fork生成。 概述:Loader > Kernel > Native > Framework > Application 细分:BootRom > Bootloader > Kernel > Init > Zygote > SystemServer > Launcher

转自: https://blog.csdn.net/xyyjxa/article/details/77568625

笔者近期做了关于联想新出的一款pad (TAB 4 8 plus)代号tb8704f 的CM 系统的适配和移植工作。其中走了不少弯路,也学习了不少知识,有时候弯路也是一种成长,看到了不一样的风景。 废话不多说,直接进入主题。分为以下几个部分讲解: 1、fastboot 解锁; 2、前期准备工作; 3、源码编译; 4、recovery 适配; 5、zip 包升级; 6、bug 解决;

fastboot 解锁

拿到机器后,第一件事,查找资料解锁bootloader,机器型号不同解锁方式不同。目前三星的机器都可以解锁,华为部分机器可能要付费,联想有些不能解锁。 不能解锁的机器,如果是高通的cpu可以尝试用高通的刷机工具进行刷机。

前期准备

如果能够拿到官方刷机包,包括boot.img、recovery.img、system.img等,那么你已经成功了走了第一步。img 文件的解包就不赘述了,资料很多。 从boot.img中提取 kernel(dt.img)、rc 文件、系统分区表fstab等;recovery.img 同boot.img;从system.img 中提取hardware 层的so包,驱动ko包,系统配置文件etc等。 如果拿不到官方包,那只能走hard 模式了,首先看看能否通过adb 提取一些我们需要的资源文件,比如,hardware 层的so包,驱动ko包,系统配置文件etc,系统分区表等; 如果不行的话,只能刷了recovery 之后通过recovery 进入system分区提取。 有了这些之后,就可以进行源码的组织编译了。

源码编译

下载到Android源码(aosp 或者 CM)之后,在device 和 vendor 目录下建立自己适配机器的目录。 在device/lenovo/tb8704f/ 目录下文件包含以下文件,我们这里可以参考cm 官方编译的产品目录自己组织。

├── Android.mk 
├── audio 
├── bluetooth 
├── BoardConfig.mk 
├── configs 
├── data-ipa-cfg-mgr 
├── device.mk 
├── extract-files.sh 
├── full_tb8704f.mk 
├── gps 
├── include 
├── init 
├── kernel 
├── kernel-headers 
├── keylayout 
├── lineage.dependencies 
├── lineage.mk 
├── overlay 
├── proprietary-files.txt 
├── README.md 
├── rootdir 
├── sepolicy 
├── setup-makefiles.sh 
├── system.prop 
├── system.prop.bak 
├── tftp.mk 
└── wifi

其中BoardConfig.mk 至为重要,直接关系移植成败。以下为这款设备组织的BoardConfig.mk内容: 文件中设定了cpu、gpu的架构、系统位数、分区信息、kernel启动参数和其它一些系统硬件配置和编译参数。

在vendor 目录下组织结构,在vendor/lenovo/tb8704f目录下建立:


├── Android.mk 
├── BoardConfigVendor.mk 
├── proprietary 
│ ├── app 
│ ├── bin 
│ ├── etc 
│ ├── framework 
│ ├── lib 
│ ├── lib64 
│ ├── media 
│ ├── priv-app 
│ └── vendor 
└── tb8704f-vendor.mk 

proprietary 目录下为对应system分区下的各个模块,我们要在这里面放入我们无法编写的so、bin文件或者配置文件等 这些文件即为前期准备的那些文件

recovery 适配

组织好device 和 vendor 目录后,编译recovery.img 通过fastboot 或者官方工具刷入,调试recovery,其中关键点在于kernel 和init.rc、分区表文件的正确性。一般这几个文件正确都能够正确启动。recovery 为我们后面刷入zip 升级包提供入口,也为我们恢复出厂和 跟新升级提供入口。

zip 包升级

通过再recovery 中adb sideload 进行升级。原本加密的设备分区要先进行格式化

bug 解决

bug 解决为分两个部分:1. 开机画面之前的bug 2. 进入开机画面之后的bug

  • 如果设备刷入boot.img 之后无法进入开机画面,第一步要确保adb 能够启动,至于如何让adb 正确启动,一般和权限相关,不在这里详述。 无法进行开机画面一般为surfacefinger错误,检查gralloc composer 和 gpu 相关;
  • 进入开机画面之后,恭喜你,已经完成一大步。后面多为权限问题和配置文件问题,对应log 一步步解决即可。

以上粗略讲解了一下如何移植Android 系统,详细介绍可以写一本小册子了,具体问题大家可以遇到之后一起讨论

android 系统结构

  1. 设备在硬件层之上是 bootloader 层,一般使用 uboot.bin,当 uboot.bin 初始化硬件后,不去启动 OS,停留在当前状态,称之为 fastboot 模式。
  2. 在bootloader 层上面是 recovery 。在 bootloader 运行的时候,可以使用 fastboot 或者官方烧录工具,烧录 recovery。recovery 包含kernel 和 rootfs.
  3. 在 recovery 运行时,可以使用 sd卡等工具,刷入 update 镜像,包含 boot.img 和 system.img。 boot.img 里面包含 kernel 和 rootfs; system.img 里面包含 android 系统和 APP。
  4. 正常 uboot 启动系统后,会直接去 boot.img 和 system.img,跳过 recovery。只用使用 音量减小和电源键的组合 或者 adb reboot recoveryadb reboot bootloader 才能进入 recovery 或者 fastboot 模式。
  5. bootloader 锁,其实就是 uboot 中设定了算法校验,不符合,就烧录不了 recovery 和 用户系统。
  6. 当然,在 fastboot 模式下,也可以直接烧录 boot.img 和 system.img,而不需要通过 recovery 模式,但是 fastboot 模式没有 recovery 模式友好。

adb命令,首先要把 adb 命令目录添加到环境变量中去。然后才能执行相应的命令

  • 安装软件 adb install xxx.apk
  • 重启安卓 adb reboot
  • 进入 recovery adb reboot recovery
  • 进入 bootloader adb reboot bootloader

如果找不到 adb 设备,那么可以参考: https://blog.csdn.net/LinSeeker85/article/details/83510393

参考

https://blog.csdn.net/luoshengyang/article/details/29688041
https://blog.csdn.net/gangjindianzi/article/details/100554482?utm_medium=distribute.pc_relevant.none-task-blog-2~default~BlogCommendFromMachineLearnPai2~default-1.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2~default~BlogCommendFromMachineLearnPai2~default-1.control
https://zhuanlan.zhihu.com/p/25041097
https://blog.csdn.net/xyyjxa/article/details/77568625
https://www.cnblogs.com/helloZQP/p/4191290.html

使用 android studio 编译 7.0.1 上面运行的 app 时,build.gradle 里面设置为 25:

android {
    compileSdk 25

    defaultConfig {

        targetSdk 25
    }
}

结果报错: resource android:attr/dialogCornerRadius not found

结果搜索,并多次尝试后,发现解决方法也很简单:

  1. file -> settings -> android sdk 安装 android 9.0
  2. file -> project structure -> modules -> properties -> compile sdk version 选择 28。

上面两步操作会再 build.gradle 里面增加 compileSdkVersion 28。 然后重新编译工程就可以了。

参考:

https://www.cnblogs.com/hupo376787/p/10285910.html
https://blog.csdn.net/ygz111111/article/details/104272161
https://blog.csdn.net/weixin_43465451/article/details/83185112

jni 如果直接把源文件从 c 改为 cpp, 那么会报错 base operand of '->' has non-pointer type 'JNIEnv {aka _JNIEnv}'和Method 'GetStringUTFChars' could not be resolved

具体的写法是有区别的。

  • c 调用
const char * file_path = (*env)->GetStringUTFChars(env, path, NULL);

return (*env)->NewStringUTF(env, "Hello from JNI !");//如果是用C语言格式就用这种方式
  • cpp 调用
const char * file_path = env->GetStringUTFChars(path, NULL);

return env->NewStringUTF((char *)"Hello from JNI !");//C++用这种格式

原因是 jni 的头文件定义

  • c

    const char* (*GetStringUTFChars)(JNIEnv*, jstring, jboolean*);
  • cpp
    const char* GetStringUTFChars(jstring string, jboolean* isCopy)
    { return functions->GetStringUTFChars(this, string, isCopy); }

参考

https://blog.csdn.net/hejia729371286/article/details/51356983

已经编译好的 .a 静态库

直接在相应的 Android.mk 里面增加:

LOCAL_SRC_FILES := $(LOCAL_PATH)/lib/libyuv_neon.a

这样就可以了

希望把部分源码编译成静态库,然后再加载

LOCAL_STATIC_LIBRARIES := libtest

这个需要有源码

比如说 libyuv,这个在 external 目录下面有这个库,所以在 framework 下面使用也很简单,只要

LOCAL_STATIC_LIBRARIES := libyuv_static

如果提示找不到,那么直接去提示的目录那边去看看,看看目录名字是什么,就把这边的库名字修改了就可以了。

参考:

https://blog.csdn.net/baidu_31872269/article/details/84554696
https://blog.csdn.net/zhang01/article/details/78760630
https://blog.csdn.net/qq840727854/article/details/54782700
https://blog.csdn.net/sofa120/article/details/83029698
https://blog.csdn.net/kafeidev/article/details/8860278
https://programming.vip/docs/compiling-google-libyuv-so-library.html

有两种方法。

1. 进入容器

docker ps
docker exec -it instance15 sh
logcat

2. 不进入容器

docker ps
adb connect localhost:5987
logcat

3. 也可以把 log 写入文件,再把文件读取出来

docker ps
docker exec -it instance15 sh
logcat >log.txt
exit

adb connect localhost:5987
adb -s localhost:5987 pull log.txt .

4. 还可以这样

docker logs --since 5m 00363a3b96d6

  1. 远程建立仓库
  2. vcs --> import into version control --> create git respository
  3. 选中整个工程(project 页面) vcs --> git -> add
  4. vcs --> git --> remote 配置远程仓库
  5. vcs --> update project --> merge --> ok
  6. vcs --> git --> commit
  7. 在项目目录下打开 git bash,输入 git pull origin master -–allow-unrelated-histories
  8. vcs --> git --> push

参考: https://www.jianshu.com/p/059ed1e01229 https://blog.csdn.net/qq_30389893/article/details/90600250