包含 Linux 内核和最小的根文件系统(加载到 RAM 磁盘)。它装载了系统和其他分区,并启动位于 system 分区上的运行时。
boot header, kernel, ramdisk
Ramdisk 分区-AOSP
system分区
包含在 Android 开源项目 (AOSP) 上提供源代码的系统应用和库。在正常操作期间,此分区被装载为只读分区;其内容仅在 OTA 更新期间更改。
vendor分区
包含在 Android 开源项目 (AOSP) 上未提供源代码的系统应用和库。在正常操作期间,此分区被装载为只读分区;其内容仅在 OTA 更新期间更改。
userdata分区
存储由用户安装的应用所保存的数据等。OTA 更新过程通常不会触及该分区。
cache分区
几个应用使用的临时保留区域(访问此分区需要使用特殊的应用权限),用于存储下载的 OTA 更新软件包。其他程序也可使用该空间,但是此类文件可能会随时消失。
安装某些 OTA 软件包可能会导致此分区被完全擦除。cache 分区还包含 OTA 更新的更新日志。
recovery分区
包含第二个完整的 Linux 系统,其中包括一个内核和特殊的恢复二进制文件(该文件可读取一个软件包并使用其内容来更新其他分区)。
执行恢复操作时使用的微小分区,可在应用 OTA 软件包并重新启动设备时,隐藏某些进程的信息。
OTA更新过程
设备会与 OTA 服务器进行定期确认,获知是否有更新可用,包括更新软件包的 URL 和向用户显示的描述字符串。
将更新下载到 cache 或 userdata 分区,并根据 /system/etc/security/otacerts.zip 中的证书验证加密签名。系统提示用户安装更新。
设备重新启动进入恢复模式,引导 recovery 分区中的内核和系统(而非 boot 分区中的内核)启动。
recovery 分区的二进制文件由 init 启动。它会在 /cache/recovery/command 中寻找将其指向下载软件包的命令行参数。
恢复操作会根据 /res/keys(包含在 recovery 分区中的 RAM 磁盘的一部分)中的公钥来验证软件包的加密签名
从软件包中提取数据,并根据需要使用该数据更新 boot、system 和/或 vendor 分区。system 分区上的某个新文件包含新的 recovery 分区的内容。
设备正常重启。
a. 加载最新更新的 boot 分区,在最新更新的 system 分区中装载并开始执行二进制文件。
b. 作为正常启动的一部分,系统会根据所需内容(预先存储为 /system 中的一个文件)检查 recovery 分区的内容。二者内容不同,所以 recovery 分区会被所需内容重新刷写(在后续引导中,recovery 分区已经包含新内容,因此无需重新刷写)。
系统更新完成!更新日志可以在 /cache/recovery/last_log.# 中找到。
* RecoverySystem contains methods for interacting with the Android
* recovery system (the separate partition that can be used to install
* system updates, wipe user data, etc.)
public
class
RecoverySystem
{
* Reboots the device in order to install the given update
* package.
* Requires the {@link android.Manifest.permission#REBOOT} permission.
* @param context the Context to use
* @param packageFile the update package to install. Must be on
* a partition mountable by recovery. (The set of partitions
* known to recovery may vary from device to device. Generally,
* /cache and /data are safe.)
* @throws IOException if writing the recovery command file
* fails, or if the reboot itself fails.
public
static
void
installPackage
(
Context
context
,
File
packageFile
)
throws
IOException
{
String
filename
=
packageFile
.
getCanonicalPath
();
Log
.
w
(
TAG
,
"!!! REBOOTING TO INSTALL "
+
filename
+
" !!!"
);
String
arg
=
"--update_package="
+
filename
+
"\n--locale="
+
Locale
.
getDefault
().
toString
();
bootCommand
(
context
,
arg
);
* Reboot into the recovery system with the supplied argument.
* @param arg to pass to the recovery utility.
* @throws IOException if something goes wrong.
private
static
void
bootCommand
(
Context
context
,
String
arg
)
throws
IOException
{
RECOVERY_DIR
.
mkdirs
();
// In case we need it
COMMAND_FILE
.
delete
();
// In case it's not writable
LOG_FILE
.
delete
();
FileWriter
command
=
new
FileWriter
(
COMMAND_FILE
);
try
{
command
.
write
(
arg
);
command
.
write
(
"\n"
);
}
finally
{
command
.
close
();
// Having written the command file, go ahead and reboot
PowerManager
pm
=
(
PowerManager
)
context
.
getSystemService
(
Context
.
POWER_SERVICE
);
pm
.
reboot
(
"recovery"
);
throw
new
IOException
(
"Reboot failed (no permissions?)"
);
Recovery模式
adb reboot recovery
POWER + (VOL+)
fastboot 与 recovery 区别, fastboot俗称线刷,需要电脑和数据线刷机,recovery俗称卡刷,通过内部存储刷机
RK3288固件升级
Firefly-RK3288升级固件
差分资源包
make otapackage
用于制作差分升级包: out/target/product/rk3288/obj/PACKAGING/target_files_intermediates/rk3288-target_files-20210603.114202.zip
rk3288-target_files-20210603.114202$ tree -L 2
├── BOOT
│ ├── cmdline
│ ├── kernel
│ ├── RAMDISK
│ └── resource.img
├── DATA
│ ├── benchmarktest
│ ├── DATA
│ └── nativetest
├── IMAGES
│ ├── boot.img
│ ├── recovery.img
│ ├── recovery-two-step.img
│ ├── system.img
│ └── system.map
├── META
│ ├── apkcerts.txt
│ ├── boot_filesystem_config.txt
│ ├── file_contexts.bin
│ ├── filesystem_config.txt
│ ├── misc_info.txt
│ ├── otakeys.txt
│ ├── recovery_filesystem_config.txt
│ ├── releasetools.py
│ └── vendor_filesystem_config.txt
├── OTA
│ ├── android-info.txt
│ └── bin
├── RECOVERY
│ ├── cmdline
│ ├── kernel
│ ├── RAMDISK
│ └── resource.img
├── SYSTEM
│ ├── app
│ ├── bin
│ ├── build.prop
│ ├── etc
│ ├── fake-libs
│ ├── fonts
│ ├── framework
│ ├── lib
│ ├── lib64
│ ├── manifest.xml
│ ├── media
│ ├── priv-app
│ ├── recovery-from-boot.p
│ ├── tts
│ ├── usr
│ ├── vendor -> /vendor
│ └── xbin
├── trust.img
├── uboot.img
├── vendor0.img
└── vendor1.img
26 directories, 29 files
OTA全量升级包
./mkimage.sh ota
out/target/product/rk3288/rk3288-ota-20210603.114202.zip
rk3288-ota-20210603.114202$ tree
├── boot.img
├── file_contexts.bin
├── META-INF
│ ├── CERT.RSA
│ ├── CERT.SF
│ ├── com
│ │ ├── android
│ │ │ ├── metadata
│ │ │ └── otacert
│ │ └── google
│ │ └── android
│ │ ├── update-binary
│ │ └── updater-script
│ └── MANIFEST.MF
├── system.new.dat
├── system.patch.dat
├── system.transfer.list
├── trust.img
├── uboot.img
├── vendor0.img
└── vendor1.img
5 directories, 16 files
差分升级包
./build/tools/releasetools/ota_from_target_files
-v -i rk3188-target_files-v1.zip
-p out/host/linux-x86
-k build/target/product/security/testkey
rk3188-target_files-v2.zip out/target/product/rk3188/rk3188-v1-v2.zip
./build/tools/releasetools/ota_from_target_files -h
Given a target-files zipfile, produces an OTA package that installs
that build. An incremental OTA is produced if -i is given, otherwise
a full OTA is produced.
Usage: ota_from_target_files [flags] input_target_files output_ota_package
-k (--package_key) <key> Key to use to sign the package (default is
the value of default_system_dev_certificate from the input
target-files's META/misc_info.txt, or
"build/target/product/security/testkey" if that value is not
specified).
For incremental OTAs, the default value is based on the source
target-file, not the target build.
-i (--incremental_from) <file>
Generate an incremental OTA using the given target-files zip as
the starting build.
-v (--verify)
Remount and verify the checksums of the files written to the
system and vendor (if used) partitions. Incremental builds only.
-w (--wipe_user_data)
Generate an OTA package that will wipe the user data partition
when installed.
-p (--path) <dir>
Prepend <dir>/bin to the list of places to search for binaries
run by this script, and expect to find jars in <dir>/framework.
-v (--verbose)
Show command lines being executed.
-h (--help)
Display this usage message and exit.