Boot Image、Ramdisk 与 GKI 详解

Boot Image、Ramdisk 与 GKI 详解

深入理解 Android 启动镜像的结构、ramdisk 的作用以及 GKI (Generic Kernel Image) 架构,这些知识是理解 Root 方案(如 Magisk、KernelSU)工作原理的基础。


1. Android 启动流程概述

1.1 启动阶段

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
┌─────────────────────────────────────────────────────────────────────────────┐
│                        Android 启动流程                                      │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                              │
│   ┌──────────┐    ┌──────────┐    ┌──────────┐    ┌──────────┐            │
│   │   ROM    │    │  Boot-   │    │  Kernel  │    │   Init   │            │
│   │  (固件)  │───►│  loader  │───►│  启动    │───►│  进程    │            │
│   └──────────┘    └──────────┘    └──────────┘    └──────────┘            │
│        │              │               │               │                    │
│        │              │               │               │                    │
│        ▼              ▼               ▼               ▼                    │
│   ┌──────────┐    ┌──────────┐    ┌──────────┐    ┌──────────┐            │
│   │ 硬件初始 │    │ 加载     │    │ 挂载     │    │ 启动     │            │
│   │ 化       │    │ boot.img │    │ ramdisk  │    │ Zygote   │            │
│   └──────────┘    └──────────┘    └──────────┘    └──────────┘            │
│                                                         │                  │
│                                                         ▼                  │
│                                                    ┌──────────┐            │
│                                                    │ System   │            │
│                                                    │ Server   │            │
│                                                    └──────────┘            │
│                                                         │                  │
│                                                         ▼                  │
│                                                    ┌──────────┐            │
│                                                    │  Launcher│            │
│                                                    │  (桌面)  │            │
│                                                    └──────────┘            │
│                                                                              │
└─────────────────────────────────────────────────────────────────────────────┘

1.2 各阶段说明

阶段说明关键文件
BootROM固化在芯片中的代码,初始化硬件-
Bootloader引导加载程序,加载内核aboot, ABL
KernelLinux 内核启动zImage, Image
Ramdisk临时根文件系统ramdisk.cpio
Init第一个用户空间进程/init
ZygoteAndroid 进程孵化器app_process

2. Boot Image 结构

2.1 Boot Image 组成

Boot Image (boot.img) 是 Android 设备启动的核心镜像:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
┌─────────────────────────────────────────────────────────────────────────────┐
│                          boot.img 结构                                       │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                              │
│   偏移量        大小          内容                                           │
│   ─────────────────────────────────────────────────────────────────────     │
│   0x0000       2KB           Boot Header (启动头)                           │
│                              - magic: "ANDROID!"                            │
│                              - kernel_size                                  │
│                              - ramdisk_size                                 │
│                              - cmdline                                      │
│                              - ...                                          │
│   ─────────────────────────────────────────────────────────────────────     │
│   对齐后       kernel_size   Kernel (内核镜像)                              │
│                              - 压缩的 Linux 内核                            │
│                              - 通常为 gzip 压缩                             │
│   ─────────────────────────────────────────────────────────────────────     │
│   对齐后       ramdisk_size  Ramdisk (初始内存盘)                           │
│                              - CPIO 格式的文件系统                          │
│                              - gzip 压缩                                    │
│   ─────────────────────────────────────────────────────────────────────     │
│   对齐后       second_size   Second Stage (可选)                            │
│                              - 第二阶段引导程序                             │
│   ─────────────────────────────────────────────────────────────────────     │
│   对齐后       dtb_size      DTB (设备树, v2+)                              │
│                              - Device Tree Blob                             │
│                                                                              │
└─────────────────────────────────────────────────────────────────────────────┘

2.2 Boot Header 版本

Android 不同版本使用不同的 boot header 格式:

版本Android 版本特点
v0-v2Android 9 及更早传统格式
v3Android 11引入 vendor_boot
v4Android 12+支持 vendor_ramdisk

2.3 Boot Header v3/v4 结构

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
// Android 12+ boot header v4
struct boot_img_hdr_v4 {
    uint8_t magic[BOOT_MAGIC_SIZE];      // "ANDROID!"
    uint32_t kernel_size;                 // 内核大小
    uint32_t ramdisk_size;               // ramdisk 大小
    uint32_t os_version;                 // 系统版本
    uint32_t header_size;                // header 大小
    uint32_t reserved[4];                // 保留字段
    uint32_t header_version;             // header 版本 (4)
    uint8_t cmdline[BOOT_ARGS_SIZE];     // 内核命令行
    uint32_t signature_size;             // 签名大小 (v4 新增)
};

3. Ramdisk 详解

