Android

Android

Basics

root

基本步骤:

  1. 解锁 frp lock 和 bootloader lock。其中 bl lock 解锁通常需要通过厂商网站获取解锁码,某些不提供解锁码的手机可以找淘宝。
  2. fastboot 下刷入 TWRP recovery。
  3. TWRP 下刷入 magisk

刷第三方固件

  1. 确保已解锁 frp lock 和 bl lock 并刷入 TWRP。
  2. TWRP 下 factory reset 然后刷入固件。

注意:

  • 建议刷第三方固件之前用 TWRP 备份 /boot 和 /system 等分区。
  • 如果之前刷过 magisk,magisk会把设备原厂固件的原版 boot.img 备份到 /data 目录下,建议备份。

fastboot (bootloader)

最基本的出厂 bootloader,除个别区块(如 bl 锁)外无法修改。

进入方法:

  1. (某些手机按键组合与此不同)关机状态下:同时按住VolDown(音量减) + Power键开机;或按住 VolDown 键同时usb连接PC。
  2. 在 Android 系统运行时连接 usb adb, 执行 adb reboot bootloader
  3. Android 系统 root 后可以安装 App 在 Power 键菜单里添加“重启到bootloader / fastboot”选项。
  4. TWRP 等 Recovery 里可以选择重启到 bootloader。

刷机

fastboot 是终极的救砖方法。

只有在 fastboot 里的状态同时显示为 "frp unlock" 和 "phone unlock" 才可以刷机,这两项任何一个是 locked 时都无法刷机。

fastboot flash boot boot.img

清除数据 (格式化)

fastboot erase userdata
fastboot erase cache

phone lock && frp lock

phone lock: 即 bootloader 锁(bl锁)。

frp lock (Factory Reset Protection): Android 5.1+ 设备默认启用的设备锁,实现 "find my device" 功能;lock 状态时,如果 factory reset 后会要求输入之前设备登录的 Google 帐号密码,否则就是砖机状态。

注意:即使设备已经解锁 bl 和 frp,如果刷某些官方的固件,在第一次启动后“SetupWizard”初始化界面登录了 Google Account,会自动重新加锁 frp!!。(傻逼 Google)如果在设置向导里跳过登录Google这一步(某些ROM不允许跳过),之后再手动在"设置 - 账户"里登录 Google 账户则不会锁上 frp。

  • frp lock 状态时: 在 fastboot 里不能刷机(fastboot flash boot boot.img);不能 sideload 启动镜像 (fastboot boot boot.img);不能解锁bl (fastboot oem unlock);但如果已经解锁了 bl (phone unlock) 则bl解锁状态会继续保持;如果 bl 已解锁,可以执行命令重新上锁 bl (fastboot oem relock)。
  • frp unlock 状态时:在 fastboot 里可以解锁 / 重新加锁 bl;如果 bl 也是解锁状态,可以刷机、sideload。
  • phone lock 状态: fastboot 里不能刷机。已经刷入的第三方内核和recovery也无法正常启动(因为签名校验不通过,会 bootloop)。
  • phone unlock && frp lock 状态:fastboot 里不能刷机,但已经刷入的自定义内核/recovery可以正常启动。

注意 frp lock 和 phone lock 这两个锁与手机的网络锁(sim lock)无关。后者只能通过运营商提供方式修改基带解锁。

unlock frp

在系统 settings - developer options - enable oem unlocking

请注意,某些手机 / 系统环境下,这个值只有在 bootloader 是加锁状态时才能修改。(出现具体条件不明,反正是Google的傻逼设计),如果 bl 已经解锁但 frp 还是加锁状态,在系统“开发者选项”里 "enable oem unlocking" 会是未选中状态且灰色不可切换,这时唯一的方法时先在 fastboot 里重新加锁 bootloader (会格式化手机),然后再回到系统开发者选项里解锁 frp

补足:如果 bl 已经解锁并且已经刷入了TWRP,但是 frp 是加锁状态,可以尝试用这个工具在 TWRP 下直接解锁 frp。

Unlock bootloader

首先保证 frp 已经解锁,
然后进入 fastboot,fastboot oem unlock [code]

bootloader 解锁和重新加锁操作都会强制 factory reset (low-level) 清空系统 /data 全部数据。

re-lock bootloader

fastboot oem relock

一些手机重新加锁时也需要输入 bootloader 解锁码参数。

一些手机的官方刷机包会自动重新加锁 bootloader (通常是 oem.img 等分区的刷机文件)

请注意:如果已经改动了 boot.img (刷第三方固件、刷第三方内核、安装 Magisk / SuperSU 等 systemless root) / 刷入了第三方 Recovery,重新加锁 bootloader 会导致系统 / Recovery 无法启动彻底变砖!并且没有任何解决方法!(部分设备网上有商家提供收费软件可以在 fastboot 里强刷;部分 高通 soc 设备可以通过 9098 模式强刷)