3.1 什么是 Ramdisk

Ramdisk 是一个临时的内存文件系统,在内核启动早期加载到内存中:

  • 格式: CPIO 归档,通常使用 gzip 压缩
  • 作用: 提供启动初期所需的文件和程序
  • 生命周期: 系统启动后可能被卸载或保留

3.2 Ramdisk 内容

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
ramdisk/
├── init                          # 第一个用户空间进程
├── init.rc                       # init 配置脚本
├── init.*.rc                     # 设备特定配置
├── default.prop                  # 默认属性
├── fstab.*                       # 文件系统挂载表
├── ueventd.rc                    # 设备节点配置
├── sbin/                         # 系统二进制文件
│   ├── adbd                      # ADB 守护进程
│   └── ...
├── system/                       # 指向 /system 的挂载点
├── vendor/                       # 指向 /vendor 的挂载点
├── dev/                          # 设备文件
├── proc/                         # 进程文件系统
└── sys/                          # sysfs 文件系统

3.3 First Stage Init vs Second Stage Init

Android 使用两阶段 init:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
┌─────────────────────────────────────────────────────────────────────────────┐
│                         Init 两阶段启动                                      │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                              │
│   ┌───────────────────────────────────────────────────────────────────┐    │
│   │                    First Stage Init                                │    │
│   │                                                                    │    │
│   │   来源: boot.img 中的 ramdisk                                      │    │
│   │   任务:                                                            │    │
│   │     1. 设置基本环境 (/dev, /proc, /sys)                           │    │
│   │     2. 加载 SELinux 策略                                          │    │
│   │     3. 挂载 /system, /vendor 等分区                               │    │
│   │     4. 切换到 Second Stage Init                                   │    │
│   │                                                                    │    │
│   └────────────────────────────┬──────────────────────────────────────┘    │
│                                │                                            │
│                                ▼                                            │
│   ┌───────────────────────────────────────────────────────────────────┐    │
│   │                   Second Stage Init                                │    │
│   │                                                                    │    │
│   │   来源: /system/bin/init                                           │    │
│   │   任务:                                                            │    │
│   │     1. 解析 init.rc 脚本                                          │    │
│   │     2. 启动各类服务 (servicemanager, surfaceflinger...)           │    │
│   │     3. 启动 Zygote                                                │    │
│   │     4. 属性服务                                                   │    │
│   │                                                                    │    │
│   └───────────────────────────────────────────────────────────────────┘    │
│                                                                              │
└─────────────────────────────────────────────────────────────────────────────┘

3.4 不同类型的 Ramdisk

Android 11+ 引入了多种 ramdisk:

类型位置内容用途
Generic Ramdiskboot.img通用 init 文件First stage init
Vendor Ramdiskvendor_boot.img厂商特定文件硬件初始化
Recovery Ramdiskrecovery.imgRecovery 环境系统恢复

4. GKI (Generic Kernel Image)

4.1 GKI 概述

GKI 是 Google 在 Android 11 引入的通用内核镜像架构:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
┌─────────────────────────────────────────────────────────────────────────────┐
│                      传统架构 vs GKI 架构                                    │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                              │
│   传统架构 (Android 10 及更早)                                               │
│   ─────────────────────────────────────────                                 │
│                                                                              │
│   ┌─────────────────────────────────────────────────────────────────────┐  │
│   │                     boot.img (设备特定)                              │  │
│   │  ┌──────────────────┐  ┌──────────────────┐  ┌──────────────────┐  │  │
│   │  │    Kernel        │  │    Ramdisk       │  │      DTB         │  │  │
│   │  │  (设备特定)      │  │   (设备特定)     │  │   (设备特定)     │  │  │
│   │  │                  │  │                  │  │                  │  │  │
│   │  │  - 厂商驱动      │  │  - init          │  │  - 设备树       │  │  │
│   │  │  - 定制修改      │  │  - 配置文件      │  │                  │  │  │
│   │  └──────────────────┘  └──────────────────┘  └──────────────────┘  │  │
│   └─────────────────────────────────────────────────────────────────────┘  │
│                                                                              │
│                                                                              │
│   GKI 架构 (Android 11+)                                                    │
│   ─────────────────────────────────────────                                 │
│                                                                              │
│   ┌──────────────────────────────────┐  ┌──────────────────────────────┐  │
│   │        boot.img (通用)           │  │     vendor_boot.img          │  │
│   │  ┌──────────────────────────┐   │  │  ┌──────────────────────┐   │  │
│   │  │    GKI Kernel            │   │  │  │  Vendor Ramdisk      │   │  │
│   │  │    (Google 提供)         │   │  │  │  (厂商提供)          │   │  │
│   │  │                          │   │  │  │                      │   │  │
│   │  │  - 标准化接口            │   │  │  │  - 硬件初始化        │   │  │
│   │  │  - 稳定 ABI              │   │  │  │  - 厂商配置          │   │  │
│   │  └──────────────────────────┘   │  │  └──────────────────────┘   │  │
│   │  ┌──────────────────────────┐   │  │  ┌──────────────────────┐   │  │
│   │  │    Generic Ramdisk       │   │  │  │        DTB           │   │  │
│   │  │    (Google 提供)         │   │  │  │   (厂商提供)         │   │  │
│   │  └──────────────────────────┘   │  │  └──────────────────────┘   │  │
│   └──────────────────────────────────┘  └──────────────────────────────┘  │
│                                                                              │
│   ┌──────────────────────────────────────────────────────────────────────┐ │
│   │                       vendor_dlkm (动态加载内核模块)                  │ │
│   │    厂商驱动以 LKM 形式加载,不修改 GKI 内核                          │ │
│   └──────────────────────────────────────────────────────────────────────┘ │
│                                                                              │
└─────────────────────────────────────────────────────────────────────────────┘

4.2 GKI 版本

GKI 版本Android 版本内核版本特点
GKI 1.0Android 115.4初始版本
GKI 2.0Android 125.10完整模块化
GKI 2.0Android 135.15增强稳定性
GKI 2.0Android 146.1最新内核支持

4.3 GKI 的优势

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
┌─────────────────────────────────────────────────────────────────────────────┐
│                           GKI 优势                                           │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                              │
│   1. 更快的安全更新                                                          │
│      - Google 可以直接推送内核安全补丁                                       │
│      - 无需等待厂商适配                                                      │
│                                                                              │
│   2. 标准化接口 (KMI - Kernel Module Interface)                             │
│      - 厂商驱动与内核解耦                                                    │
│      - 驱动以模块形式加载                                                    │
│                                                                              │
│   3. 更小的 boot.img                                                        │
│      - 厂商特定内容移至 vendor_boot                                          │
│      - 便于 OTA 更新                                                        │
│                                                                              │
│   4. 利于 Root 方案                                                         │
│      - KernelSU 可以作为 LKM 加载                                           │
│      - 无需编译完整内核                                                      │
│                                                                              │
└─────────────────────────────────────────────────────────────────────────────┘

4.4 检查设备是否使用 GKI

1
2
3
4
5
6
7
8
9
# 检查内核版本
adb shell uname -r
# GKI 内核通常显示: 5.10.x-android13-x-xxxxx

# 检查是否存在 vendor_boot 分区
adb shell ls -la /dev/block/by-name/ | grep vendor_boot

# 检查内核配置
adb shell zcat /proc/config.gz | grep CONFIG_GKI

5. 分区与镜像类型

5.1 启动相关分区

分区用途备注
boot内核 + 通用 ramdisk必需
vendor_boot厂商 ramdisk + DTBGKI 设备
init_boot通用 ramdiskAndroid 13+
recoveryRecovery 环境部分设备
dtbo设备树覆盖独立分区

5.2 Android 13+ 分区变化

1
2
3
4
5
6
Android 12:
boot.img = kernel + generic_ramdisk

Android 13+:
boot.img = kernel only
init_boot.img = generic_ramdisk

5.3 A/B 分区

现代 Android 设备使用 A/B 分区方案:

1
2
3
4
boot_a    boot_b
vendor_boot_a    vendor_boot_b
system_a    system_b
...

查看当前槽位:

1
2
adb shell getprop ro.boot.slot_suffix
# 输出: _a 或 _b

6. Root 方案与启动镜像

6.1 Magisk 修改方式

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
┌─────────────────────────────────────────────────────────────────────────────┐
│                        Magisk 修改 Boot Image                                │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                              │
│   原始 boot.img                    修改后 boot.img                          │
│   ─────────────────               ─────────────────                         │
│                                                                              │
│   ┌─────────────────┐             ┌─────────────────┐                       │
│   │    Kernel       │             │    Kernel       │  (保持不变)           │
│   └─────────────────┘             └─────────────────┘                       │
│   ┌─────────────────┐             ┌─────────────────┐                       │
│   │    Ramdisk      │    ───►     │ Magisk Ramdisk  │                       │
│   │                 │             │                 │                       │
│   │  - init         │             │  - magiskinit   │  ← 替换 init          │
│   │  - init.rc      │             │  - init.rc      │                       │
│   │  - ...          │             │  - overlay.d/   │  ← Magisk 覆盖        │
│   │                 │             │  - ...          │                       │
│   └─────────────────┘             └─────────────────┘                       │
│                                                                              │
│   Magisk 注入流程:                                                          │
│   1. magiskinit 作为 init 启动                                              │
│   2. 执行 Magisk 初始化                                                     │
│   3. 挂载 Magisk 文件系统                                                   │
│   4. 启动 magiskd 守护进程                                                  │
│   5. 调用原始 init 继续启动                                                 │
│                                                                              │
└─────────────────────────────────────────────────────────────────────────────┘