File System

Partitions and Images

实际分区:

  • /boot : 存放 kernel(以及附带的ramdisk) 的分区。一些ROM刷机包里包含了这个分区的镜像 boot.img。也可以通过 fastboot flash boot boot.img 手动刷入新内核。boot.img 里打包了 kernel, ramdisk 和其他的 second stage 代码。
  • /recovery : recovery 分区。通过 fastboot flash recovery recovery.img 刷入。TWRP 是最常用的 recovery,刷入。启动TWRP的方式通常为:关机状态下,“按住VolUp(音量加) + Power 键”开机或“按住 VolUp”键时连接 PC usb。
  • /system : 系统分区。通常在Android运行时这个分区是挂载为只读的,只有在 OTA升级 / 官方刷机软件刷机时才会修改其中内容。root 后可以挂载为可写分区并在运行时任意修改其中内容。
  • /cache : (旧版 Android)缓存分区。主要用于旧Android设备(出厂Android版本 < 7.0) OTA 升级过程中。出厂版本 Android 7.0+ 设备没有这个分区。
  • /data : 数据(userdata)分区,即手机的内置存储(Internal Storage)物理分区。里面内容包括:
    • /data/app : 用户安装的 App
    • /data/data : 所有 App 的数据。
    • /data/media : 内置存储(Internal Storage),包括设备每个用户的 /sdcard。(详见下文)
    • /data/dalvik-cache : Dalvik / ART Cache。(某些手机里这是一个独立物理分区)

某些手机还可能有一些其他分区:

  • /radio: 基带(baseband) 分区
  • /vendor: 通常和 system 一样,也是仅在系统升级时修改。驱动分区,例如相机驱动、音频驱动等。
  • /misc

虚拟分区 / 挂载点:

  • /storage : 存放 Internal Storage / External Storage (包括SD卡) 等挂载点的 tmpfs.
  • /storage/emulated : 所有用户的 Internal Storage 存放路径。实际指向 /data/media
  • /sdcard : 等效于 Linux 的 ~ 用户根目录。是一个符号链接,实际指向 /data/media/{USER_ID},对于第一个(主)用户,即为 /data/media/0。(注:某些Android <=5.0 以前的设备 /sdcard 和 /data 是两个不同的物理分区,这些旧设备经常会遇到 /sdcard 和 /data 其中一个可用空间不足的问题)

/storage 和 /sdcard 不是实际物理分区。

  • 在 (较新版本)TWRP 里 wipe /data 时不会清除 /data/media,因此不影响 /sdcard 里内容。(所以这个 wipe 工作在文件系统层,而不是直接格式化块设备?);而 “format data”则会格式化整个 /data。TWRP 提供的 "Factory reset" 快捷操作按钮会重置 Dalvik / ART Cache, /cache 和 /data (除/data/media) 这3个分区内容。(Dalvik / ART cache 实际上也位于 /data 分区里)
  • 除一些小分区外,设备闪存划分为 /system 和 /data 两个主要分区。 /system 一般出厂划分1-3GB,剩余的大部分空间都在 /data。
  • /system, /data 等各分区大小是设备出厂时固定的。可以在 recovery 里用 fdisk 等工具重新分区以调整各分区大小,但过程十分复杂、与具体设备相关并且具有危险性(错误操作设备会变砖)。少数情况下,某些 OTA 升级包也会调整分区划分。

/sdcard 是通常 App 可见的所谓“外置存储”(external storage)目录。这里的“外置存储”名字与“内置存储”(internal storage)相对,其名称来源是因为早期Android设备(< Android 4.0)自带flash存储很小(几百MB),所有应用和数据都需要安装在额外插入的sd卡里。

如果手机有 sd 卡槽,那么插入的 sd 卡会被挂载为 /sdcard1。/sdcard 和 /sdcard1 都属于“外置存储”。

“外置存储”对所属用户完全开放访问权限;App 访问“外置存储”需要READ_EXTERNAL_STORAGE或WRITE_EXTERNAL_STORAGE权限。而 /data 里除 /data/media 以外的其他数据,以及 /data/media 里非当前用户的主文件夹都是系统保护的,不root无法访问。

Details (Android 6+)

https://android.stackexchange.com/questions/205430/what-is-storage-emulated-0

# for (Java) Android apps (running inside zygote virtual machine)
# "/storage to VIEW" bind mount is inside a separate mount namespace for every app
/sdcard >S> /storage/self/primary
/storage/self >B> /mnt/user/USER-ID
/mnt/user/USER-ID/primary >S> /storage/emulated/USER-ID
/storage/emulated >B> /mnt/runtime/VIEW/emulated
/mnt/runtime/VIEW/emulated >E> /data/media