6.2 KernelSU 修改方式

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
┌─────────────────────────────────────────────────────────────────────────────┐
│                       KernelSU 修改 Boot Image                               │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                              │
│   方式一: 修改内核 (编译时集成)                                              │
│   ─────────────────────────────────                                         │
│                                                                              │
│   ┌─────────────────┐             ┌─────────────────┐                       │
│   │  原始 Kernel    │    ───►     │ KernelSU Kernel │  ← 编译时集成         │
│   └─────────────────┘             └─────────────────┘                       │
│   ┌─────────────────┐             ┌─────────────────┐                       │
│   │    Ramdisk      │             │    Ramdisk      │  (保持不变)           │
│   └─────────────────┘             └─────────────────┘                       │
│                                                                              │
│                                                                              │
│   方式二: LKM 加载 (GKI 设备)                                               │
│   ─────────────────────────────────                                         │
│                                                                              │
│   ┌─────────────────┐             ┌─────────────────┐                       │
│   │  GKI Kernel     │             │  GKI Kernel     │  (保持不变)           │
│   └─────────────────┘             └─────────────────┘                       │
│   ┌─────────────────┐             ┌─────────────────┐                       │
│   │    Ramdisk      │    ───►     │    Ramdisk      │                       │
│   │                 │             │  + kernelsu.ko  │  ← 添加内核模块       │
│   │                 │             │  + 加载脚本     │                       │
│   └─────────────────┘             └─────────────────┘                       │
│                                                                              │
│   启动时加载 kernelsu.ko 模块,无需修改内核本身                             │
│                                                                              │
└─────────────────────────────────────────────────────────────────────────────┘

7. 实用工具与操作

7.1 提取 Boot Image

1
2
3
4
5
6
7
8
# 方法一: 从设备提取
adb shell su -c "dd if=/dev/block/by-name/boot of=/sdcard/boot.img"
adb pull /sdcard/boot.img

# 方法二: 从 OTA 包提取
unzip ota.zip boot.img
# 或使用 payload-dumper
python payload_dumper.py payload.bin --out ./extracted/

7.2 解包 Boot Image

使用 magiskboot (推荐):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 解包
./magiskboot unpack boot.img

# 生成的文件:
# - kernel          内核
# - ramdisk.cpio    ramdisk (压缩的)
# - dtb             设备树 (如果有)

# 解包 ramdisk
./magiskboot cpio ramdisk.cpio extract

使用 AIK (Android Image Kitchen):

1
2
./unpackimg.sh boot.img
# 输出到 split_img/ 和 ramdisk/

使用 mkbootimg 工具链:

1
2
3
4
5
# 解包
unpack_bootimg --boot_img boot.img --out boot_unpacked/

# 查看 boot.img 信息
unpack_bootimg --boot_img boot.img --format mkbootimg

7.3 打包 Boot Image

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# 使用 magiskboot
./magiskboot repack boot.img new_boot.img

# 使用 mkbootimg
mkbootimg \
    --kernel kernel \
    --ramdisk ramdisk.cpio.gz \
    --cmdline "..." \
    --os_version 13.0.0 \
    --os_patch_level 2024-01 \
    --header_version 4 \
    -o new_boot.img

7.4 刷入 Boot Image

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 进入 fastboot 模式
adb reboot bootloader

# 刷入 boot 分区
fastboot flash boot new_boot.img

# 对于 A/B 设备,可能需要指定槽位
fastboot flash boot_a new_boot.img

# 重启
fastboot reboot

7.5 修改 Ramdisk

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 1. 解包 ramdisk
mkdir ramdisk_dir
cd ramdisk_dir
gzip -dc ../ramdisk.cpio.gz | cpio -idmv

# 2. 修改文件
# 例如修改 init.rc, default.prop 等

# 3. 重新打包
find . | cpio -o -H newc | gzip > ../ramdisk.cpio.gz

7.6 验证 Boot Image

1
2
3
4
5
# 使用 avbtool 验证签名 (如果使用 AVB)
avbtool verify_image --image boot.img

# 查看 vbmeta 信息
avbtool info_image --image vbmeta.img

相关章节


相关内容

如果这篇文章对你有帮助,请我喝杯咖啡吧~
+5 支付宝支付宝
+5 微信微信