# for services/daemons/processes in root/global namespace (VIEW = default)
/sdcard >S> /storage/self/primary
/storage >B> /mnt/runtime/default
/mnt/runtime/default/self/primary >S> /mnt/user/USER-ID/primary
/mnt/user/USER-ID/primary >S> /storage/emulated/USER-ID
/storage/emulated >B> /mnt/runtime/default/emulated
/mnt/runtime/default/emulated >E> /data/media
  • >S> for symlink (The former is a symlink of later), >E> for emulated and >B> for bind mount
  • USER-ID of current user in case of Multiple Users or Work Profile, normally 0 i.e. that of device owner
  • VIEW is one of read (for apps with permission.READ_EXTERNAL_STORAGE) or write (permission.WRITE_EXTERNAL_STORAGE) or default (for processes running in root/global mount namespace i.e. outside zygote)
  • There were minor differences on previous Android versions but the concept of emulation was same ever since implemented.
  • For a little bit more details on Android's mount namespace implementation, see this answer.

In short, /sdcard and /storage/emulated/0 - which represent a FAT/vFAT/FAT32 filesystem - point towards /data/media/0 (or /mnt/expand/[UUID]/media/0 in case of Adoptable Storage) through FUSE or sdcardfs emulation.

Being not Android specific but generally Linux related, symlink and bind mount (see "Creating a bind mount") are out of the scope of this question, as the question is about emulation part mainly.

Systemless

不写入 /system 分区而对系统进行修改。最常用的是 Magisk:

  • patch 并替换 boot.img 分区实现 root。(对 ramdisk 打 patch;某些三星手机也 patch 了 kernel 以禁用某些安全特性)
  • Systemless modules: 文件存放于Magisk Manager app数据空间,通过虚拟文件系统实现“模拟”覆盖 /system 分区。

Encrption

Android 5.0+ 支持全盘加密(FDE, full-disk encryption)。
Android 7.0+ 新增支持文件级别加密(FBE, file-based encryption)

加密使用用户锁屏密码保护密钥(如果设置了锁屏密码的话)。

  • FDE: Android 5.0+ 支持。加密在块设备级别。安全性高。缺点是每次开机必须输入锁屏密码解密 /data,否则系统大部分功能不工作(闹钟不工作、无法接听电话、辅助服务不工作、无法使用安装的第三方输入法等等)
  • FBE: Android 7.0+ 支持。加密在文件级别。不同文件可以使用不同加密密钥。支持 Direct Boot (系统部分功能开机后无需解锁即立即可用);缺点是:对于 Android 7.0-8.1, FBE 后无法与 Adoptable Storage(将sd卡转为"内置存储"使用)并存;Android 9.0 解决了这个问题。

检测设备存储加密状态:

UI:

Go into your "Settings"-App. In "Security", if it offers you to encrypt your device it is unencrypted. If it says something like "Device is encrypted" it indeed is encrypted.

ADB:

adb shell getprop ro.crypto.state
# output "encrypted" or "uncrypted"

adb shell getprop ro.crypto.type
# output "block" or "file" for encrypted phone

SD Card (external storage)

Android < 6.0 只能将(硬件卡槽) sd 卡作为纯用户文件数据存储区,无法用于存储 app 以及 app 数据。

Android 6.0+ 支持开启 Adoptable Storage,能把 sd 卡当内置存储一样用。

注意: Android 7.0-8.1 的 FBE 与 Adoptable Storage 不兼容。(参考上文)

部分设备会在插入首次某张sd卡时询问是否对这张sd卡开启 Adoptable Storage。而某些其他设备不会提示,默认直接将sd卡当作传统“外置存储”方式使用,但可以通过“设置 - 存储”页面开启。也可以通过 adb 启用(无需 root)

开启 Adoptable Storage 会格式化并加密对应 sd 卡,此 sd 卡之后只能在本设备上使用。

开启 Adoptable Storage 时, Android 询问用户是否把 sd 卡挂载为 /sdcard (primary shared storage contents) 使用,如果选择是,会把原先的 /sdcard (设备flash存储里) 里内容迁移过去。

App 必须显式声明支持"Adoptable Storage"才能被安装在 AS sd卡里。

Tips & Solutions

"分身"、"双开"

  • 使用 Android 4.4+ 自带的多用户功能。缺点是切换用户比较麻烦。
  • 使用 Android 5.0+ 的 work profile (Android for work) 功能实现“手机分身”功能: IslandShelter等。可以一键冻结整个工作空间,非常好用。

Last update: 2019-08-29 09:20:18 UTC