当前位置: 首页 > news >正文

Android分区刷机原理深度解析:从Bootloader到Framework的完整启动流程

前言

Android系统作为当今最流行的移动操作系统,其底层架构设计精巧而复杂。理解Android的分区结构和启动流程,不仅是进行系统定制、ROM开发的基础,也是深入掌握Android系统原理的必经之路。本文将从硬件层面到系统框架层面,全面剖析Android的分区架构、刷机原理以及完整的启动流程。

一、Android分区架构概述

1.1 分区的本质

在深入讲解各个分区之前,我们需要理解分区的本质。Android设备的存储介质(通常是eMMC或UFS)在逻辑上被划分为多个独立的区域,每个区域存储不同类型的数据。这种划分通过**GPT(GUID Partition Table)或传统的MBR(Master Boot Record)**分区表来管理。

GPT分区表结构:

// GPT Header结构
typedef struct {uint8_t  signature[8];        // "EFI PART"uint32_t revision;uint32_t header_size;uint32_t header_crc32;uint32_t reserved;uint64_t current_lba;uint64_t backup_lba;uint64_t first_usable_lba;uint64_t last_usable_lba;uint8_t  disk_guid[16];uint64_t partition_entry_lba;uint32_t num_partition_entries;uint32_t partition_entry_size;uint32_t partition_array_crc32;
} gpt_header_t;// GPT分区条目结构
typedef struct {uint8_t  partition_type_guid[16];uint8_t  unique_partition_guid[16];uint64_t first_lba;uint64_t last_lba;uint64_t attributes;uint16_t partition_name[36];
} gpt_entry_t;

1.2 查看设备分区信息

在Android设备上,可以通过以下命令查看分区布局:

# 查看分区表
cat /proc/partitions# 查看块设备信息
ls -l /dev/block/platform/*/by-name/# 使用parted工具查看详细分区信息
parted /dev/block/mmcblk0 print

典型输出示例:

Number  Start   End     Size    File system  Name1      17.4kB  134MB   134MB                bootloader2      134MB   135MB   524kB                dsp3      135MB   136MB   1049kB               rpm4      136MB   137MB   524kB                tz5      137MB   138MB   524kB                pad6      138MB   139MB   1049kB               modem7      139MB   140MB   524kB                misc8      140MB   141MB   524kB                persist9      141MB   142MB   524kB                metadata
10      142MB   143MB   524kB                bk1
11      143MB   144MB   524kB                bk2
12      144MB   145MB   524kB                fsc
13      145MB   146MB   524kB                ssd
14      146MB   147MB   524kB                keystore
15      147MB   148MB   524kB                config
16      148MB   149MB   524kB                oem
17      149MB   182MB   33.6MB               boot
18      182MB   215MB   33.6MB               recovery
19      215MB   249MB   33.6MB               fota
20      249MB   3435MB  3186MB  ext4         system
21      3435MB  3969MB  524MB   ext4         cache
22      3969MB  32.0GB  28.0GB  ext4         userdata

二、核心分区详解

2.1 Bootloader分区

功能概述:
Bootloader是设备启动的第一个程序,相当于PC上的BIOS/UEFI。它负责初始化硬件、验证启动镜像、加载内核到内存并启动。

技术细节:

Android设备通常使用多级Bootloader架构:

  1. PBL (Primary Bootloader) - 固化在ROM中,不可修改
  2. SBL (Secondary Bootloader) - 可更新,通常是厂商定制
  3. ABOOT (Application Bootloader) - Little Kernel(LK)

Little Kernel启动代码:

// bootloader/lk/app/aboot/aboot.c
void aboot_init(const struct app_descriptor *app)
{unsigned reboot_mode = 0;bool boot_into_fastboot = false;// 检查重启原因reboot_mode = check_reboot_mode();switch (reboot_mode){case RECOVERY_MODE:boot_into_recovery = 1;break;case FASTBOOT_MODE:boot_into_fastboot = true;break;case ALARM_BOOT:boot_into_alarm = 1;break;default:// 正常启动模式boot_linux_from_mmc();break;}
}// 从MMC加载Linux内核
int boot_linux_from_mmc(void)
{struct boot_img_hdr *hdr = (void*) BOOT_IMG_ADDR;unsigned offset = 0;unsigned long long ptn = 0;int index = INVALID_PTN;// 获取boot分区index = partition_get_index("boot");ptn = partition_get_offset(index);// 读取boot镜像头if (mmc_read(ptn + offset, (unsigned int *) hdr, BOOT_IMG_HDR_SIZE)) {dprintf(CRITICAL, "ERROR: Cannot read boot image header\n");return -1;}// 验证boot镜像签名if (check_aboot_addr_range_overlap(hdr->kernel_addr, hdr->kernel_size) ||check_aboot_addr_range_overlap(hdr->ramdisk_addr, hdr->ramdisk_size)){dprintf(CRITICAL, "kernel/ramdisk addresses overlap with aboot addresses.\n");return -1;}// 加载kerneloffset = BOOT_IMG_HDR_SIZE;if (mmc_read(ptn + offset, (void *)hdr->kernel_addr, hdr->kernel_size)) {dprintf(CRITICAL, "ERROR: Cannot read kernel image\n");return -1;}// 加载ramdiskoffset += hdr->kernel_size;offset = ROUND_TO_PAGE(offset, page_mask);if (mmc_read(ptn + offset, (void *)hdr->ramdisk_addr, hdr->ramdisk_size)) {dprintf(CRITICAL, "ERROR: Cannot read ramdisk image\n");return -1;}// 启动内核boot_linux((void *)hdr->kernel_addr, (void *)hdr->tags_addr,(const char *)hdr->cmdline, board_machtype(),(void *)hdr->ramdisk_addr, hdr->ramdisk_size);return 0;
}

Fastboot协议实现:

Fastboot是Bootloader提供的一个通信协议,用于刷机操作:

// bootloader/lk/app/aboot/fastboot.c
void cmd_flash_mmc_img(const char *arg, void *data, unsigned sz)
{unsigned long long ptn = 0;unsigned long long size = 0;int index = INVALID_PTN;char *token = NULL;char *pname = NULL;// 解析分区名称token = strtok((char *)arg, " ");pname = token;// 获取分区信息index = partition_get_index(pname);ptn = partition_get_offset(index);if (ptn == 0) {fastboot_fail("partition table doesn't exist");return;}size = partition_get_size(index);if (sz > size) {fastboot_fail("size too large");return;}// 写入数据到分区if (mmc_write(ptn, sz, (unsigned int *)data)) {fastboot_fail("flash write failure");return;}fastboot_okay("");
}

2.2 Boot分区

功能概述:
Boot分区包含Linux内核(kernel)和根文件系统的内存映像(ramdisk),是Android正常启动的关键分区。

Boot.img结构:

// system/core/mkbootimg/include/bootimg/bootimg.h
#define BOOT_MAGIC "ANDROID!"
#define BOOT_MAGIC_SIZE 8
#define BOOT_NAME_SIZE 16
#define BOOT_ARGS_SIZE 512
#define BOOT_EXTRA_ARGS_SIZE 1024struct boot_img_hdr_v0 {uint8_t magic[BOOT_MAGIC_SIZE];      // "ANDROID!"uint32_t kernel_size;                // 内核大小uint32_t kernel_addr;                // 内核加载地址uint32_t ramdisk_size;               // ramdisk大小uint32_t ramdisk_addr;               // ramdisk加载地址uint32_t second_size;                // 第二阶段引导程序大小uint32_t second_addr;                // 第二阶段引导程序地址uint32_t tags_addr;                  // 设备树标签地址uint32_t page_size;                  // flash页大小uint32_t header_version;             // 头版本uint32_t os_version;                 // 操作系统版本uint8_t name[BOOT_NAME_SIZE];        // 产品名称uint8_t cmdline[BOOT_ARGS_SIZE];     // 内核命令行uint32_t id[8];                      // 时间戳/校验和uint8_t extra_cmdline[BOOT_EXTRA_ARGS_SIZE];
};// Boot镜像布局:
// +-----------------------+
// | boot header           | 1 page
// +-----------------------+
// | kernel                | n pages
// +-----------------------+
// | ramdisk               | m pages
// +-----------------------+
// | second stage          | o pages (可选)
// +-----------------------+
// | device tree           | p pages (可选)
// +-----------------------+

制作Boot镜像工具:

#!/usr/bin/env python3
# mkbootimg实现示例import struct
import osclass BootImage:BOOT_MAGIC = b'ANDROID!'BOOT_MAGIC_SIZE = 8BOOT_NAME_SIZE = 16BOOT_ARGS_SIZE = 512BOOT_EXTRA_ARGS_SIZE = 1024def __init__(self):self.kernel = Noneself.ramdisk = Noneself.second = Noneself.dtb = Noneself.cmdline = ""self.page_size = 2048self.base = 0x10000000self.kernel_offset = 0x00008000self.ramdisk_offset = 0x01000000self.second_offset = 0x00f00000self.tags_offset = 0x00000100def pack_header(self):"""打包boot头"""header = struct.pack('8s10I16s512s8I1024s',self.BOOT_MAGIC,len(self.kernel) if self.kernel else 0,self.base + self.kernel_offset,len(self.ramdisk) if self.ramdisk else 0,self.base + self.ramdisk_offset,len(self.second) if self.second else 0,self.base + self.second_offset,self.base + self.tags_offset,self.page_size,0,  # header_version0,  # os_versionb'',  # nameself.cmdline.encode('ascii').ljust(512, b'\x00'),0, 0, 0, 0, 0, 0, 0, 0,  # idb''  # extra_cmdline)return headerdef pad_to_page(self, data):"""填充到页边界"""padding = self.page_size - (len(data) % self.page_size)if padding < self.page_size:data += b'\x00' * paddingreturn datadef create_image(self, output_path):"""创建boot镜像"""with open(output_path, 'wb') as f:# 写入头header = self.pack_header()f.write(self.pad_to_page(header))# 写入kernelif self.kernel:f.write(self.pad_to_page(self.kernel))# 写入ramdiskif self.ramdisk:f.write(self.pad_to_page(self.ramdisk))# 写入secondif self.second:f.write(self.pad_to_page(self.second))# 写入dtbif self.dtb:f.write(self.pad_to_page(self.dtb))# 使用示例
boot_img = BootImage()
boot_img.kernel = open('zImage', 'rb').read()
boot_img.ramdisk = open('ramdisk.img', 'rb').read()
boot_img.cmdline = "console=ttyMSM0,115200,n8 androidboot.hardware=qcom"
boot_img.create_image('boot.img')

Ramdisk结构:

Ramdisk是一个cpio格式的压缩文件系统,包含init程序和系统启动所需的配置文件:

# 解压ramdisk
mkdir ramdisk
cd ramdisk
gunzip -c ../ramdisk.img | cpio -i# ramdisk目录结构
.
├── init                    # init可执行文件
├── init.rc                 # 主要init配置文件
├── init.{hardware}.rc      # 硬件相关配置
├── init.usb.rc            # USB配置
├── init.zygote64.rc       # Zygote配置
├── ueventd.rc             # 设备节点规则
├── default.prop           # 默认属性
├── dev/                   # 设备节点目录
├── proc/                  # proc挂载点
├── sys/                   # sysfs挂载点
├── system/                # system挂载点
├── vendor/                # vendor挂载点
├── data/                  # data挂载点
├── sbin/                  # 系统二进制文件
│   └── recovery          # recovery模式二进制
└── etc/                   # 配置文件└── fstab.{hardware}   # 文件系统表

2.3 System分区

功能概述:
System分区包含Android操作系统的核心组件,包括系统应用、框架服务、系统库等。

目录结构:

/system/
├── app/                          # 系统应用
│   ├── Browser.apk
│   ├── Calendar.apk
│   ├── Camera.apk
│   ├── Contacts.apk
│   ├── Phone.apk
│   └── Settings.apk
├── priv-app/                     # 特权应用(具有系统权限)
│   ├── GoogleServicesFramework.apk
│   ├── Launcher3.apk
│   └── SystemUI.apk
├── framework/                    # Android框架
│   ├── framework.jar            # 核心框架
│   ├── framework-res.apk        # 框架资源
│   ├── services.jar             # 系统服务
│   └── android.policy.jar       # 策略框架
├── lib/                         # 32位系统库
│   ├── libc.so
│   ├── libm.so
│   ├── liblog.so
│   ├── libcutils.so
│   └── libandroid_runtime.so
├── lib64/                       # 64位系统库
├── bin/                         # 系统二进制文件
│   ├── app_process            # Zygote进程
│   ├── servicemanager         # Binder服务管理器
│   ├── surfaceflinger         # 显示服务
│   ├── mediaserver            # 媒体服务
│   └── installd               # 应用安装守护进程
├── xbin/                        # 扩展二进制文件
│   ├── su                      # 超级用户(root设备)
│   └── busybox                # 工具集合
├── etc/                         # 配置文件
│   ├── permissions/           # 权限定义
│   ├── security/              # 安全策略
│   └── vold.fstab             # 存储卷配置
├── fonts/                       # 系统字体
├── media/                       # 媒体资源
│   ├── audio/                 # 音频文件
│   └── bootanimation.zip      # 开机动画
└── build.prop                   # 系统属性配置

System镜像格式:

System分区通常使用ext4文件系统,也可能使用F2FS(Flash-Friendly File System):

// 创建ext4文件系统镜像的代码示例
// system/extras/ext4_utils/make_ext4fs.c#include <ext4_utils/ext4_utils.h>
#include <ext4_utils/make_ext4fs.h>int make_ext4fs_internal(int fd, const char *directory,const char *mountpoint, fs_config_func_t fs_config_func,int gzip, int sparse, int crc,int wipe, int init_itabs, int verbose)
{struct ext4_info info;// 初始化ext4信息结构info.len = compute_block_size();info.block_size = 4096;info.blocks_per_group = 32768;info.inodes_per_group = 8192;info.inode_size = 256;info.label = "";info.no_journal = 0;// 分配块组allocate_block_groups(&info);// 写入超级块write_super_block(fd, &info);// 写入块组描述符表write_block_group_descriptors(fd, &info);// 如果指定了目录,则填充文件系统if (directory) {populate_fs(fd, directory, &info, fs_config_func);}// 写入校验和if (crc) {append_crc(fd, &info);}return 0;
}

2.4 Vendor分区

功能概述:
从Android 8.0(Oreo)开始引入Project Treble架构,Vendor分区用于存储硬件抽象层(HAL)实现和芯片厂商提供的二进制文件,实现了系统框架与硬件实现的解耦。

目录结构:

/vendor/
├── bin/                         # 厂商二进制文件
│   ├── hw/                     # 硬件服务
│   │   ├── android.hardware.audio@4.0-service
│   │   ├── android.hardware.camera.provider@2.4-service
│   │   ├── android.hardware.drm@1.2-service
│   │   └── android.hardware.graphics.composer@2.3-service
│   └── thermal-engine          # 温控守护进程
├── lib/                         # 32位厂商库
│   ├── hw/                     # 硬件模块
│   │   ├── gralloc.msm8998.so
│   │   ├── camera.msm8998.so
│   │   └── sensors.msm8998.so
│   └── libqmi.so
├── lib64/                       # 64位厂商库
├── etc/                         # 厂商配置
│   ├── permissions/           # 厂商权限
│   ├── init/                  # init脚本
│   ├── audio_effects.xml      # 音效配置
│   ├── media_codecs.xml       # 编解码器配置
│   └── vintf/                 # VINTF清单
│       └── manifest.xml       # HAL接口清单
└── firmware/                    # 固件文件├── adsp.mdt               # DSP固件├── modem.mdt              # 调制解调器固件└── venus.mdt              # 视频编解码器固件

VINTF清单示例:

<!-- vendor/etc/vintf/manifest.xml -->
<manifest version="1.0" type="device"><!-- Camera HAL --><hal format="hidl"><name>android.hardware.camera.provider</name><transport>hwbinder</transport><version>2.4</version><interface><name>ICameraProvider</name><instance>legacy/0</instance></interface></hal><!-- Audio HAL --><hal format="hidl"><name>android.hardware.audio</name><transport>hwbinder</transport><version>6.0</version><interface><name>IDevicesFactory</name><instance>default</instance></interface></hal><!-- Graphics Composer HAL --><hal format="hidl"><name>android.hardware.graphics.composer</name><transport>hwbinder</transport><version>2.3</version><interface><name>IComposer</name><instance>default</instance></interface></hal>
</manifest>

2.5 Data分区

功能概述:
Data分区存储用户数据和应用数据,是唯一可读写的分区。

目录结构:

/data/
├── app/                         # 用户安装的应用
│   └── com.example.app-xxx/
│       └── base.apk
├── data/                        # 应用私有数据
│   └── com.example.app/
│       ├── cache/              # 应用缓存
│       ├── databases/          # 数据库
│       ├── files/              # 文件
│       └── shared_prefs/       # SharedPreferences
├── dalvik-cache/               # ART/Dalvik缓存
│   ├── arm/
│   │   └── system@app@*.apk@classes.dex
│   └── arm64/
├── system/                      # 系统数据
│   ├── packages.xml            # 包管理器数据
│   ├── packages.list           # 包列表
│   ├── users/                  # 多用户数据
│   └── sync/                   # 同步数据
├── misc/                        # 其他数据
│   ├── wifi/                   # WiFi配置
│   ├── bluetooth/              # 蓝牙配置
│   └── keychain/               # 密钥链
├── media/                       # 共享存储
│   └── 0/                      # 主用户存储
│       ├── Android/
│       ├── DCIM/               # 相机照片
│       ├── Download/           # 下载
│       └── Music/              # 音乐
├── local/                       # 本地数据
│   └── tmp/                    # 临时文件
└── tombstones/                  # 崩溃转储

加密机制:

Android支持全盘加密(FDE)和文件级加密(FBE):

// system/vold/cryptfs.c
// FDE加密实现#define CRYPT_FOOTER_OFFSET 0x4000struct crypt_mnt_ftr {__le32 magic;              /* 魔数 0x4353544E */__le16 major_version;__le16 minor_version;__le32 ftr_size;          /* 结构体大小 */__le32 flags;             /* 加密标志 */__le32 keysize;           /* 密钥大小 */__le32 crypt_type;        /* 加密类型 */__le64 fs_size;           /* 文件系统大小 */__le32 failed_decrypt_count;unsigned char crypto_type_name[MAX_CRYPTO_TYPE_NAME_LEN];__le32 spare2;unsigned char master_key[MAX_KEY_LEN];  /* 主密钥 */unsigned char salt[SALT_LEN];           /* 盐值 */
};int cryptfs_enable_internal(char *passwd, int crypt_type)
{struct crypt_mnt_ftr crypt_ftr;unsigned char encrypted_master_key[KEY_LEN_BYTES];unsigned char salt[SALT_LEN];// 生成随机主密钥if (read_urandom(crypt_ftr.master_key, KEY_LEN_BYTES) != 0) {return -1;}// 生成随机盐值if (read_urandom(salt, SALT_LEN) != 0) {return -1;}// 使用用户密码加密主密钥encrypt_master_key(passwd, salt, crypt_ftr.master_key,encrypted_master_key, &crypt_ftr);// 写入加密footerput_crypt_ftr_and_key(&crypt_ftr);// 使用dm-crypt设置加密卷create_crypto_blk_dev(&crypt_ftr, encrypted_master_key,real_blkdev, crypto_blkdev, "userdata");return 0;
}

2.6 Recovery分区

功能概述:
Recovery是一个独立的最小化Linux环境,用于系统恢复、升级和维护操作。

Recovery模式功能:

  1. 系统更新(OTA升级)
  2. 恢复出厂设置
  3. 清除缓存分区
  4. 备份和恢复
  5. 从SD卡安装更新包

Recovery主程序实现:

// bootable/recovery/recovery.cppstatic const char *COMMAND_FILE = "/cache/recovery/command";
static const char *LOG_FILE = "/cache/recovery/log";enum PromptAndWaitResult {PROMPT_AND_WAIT_REBOOT,PROMPT_AND_WAIT_FASTBOOT,PROMPT_AND_WAIT_RECOVERY
};int main(int argc, char **argv) {// 设置管道用于UI通信if (pipe(g_pipe) == -1) {LOGE("Failed to create pipe: %s\n", strerror(errno));return EXIT_FAILURE;}// 初始化UIui = new RecoveryUI();ui->Init();ui->SetLocale(locale);// 加载volume表load_volume_table();// 挂载/cache分区ensure_path_mounted(CACHE_ROOT);// 读取命令文件std::vector<std::string> args;get_args(&args);int status = INSTALL_SUCCESS;if (update_package != nullptr) {// 安装更新包status = install_package(update_package, &wipe_cache, TEMPORARY_INSTALL_FILE);if (status == INSTALL_SUCCESS && wipe_cache) {if (erase_volume("/cache")) {LOGE("Cache wipe failed.\n");status = INSTALL_ERROR;}}if (status != INSTALL_SUCCESS) {ui->Print("Installation aborted.\n");}} else if (wipe_data) {// 恢复出厂设置if (erase_volume("/data")) {status = INSTALL_ERROR;}if (erase_volume("/cache")) {status = INSTALL_ERROR;}ui->Print("\nData wipe complete.\n");} else if (wipe_cache) {// 清除缓存if (erase_volume("/cache")) {status = INSTALL_ERROR;}ui->Print("\nCache wipe complete.\n");} else {// 进入交互式recovery菜单status = prompt_and_wait();}// 完成后重启finish_recovery(send_intent);return EXIT_SUCCESS;
}// OTA升级实现
int install_package(const char* path, bool* wipe_cache, const char* install_file) {// 打开更新包MemMapping map;if (sysMapFile(path, &map) != 0) {LOGE("failed to map file\n");return INSTALL_CORRUPT;}// 验证签名std::vector<Certificate> loadedKeys;if (!load_keys(PUBLIC_KEYS_FILE, loadedKeys)) {LOGE("Failed to load keys\n");return INSTALL_CORRUPT;}int err = verify_file(map.addr, map.length, loadedKeys);if (err != VERIFY_SUCCESS) {LOGE("signature verification failed\n");return INSTALL_CORRUPT;}// 安装更新ZipArchive zip;if (mzOpenZipArchive(map.addr, map.length, &zip) != 0) {LOGE("Can't open %s\n", path);return INSTALL_CORRUPT;}// 执行updater-scriptint result = try_update_binary(path, &zip, wipe_cache);mzCloseZipArchive(&zip);sysReleaseMap(&map);return result;
}

2.7 Cache分区

功能概述:
Cache分区用于临时存储系统运行时产生的缓存数据和OTA升级包。

主要用途:

/cache/
├── recovery/                    # Recovery相关文件
│   ├── command                 # Recovery命令
│   ├── log                     # Recovery日志
│   └── last_log                # 上次日志
├── dalvik-cache/               # Dalvik/ART编译缓存(已弃用)
└── lost+found/                 # 文件系统恢复

2.8 Persist分区

功能概述:
Persist分区用于存储持久化配置数据,即使恢复出厂设置也不会被清除。

/persist/
├── sensors/                     # 传感器校准数据
│   ├── accel_cal_params
│   ├── gyro_cal_params
│   └── compass_cal_params
├── data/                        # 持久化数据
│   ├── tz/                     # TrustZone数据
│   └── bluetooth/              # 蓝牙配对信息
└── wifi/                        # WiFi MAC地址

2.9 Misc分区

功能概述:
Misc分区存储系统引导控制信息,如启动模式、恢复命令等。

Bootloader控制块结构:

// bootable/recovery/bootloader_message/include/bootloader_message/bootloader_message.hstruct bootloader_message {char command[32];              // 启动命令char status[32];               // 状态信息char recovery[768];            // Recovery命令行char stage[32];                // 升级阶段char reserved[1184];           // 保留
};// 命令示例:
// command = "boot-recovery" -> 启动到recovery模式
// command = "update-radio" -> 更新基带
// recovery = "recovery\n--wipe_data\n" -> 执行数据擦除

设置启动模式:

// system/core/reboot/reboot.cint set_bootloader_message(const struct bootloader_message *in) {int fd = open("/dev/block/by-name/misc", O_WRONLY | O_SYNC);if (fd < 0) {return -1;}int count = write(fd, in, sizeof(*in));close(fd);return (count == sizeof(*in)) ? 0 : -1;
}// 设置重启到recovery
void reboot_to_recovery() {struct bootloader_message boot;memset(&boot, 0, sizeof(boot));strlcpy(boot.command, "boot-recovery", sizeof(boot.command));strlcpy(boot.recovery, "recovery\n", sizeof(boot.recovery));set_bootloader_message(&boot);// 执行重启property_set("sys.powerctl", "reboot,recovery");
}

2.10 其他重要分区

EFS分区(Encrypted File System):
存储设备唯一标识符,如IMEI、蓝牙/WiFi MAC地址等。

Modem分区:
存储基带固件,负责移动网络通信。

DSP分区:
存储数字信号处理器固件,用于音频/视频处理。

TZ分区(TrustZone):
存储TrustZone操作系统,负责安全相关功能。

三、Android完整启动流程

3.1 启动流程概览

┌─────────────────────────────────────────────────────┐
│                  按下电源键                          │
└──────────────────┬──────────────────────────────────┘│▼
┌─────────────────────────────────────────────────────┐
│  Boot ROM (PBL) - 芯片内置,不可修改                 │
│  • 初始化基本硬件                                    │
│  • 加载Bootloader到RAM                              │
└──────────────────┬──────────────────────────────────┘│▼
┌─────────────────────────────────────────────────────┐
│  Bootloader (SBL/ABOOT)                             │
│  • 初始化更多硬件组件                                │
│  • 检查启动模式(正常/recovery/fastboot)              │
│  • 验证boot.img签名                                 │
│  • 加载kernel和ramdisk到内存                        │
│  • 跳转到kernel入口                                 │
└──────────────────┬──────────────────────────────────┘│▼
┌─────────────────────────────────────────────────────┐
│  Linux Kernel                                        │
│  • 初始化内核子系统                                  │
│  • 加载驱动程序                                      │
│  • 挂载根文件系统(ramdisk)                           │
│  • 启动第一个用户空间进程: /init                     │
└──────────────────┬──────────────────────────────────┘│▼
┌─────────────────────────────────────────────────────┐
│  Init进程 (PID 1)                                    │
│  • 解析init.rc配置文件                               │
│  • 创建文件系统目录结构                              │
│  • 挂载system、vendor、data分区                      │
│  • 设置系统属性                                      │
│  • 启动各种守护进程                                  │
└──────────────────┬──────────────────────────────────┘│▼
┌─────────────────────────────────────────────────────┐
│  Zygote进程                                          │
│  • 初始化Dalvik/ART虚拟机                            │
│  • 预加载系统类和资源                                │
│  • fork出System Server                              │
│  • 监听socket等待启动应用进程                        │
└──────────────────┬──────────────────────────────────┘│▼
┌─────────────────────────────────────────────────────┐
│  System Server                                       │
│  • 启动系统核心服务                                  │
│    - ActivityManagerService                          │
│    - PackageManagerService                           │
│    - WindowManagerService                            │
│    - PowerManagerService等                           │
│  • 注册服务到ServiceManager                          │
└──────────────────┬──────────────────────────────────┘│▼
┌─────────────────────────────────────────────────────┐
│  启动Home Launcher                                   │
│  • ActivityManagerService启动Launcher                │
│  • 显示桌面                                          │
│  • 系统启动完成                                      │
└─────────────────────────────────────────────────────┘

3.2 Kernel初始化详解

Kernel入口函数:

// kernel/init/main.casmlinkage __visible void __init start_kernel(void)
{char *command_line;char *after_dashes;// 设置任务栈set_task_stack_end_magic(&init_task);// 早期架构初始化setup_arch(&command_line);// 内存管理初始化mm_init();// 调度器初始化sched_init();// 中断系统初始化early_irq_init();init_IRQ();// 定时器初始化tick_init();init_timers();hrtimers_init();// 控制台初始化console_init();// 内核模块初始化do_basic_setup();// 挂载根文件系统prepare_namespace();// 启动init进程if (!try_to_run_init_process("/init") ||!try_to_run_init_process("/sbin/init") ||!try_to_run_init_process("/etc/init") ||!try_to_run_init_process("/bin/init") ||!try_to_run_init_process("/bin/sh"))return;panic("No working init found.");
}// 启动init进程
static int try_to_run_init_process(const char *init_filename)
{int ret;ret = run_init_process(init_filename);if (ret && ret != -ENOENT) {pr_err("Starting init: %s exists but couldn't execute it (error %d)\n",init_filename, ret);}return ret;
}

3.3 Init进程详解

Init是Android用户空间的第一个进程,负责启动所有其他系统服务和守护进程。

Init主函数:

// system/core/init/init.cppint main(int argc, char** argv) {// 第一阶段:最小化环境设置if (is_first_stage) {// 创建基本文件系统mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755");mkdir("/dev/pts", 0755);mkdir("/dev/socket", 0755);mount("devpts", "/dev/pts", "devpts", 0, NULL);mount("proc", "/proc", "proc", 0, NULL);mount("sysfs", "/sys", "sysfs", 0, NULL);// SELinux初始化selinux_initialize(true);// 重新执行自己进入第二阶段const char* path = "/init";const char* args[] = {path, "second_stage", nullptr};execv(path, const_cast<char**>(args));}// 第二阶段:完整初始化// 初始化属性服务property_init();// 从内核命令行读取属性process_kernel_cmdline();// 导入默认属性property_load_boot_defaults();// SELinux完整初始化selinux_initialize(false);// 创建epoll实例用于事件循环epoll_fd = epoll_create1(EPOLL_CLOEXEC);// 初始化信号处理signal_handler_init();// 初始化属性服务socketstart_property_service();// 解析init.rc文件Parser parser;parser.AddSectionParser("service", std::make_unique<ServiceParser>());parser.AddSectionParser("on", std::make_unique<ActionParser>());parser.AddSectionParser("import", std::make_unique<ImportParser>());// 解析主配置文件parser.ParseConfig("/init.rc");// 解析硬件特定配置parser.ParseConfig(StringPrintf("/init.%s.rc", GetProperty("ro.hardware", "").c_str()));// 触发early-init动作ActionManager::GetInstance().QueueEventTrigger("early-init");// 挂载文件系统ActionManager::GetInstance().QueueEventTrigger("init");// 触发late-initActionManager::GetInstance().QueueEventTrigger("late-init");// 进入主事件循环while (true) {// 重启需要重启的服务restart_processes();// 执行待执行的命令if (!(waiting_for_exec || waiting_for_prop)) {execute_one_command();}// 等待事件int nr = epoll_wait(epoll_fd, ev, ARRAY_SIZE(ev), timeout_ms);if (nr == -1) {PLOG(ERROR) << "epoll_wait failed";continue;}// 处理事件for (int i = 0; i < nr; ++i) {if (ev[i].data.ptr == &signal_handler) {handle_signal();} else if (ev[i].data.ptr == &property_set_fd) {handle_property_set_fd();}}}return 0;
}

Init.rc配置文件:

# system/core/rootdir/init.rc# 早期初始化
on early-init# 设置init进程优先级setpriority 0 0 -20# 创建cgroup挂载点mkdir /dev/cpuctlmount cgroup none /dev/cpuctl cpu# 启动ueventdstart ueventd# 主初始化
on init# 创建标准目录mkdir /systemmkdir /data 0771 system systemmkdir /cache 0770 system cachemkdir /config 0500 root root# 挂载tmpfs到/mntmkdir /mnt 0775 root systemmount tmpfs tmpfs /mnt mode=0755,uid=0,gid=1000# 创建符号链接symlink /system/etc /etcsymlink /system/bin /binsymlink /system/vendor /vendor# 配置内核参数write /proc/sys/kernel/panic_on_oops 1write /proc/sys/kernel/hung_task_timeout_secs 0write /proc/cpu/alignment 4# 初始化全局环境变量export PATH /system/bin:/system/xbin:/vendor/binexport ANDROID_ROOT /systemexport ANDROID_DATA /dataexport EXTERNAL_STORAGE /sdcard# 延迟初始化
on late-init# 触发文件系统挂载trigger fstrigger post-fstrigger post-fs-data# 启动核心服务trigger boot# 文件系统挂载
on fs# 挂载system分区mount ext4 /dev/block/platform/msm_sdcc.1/by-name/system /system ro barrier=1# 挂载vendor分区mount ext4 /dev/block/platform/msm_sdcc.1/by-name/vendor /vendor ro barrier=1# 挂载cache分区mount ext4 /dev/block/platform/msm_sdcc.1/by-name/cache /cache nosuid nodev barrier=1on post-fs-data# 创建data目录结构mkdir /data/misc 01771 system miscmkdir /data/local 0751 root rootmkdir /data/local/tmp 0771 shell shellmkdir /data/app-private 0771 system systemmkdir /data/app 0771 system system# 启动vold(Volume Daemon)start vold# 启动核心服务
on boot# 基本网络ifup lohostname localhostdomainname localdomain# 设置权限chown system system /sys/class/leds/lcd-backlight/brightnesschmod 0660 /sys/class/leds/lcd-backlight/brightness# 启动服务管理器start servicemanager# 启动健康HALstart health-hal-2-0# 启动Zygotestart zygotestart zygote_secondary# 服务定义# ServiceManager - Binder服务管理器
service servicemanager /system/bin/servicemanagerclass coreuser systemgroup systemcriticalonrestart restart healthdonrestart restart zygoteonrestart restart mediaonrestart restart surfaceflingeronrestart restart drm# Zygote - 应用进程孵化器
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygoteclass mainpriority -20socket zygote stream 660 root systemonrestart write /sys/android_power/request_state wakeonrestart write /sys/power/state ononrestart restart audioserveronrestart restart cameraserveronrestart restart mediaonrestart restart netdonrestart restart wificond# SurfaceFlinger - 显示服务
service surfaceflinger /system/bin/surfaceflingerclass coreuser systemgroup graphics drmrpc readproconrestart restart zygotewritepid /dev/cpuset/system-background/tasks# Media服务
service media /system/bin/mediaserverclass mainuser mediagroup audio camera inet net_bt net_bt_admin net_bw_acct drmrpc mediadrmioprio rt 4writepid /dev/cpuset/foreground/tasks# 网络守护进程
service netd /system/bin/netdclass mainsocket netd stream 0660 root systemsocket dnsproxyd stream 0660 root inetsocket mdns stream 0660 root systemsocket fwmarkd stream 0660 root inet

3.4 Zygote进程详解

Zygote是Android的应用进程孵化器,所有应用进程都是从Zygote fork出来的。

Zygote主函数:

// frameworks/base/cmds/app_process/app_main.cppint main(int argc, char* const argv[])
{AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));// 解析参数bool zygote = false;bool startSystemServer = false;bool application = false;String8 niceName;String8 className;++i;while (i < argc) {const char* arg = argv[i++];if (strcmp(arg, "--zygote") == 0) {zygote = true;niceName = ZYGOTE_NICE_NAME;} else if (strcmp(arg, "--start-system-server") == 0) {startSystemServer = true;} else if (strcmp(arg, "--application") == 0) {application = true;} else if (strncmp(arg, "--nice-name=", 12) == 0) {niceName.setTo(arg + 12);}}if (zygote) {// 启动Zygote模式runtime.start("com.android.internal.os.ZygoteInit", args, zygote);} else if (className) {// 启动应用模式runtime.start("com.android.internal.os.RuntimeInit", args, zygote);}
}

ZygoteInit.java:

// frameworks/base/core/java/com/android/internal/os/ZygoteInit.javapublic class ZygoteInit {public static void main(String argv[]) {ZygoteServer zygoteServer = new ZygoteServer();// 预加载类和资源preload(bootTimingsTraceLog);// 启动System Serverif (startSystemServer) {Runnable r = forkSystemServer(abiList, socketName, zygoteServer);if (r != null) {r.run();return;}}// 监听socket,等待ActivityManagerService的连接请求caller = zygoteServer.runSelectLoop(abiList);// fork出的子进程执行if (caller != null) {caller.run();}}// 预加载常用类private static void preloadClasses() {InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("preloaded-classes");BufferedReader br = new BufferedReader(new InputStreamReader(is), 256);String line;while ((line = br.readLine()) != null) {line = line.trim();if (line.startsWith("#") || line.isEmpty()) {continue;}try {Class.forName(line, true, null);} catch (ClassNotFoundException e) {Log.w(TAG, "Class not found for preloading: " + line);}}}// Fork System Server进程private static Runnable forkSystemServer(String abiList, String socketName,ZygoteServer zygoteServer) {String args[] = {"--setuid=1000","--setgid=1000","--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1032,3001,3002,3003,3006,3007,3009,3010","--capabilities=" + capabilities + "," + capabilities,"--nice-name=system_server","--runtime-args","--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,"com.android.server.SystemServer",};ZygoteArguments parsedArgs = null;int pid;try {parsedArgs = new ZygoteArguments(args);// Fork子进程pid = Zygote.forkSystemServer(parsedArgs.mUid,parsedArgs.mGid,parsedArgs.mGids,parsedArgs.mRuntimeFlags,null,parsedArgs.mPermittedCapabilities,parsedArgs.mEffectiveCapabilities);} catch (IllegalArgumentException ex) {throw new RuntimeException(ex);}// 子进程if (pid == 0) {if (hasSecondZygote(abiList)) {waitForSecondaryZygote(socketName);}zygoteServer.closeServerSocket();return handleSystemServerProcess(parsedArgs);}return null;}
}

Zygote Fork机制:

// frameworks/base/core/jni/com_android_internal_os_Zygote.cppstatic pid_t ForkCommon(JNIEnv* env, bool is_system_server,jintArray fds_to_close, jintArray fds_to_ignore) {SetSignalHandlers();// Fork前确保所有线程都处于安全状态JNIEnv* child_jnienv = nullptr;pid_t pid = fork();if (pid == 0) {// 子进程// 清理不需要的资源DetachDescriptors(env, fds_to_close);// 重置信号处理UnsetSignalHandlers();// 创建新的JNI环境child_jnienv = GetJNIEnvOrDie();// 设置进程名if (is_system_server) {SetProcessName("system_server");}} else if (pid > 0) {// 父进程}return pid;
}

3.5 System Server详解

System Server是Android框架服务的宿主进程,运行着所有核心系统服务。

SystemServer.java:

// frameworks/base/services/java/com/android/server/SystemServer.javapublic final class SystemServer {public static void main(String[] args) {new SystemServer().run();}private void run() {// 设置虚拟机参数VMRuntime.getRuntime().clearGrowthLimit();VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);// 加载native服务System.loadLibrary("android_servers");// 初始化系统上下文createSystemContext();// 创建系统服务管理器mSystemServiceManager = new SystemServiceManager(mSystemContext);LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);// 启动各种服务try {startBootstrapServices();  // 引导服务startCoreServices();       // 核心服务startOtherServices();      // 其他服务} catch (Throwable ex) {Slog.e("System", "******************************************");Slog.e("System", "************ Failure starting system services", ex);throw ex;}// 循环等待Looper.loop();throw new RuntimeException("Main thread loop unexpectedly exited");}// 启动引导服务private void startBootstrapServices() {// Installer服务 - 负责安装/卸载应用Installer installer = mSystemServiceManager.startService(Installer.class);// ActivityManagerService - 活动管理mActivityManagerService = mSystemServiceManager.startService(ActivityManagerService.Lifecycle.class).getService();mActivityManagerService.setSystemServiceManager(mSystemServiceManager);mActivityManagerService.setInstaller(installer);// PowerManagerService - 电源管理mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);// DisplayManagerService - 显示管理mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);// PackageManagerService - 包管理mPackageManagerService = PackageManagerService.main(mSystemContext, installer,mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);// UserManagerService - 用户管理mSystemServiceManager.startService(UserManagerService.LifeCycle.class);}// 启动核心服务private void startCoreServices() {// BatteryService - 电池服务mSystemServiceManager.startService(BatteryService.class);// UsageStatsService - 使用统计mSystemServiceManager.startService(UsageStatsService.class);// WebViewUpdateServicemSystemServiceManager.startService(WebViewUpdateService.class);}// 启动其他服务private void startOtherServices() {// InputManagerService - 输入管理inputManager = new InputManagerService(context);// WindowManagerService - 窗口管理wm = WindowManagerService.main(context, inputManager,mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF,!mFirstBoot, mOnlyCore, new PhoneWindowManager());ServiceManager.addService(Context.WINDOW_SERVICE, wm);ServiceManager.addService(Context.INPUT_SERVICE, inputManager);inputManager.setWindowManagerCallbacks(wm.getInputMonitor());inputManager.start();// ConnectivityService - 网络连接connectivity = new ConnectivityService(context, networkManagement,networkStats, networkPolicy);ServiceManager.addService(Context.CONNECTIVITY_SERVICE, connectivity);// NotificationManagerService - 通知管理mSystemServiceManager.startService(NotificationManagerService.class);// LocationManagerService - 位置服务mSystemServiceManager.startService(LocationManagerService.class);// AudioService - 音频服务mSystemServiceManager.startService(AudioService.Lifecycle.class);// 启动完成,通知AMS系统就绪mActivityManagerService.systemReady(() -> {// 启动LauncherstartHomeActivity();});}
}

ActivityManagerService核心功能:

// frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.javapublic class ActivityManagerService extends IActivityManager.Stub {// 启动Activitypublic final int startActivity(IApplicationThread caller, String callingPackage,Intent intent, String resolvedType, IBinder resultTo, String resultWho,int requestCode, int startFlags, ProfilerInfo profilerInfo,Bundle bOptions) {return startActivityAsUser(caller, callingPackage, intent, resolvedType,resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions,UserHandle.getCallingUserId());}// 启动进程private final void startProcessLocked(ProcessRecord app, String hostingType,String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {try {// 通过Zygote fork新进程final int userId = UserHandle.getUserId(app.uid);int[] gids = null;final IPackageManager pm = AppGlobals.getPackageManager();try {gids = pm.getPackageGids(app.info.packageName, 0, app.userId);} catch (RemoteException e) {}int debugFlags = 0;if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;}Process.ProcessStartResult startResult = Process.start(entryPoint,app.processName, uid, uid, gids, debugFlags, mountExternal,app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,app.info.dataDir, invokeWith, entryPointArgs);synchronized (this) {app.pid = startResult.pid;app.thread = null;app.pendingStart = false;}} catch (RuntimeException e) {app.pid = 0;}}
}

四、刷机原理与实践

4.1 刷机方式分类

1. Fastboot刷机

通过Bootloader的Fastboot模式进行刷机,最常用最安全的方式:

# 重启到fastboot模式
adb reboot bootloader# 查看设备
fastboot devices# 刷写各个分区
fastboot flash boot boot.img
fastboot flash system system.img
fastboot flash vendor vendor.img
fastboot flash userdata userdata.img
fastboot flash recovery recovery.img# 格式化data分区
fastboot -w# 重启设备
fastboot reboot

Fastboot命令实现:

// system/core/fastboot/fastboot.cppint main(int argc, char* argv[]) {const char* cmdline = NULL;const char* data = NULL;unsigned sz;fastboot_device_t* dev = fb_open();if (!strcmp(argv[1], "flash")) {// 刷写分区const char* partition = argv[2];const char* filename = argv[3];// 读取镜像文件data = load_file(filename, &sz);if (data == 0) {die("cannot load '%s'", filename);}// 获取分区信息fb_queue_query_var(dev, "partition-type:" + partition);fb_queue_query_var(dev, "partition-size:" + partition);// 擦除分区fb_queue_erase(dev, partition);// 下载镜像到设备RAMfb_queue_download(dev, "boot.img", data, sz);// 刷写到flashfb_queue_flash(dev, partition);} else if (!strcmp(argv[1], "erase")) {// 擦除分区fb_queue_erase(dev, argv[2]);} else if (!strcmp(argv[1], "getvar")) {// 获取变量fb_queue_display(dev, argv[2], argv[2]);} else if (!strcmp(argv[1], "reboot")) {// 重启fb_queue_reboot(dev);}// 执行队列中的命令fb_execute_queue(dev);fb_close(dev);return 0;
}

2. Recovery刷机

通过Recovery模式刷写OTA升级包:

# 重启到recovery模式
adb reboot recovery# 推送OTA包到设备
adb push update.zip /sdcard/# 在recovery中选择"Install update from SD card"
# 或通过命令行
adb shell
echo --update_package=/sdcard/update.zip > /cache/recovery/command
reboot recovery

OTA包结构:

update.zip
├── META-INF/
│   └── com/
│       └── google/
│           └── android/
│               ├── update-binary      # 安装脚本解释器
│               ├── updater-script     # 安装脚本
│               └── update-binary-sig  # 签名
├── boot.img                          # 新的boot镜像
├── system/                           # 系统文件
│   ├── app/
│   ├── framework/
│   ├── lib/
│   └── ...
└── patch/                            # 差分补丁├── system.patch└── vendor.patch

Updater-script示例:

# META-INF/com/google/android/updater-script# 显示进度
ui_print("=============================");
ui_print(" Android OTA Update ");
ui_print("=============================");# 检查设备
assert(getprop("ro.product.device") == "devicename" ||getprop("ro.build.product") == "devicename");# 挂载分区
ui_print("Mounting system...");
mount("ext4", "EMMC", "/dev/block/platform/msm_sdcc.1/by-name/system", "/system");# 删除旧文件
ui_print("Removing old files...");
delete_recursive("/system/app/OldApp");# 提取新文件
ui_print("Extracting system files...");
package_extract_dir("system", "/system");# 设置权限
ui_print("Setting permissions...");
set_perm_recursive(0, 0, 0755, 0644, "/system/app");
set_perm(0, 0, 0755, "/system/bin/app_process");# 刷写boot镜像
ui_print("Installing boot image...");
package_extract_file("boot.img", "/dev/block/platform/msm_sdcc.1/by-name/boot");# 卸载分区
unmount("/system");# 完成
ui_print("Update complete!");
ui_print("Rebooting...");

3. 线刷

使用厂商提供的专用刷机工具,如小米的MiFlash、三星的Odin等。

4.2 镜像文件解包与打包

解包Boot镜像:

#!/usr/bin/env python3
import struct
import osdef unpack_boot_img(boot_img_path):with open(boot_img_path, 'rb') as f:# 读取头部header = f.read(2048)# 解析头部magic = header[0:8]if magic != b'ANDROID!':print("Invalid boot image!")returnkernel_size = struct.unpack('<I', header[8:12])[0]kernel_addr = struct.unpack('<I', header[12:16])[0]ramdisk_size = struct.unpack('<I', header[16:20])[0]ramdisk_addr = struct.unpack('<I', header[20:24])[0]second_size = struct.unpack('<I', header[24:28])[0]second_addr = struct.unpack('<I', header[28:32])[0]tags_addr = struct.unpack('<I', header[32:36])[0]page_size = struct.unpack('<I', header[36:40])[0]print(f"Kernel size: {kernel_size}")print(f"Ramdisk size: {ramdisk_size}")print(f"Page size: {page_size}")# 计算偏移kernel_offset = page_sizeramdisk_offset = kernel_offset + ((kernel_size + page_size - 1) // page_size) * page_size# 提取kernelf.seek(kernel_offset)kernel = f.read(kernel_size)with open('kernel', 'wb') as kf:kf.write(kernel)print("Extracted kernel")# 提取ramdiskf.seek(ramdisk_offset)ramdisk = f.read(ramdisk_size)with open('ramdisk.img', 'wb') as rf:rf.write(ramdisk)print("Extracted ramdisk")# 解压ramdiskos.system('mkdir ramdisk')os.system('cd ramdisk && gunzip -c ../ramdisk.img | cpio -i')print("Unpacked ramdisk")if __name__ == '__main__':unpack_boot_img('boot.img')

打包System镜像:

#!/bin/bash
# 制作ext4格式的system镜像# 计算system目录大小
SYSTEM_SIZE=$(du -sb system | awk '{print $1}')
# 增加20%空间
IMAGE_SIZE=$((SYSTEM_SIZE * 12 / 10))# 创建空白镜像文件
dd if=/dev/zero of=system.img bs=1 count=0 seek=$IMAGE_SIZE# 格式化为ext4
mkfs.ext4 -F -L system system.img# 挂载镜像
mkdir -p temp_mount
sudo mount -o loop system.img temp_mount# 复制文件到镜像
sudo cp -a system/* temp_mount/# 卸载镜像
sudo umount temp_mount
rmdir temp_mount# 转换为sparse格式(可选,减小文件大小)
img2simg system.img system.sparse.imgecho "System image created: system.img"

4.3 签名验证机制

Android使用数字签名来确保系统镜像的完整性和真实性。

Verified Boot (dm-verity):

// system/extras/verity/dm-verity-signing.cppint sign_verity_table(const char* table, const char* key,unsigned char* signature, size_t signature_size) {RSA* rsa = NULL;FILE* f = NULL;int rc = -1;// 读取私钥f = fopen(key, "r");if (!f) {fprintf(stderr, "Can't open key file %s\n", key);return -1;}rsa = PEM_read_RSAPrivateKey(f, NULL, NULL, NULL);fclose(f);if (!rsa) {fprintf(stderr, "Failed to read RSA key\n");return -1;}// 计算SHA-256哈希unsigned char digest[SHA256_DIGEST_LENGTH];SHA256((unsigned char*)table, strlen(table), digest);// 使用RSA私钥签名unsigned int sig_len = 0;if (RSA_sign(NID_sha256, digest, sizeof(digest),signature, &sig_len, rsa) != 1) {fprintf(stderr, "RSA signature failed\n");goto out;}rc = 0;out:RSA_free(rsa);return rc;
}

AVB (Android Verified Boot 2.0):

// external/avb/libavb/avb_slot_verify.cAvbSlotVerifyResult avb_slot_verify(AvbOps* ops,const char* const* requested_partitions,const char* ab_suffix,AvbSlotVerifyFlags flags,AvbHashtreeErrorMode hashtree_error_mode,AvbSlotVerifyData** out_data) {AvbSlotVerifyResult ret;AvbVBMetaData* vbmeta_images = NULL;// 加载vbmeta分区ret = load_and_verify_vbmeta(ops, requested_partitions, ab_suffix,flags, &vbmeta_images);if (ret != AVB_SLOT_VERIFY_RESULT_OK) {goto out;}// 验证每个分区for (size_t n = 0; requested_partitions[n] != NULL; n++) {const char* partition_name = requested_partitions[n];// 加载分区uint8_t* partition_data = NULL;size_t partition_data_size = 0;ret = ops->read_from_partition(ops, partition_name, 0,partition_data_size,partition_data,&partition_data_size);// 验证哈希ret = verify_partition_hash(vbmeta_images, partition_name,partition_data, partition_data_size);if (ret != AVB_SLOT_VERIFY_RESULT_OK) {avb_error("Hash verification failed for partition: ",partition_name, "\n");goto out;}}out:return ret;
}

五、高级主题

5.1 A/B系统分区

Android 7.0引入无缝更新机制(A/B System Updates),设备有两套系统分区:

Slot A:
- boot_a
- system_a
- vendor_aSlot B:
- boot_b
- system_b
- vendor_b

更新流程:

// system/update_engine/update_attempter.ccvoid UpdateAttempter::ProcessingDone(const ActionProcessor* processor,ErrorCode code) {if (code == ErrorCode::kSuccess) {// 标记当前slot为成功boot_control_->MarkBootSuccessful();// 切换到新slotif (!boot_control_->SetActiveBootSlot(target_slot_)) {LOG(ERROR) << "Unable to set the active slot to " << target_slot_;}// 重启到新系统Terminate();}
}// hardware/interfaces/boot/1.0/default/BootControl.cpp
Return<bool> BootControl::setActiveBootSlot(uint32_t slot) {struct boot_control_private *private = impl_->priv;// 设置boot control头private->header.slot_info[slot].priority = 15;private->header.slot_info[slot].tries_remaining = 7;private->header.slot_info[slot].successful_boot = 0;// 另一个slot设置为非活动uint32_t other_slot = slot ? 0 : 1;private->header.slot_info[other_slot].priority = 0;// 写入磁盘write_boot_control(private);return true;
}

5.2 动态分区(Dynamic Partitions)

Android 10引入动态分区,使用LVM(逻辑卷管理)技术:

Physical Partition (super):
├── Logical Partition: system
├── Logical Partition: vendor
├── Logical Partition: product
└── Free Space

动态分区元数据:

// system/core/fs_mgr/liblp/include/liblp/metadata_format.hstruct LpMetadataGeometry {uint32_t magic;uint16_t major_version;uint16_t minor_version;uint32_t header_size;uint32_t header_checksum;uint32_t tables_size;uint32_t tables_checksum;
};struct LpMetadataPartition {char name[36];uint32_t attributes;uint64_t first_extent_index;uint64_t num_extents;uint32_t group_index;
};struct LpMetadataExtent {uint64_t num_sectors;uint32_t target_type;uint64_t target_data;uint32_t target_source;
};

5.3 SELinux安全上下文

SELinux为Android提供强制访问控制(MAC):

SELinux策略编译:

# 编译SELinux策略
m4 -D mls_num_sens=1 -D mls_num_cats=1024 -D target_build_variant=user \-s policy.conf > policy.conf.m4
checkpolicy -M -c 30 -o sepolicy policy.conf.m4# 加载策略
load_policy sepolicy

文件标签设置:

# system/sepolicy/private/file_contexts# System分区
/system(/.*)?              u:object_r:system_file:s0
/system/bin(/.*)?          u:object_r:system_file:s0
/system/bin/app_process.*  u:object_r:zygote_exec:s0
/system/bin/servicemanager u:object_r:servicemanager_exec:s0# Data分区
/data(/.*)?                u:object_r:system_data_file:s0
/data/app(/.*)?            u:object_r:apk_data_file:s0
/data/data(/.*)?           u:object_r:app_data_file:s0# Device节点
/dev/binder                u:object_r:binder_device:s0
/dev/hwbinder              u:object_r:hwbinder_device:s0
/dev/vndbinder             u:object_r:vndbinder_device:s0

六、实战案例:定制ROM

6.1 获取源代码

# 初始化repo
repo init -u https://android.googlesource.com/platform/manifest -b android-12.0.0_r1# 同步代码
repo sync -j8

6.2 修改系统分区

# 进入system目录
cd system/app# 删除不需要的应用
rm -rf Browser
rm -rf Email
rm -rf Music# 添加自定义应用
cp ~/MyApp/MyApp.apk ./# 修改build.prop
cd ../..
vim build.prop# 添加自定义属性
ro.custom.version=1.0
ro.custom.build_date=$(date +%Y%m%d)

6.3 编译系统

# 设置环境
source build/envsetup.sh# 选择目标设备
lunch aosp_xxx-userdebug# 编译
make -j$(nproc)# 生成的镜像在out/target/product/xxx/目录下
ls out/target/product/xxx/*.img

6.4 刷入设备

# 重启到fastboot
adb reboot bootloader# 刷入镜像
fastboot flash boot out/target/product/xxx/boot.img
fastboot flash system out/target/product/xxx/system.img
fastboot flash vendor out/target/product/xxx/vendor.img# 重启
fastboot reboot

七、故障排查与调试

7.1 常见启动问题

卡在Logo界面:

  • 原因: boot.img损坏或kernel参数错误
  • 解决: 重新刷入官方boot.img

无限重启:

  • 原因: system分区损坏或SELinux策略冲突
  • 解决: 通过recovery清除data分区或刷入完整ROM

进入Fastboot/Recovery:

  • 原因: misc分区标志异常
  • 解决: 清除misc分区
# 清除misc分区
adb shell
dd if=/dev/zero of=/dev/block/by-name/misc bs=1 count=1024

7.2 日志分析

查看启动日志:

# Kernel日志
adb shell dmesg# Logcat日志
adb logcat# 查看上次崩溃日志
adb shell cat /proc/last_kmsg# Recovery日志
adb shell cat /cache/recovery/log

分析启动时间:

# 查看各阶段耗时
adb shell dmesg | grep "init:"# 查看服务启动时间
adb shell dumpsys activity services

八、总结

本文详细介绍了Android分区架构、启动流程和刷机原理。主要内容包括:

  1. 分区架构: 详细讲解了Boot、System、Vendor、Data等核心分区的功能和实现
  2. 启动流程: 从Bootloader到Android Framework的完整启动链
  3. 关键组件: Init进程、Zygote、System Server的工作原理
  4. 刷机技术: Fastboot、Recovery OTA等刷机方式的实现
  5. 高级特性: A/B分区、动态分区、SELinux等现代Android特性

掌握这些知识,不仅能够深入理解Android系统的运作机制,也为进行系统定制、ROM开发、问题排查奠定了坚实的基础。

参考资源

  • Android Open Source Project: https://source.android.com
  • Linux Kernel Documentation: https://www.kernel.org/doc/html/latest/
  • Little Kernel Project: https://github.com/littlekernel/lk
  • Android Verified Boot: https://source.android.com/security/verifiedboot
  • SELinux for Android: https://source.android.com/security/selinux

作者注: 本文涉及的代码示例基于AOSP项目,部分代码经过简化以便理解。实际实现可能因Android版本和设备而异。在进行刷机操作前,请务必备份重要数据,并确保了解相关风险。

http://www.dtcms.com/a/535981.html

相关文章:

  • 高防 IP 如何保护企业网站?
  • 原创 网站 源码Discuz网站制作教程
  • windows 2003建设网站网站制作案例市场
  • mysql的安装和卸载过程
  • 软件设计师知识点总结:算法设计与分析
  • 互联网设计公司网站wordpress 404页面模板
  • python+ai智能根据doc教案文档生成ppt
  • PPT WPS ERROR +mn-ea
  • 技术解析 | QtScrcpy:一款基于Qt的跨平台Android投屏工具的实现原理与代码架构
  • F037 vue+neo4j 编程语言知识图谱可视化分析系统vue+flask+neo4j
  • qt设置运行框左上角图标
  • 大量PPT文件怎么快速转换成JPG格式的长图
  • 网站数据怎么做接口供小程序调用企业手机网站建设策划方案
  • LabVIEW机械零件尺寸检测
  • 网站建设公司整站源码专做网站公司
  • ProfiNet转EtherNet/IP工业智能网关实现欧姆龙PLC与倍福I/O模块通讯的实操案例
  • AR工业巡检:虚实融合的智能巡检技术详解
  • 【LUA教程】LUA脚本语言中文教程.PDF
  • 初识影刀--一款 AI 驱动的 RPA 自动化软件
  • SAP SD客户对账开票功能分享
  • 洛谷 P1177:【模板】排序 ← 基数排序实现
  • 株洲网站设计外包首选中国可信网站查询
  • 物联网智慧医疗:告别胶片时代的就医革命
  • 3步实现MQTT远程连接!EMQX+cpolar构建物联网消息高速公路
  • 怎么注册微网站织梦建设网站全过程
  • [无人机sdk] `FlightController` | startTakeoffSync() | actionSync()
  • [linux仓库]线程与进程的较量:资源划分与内核实现的全景解析[线程·贰]
  • Flutter开发HarmonyOS鸿蒙App商业项目实战已出炉
  • 宁波网站建设制作公司排名网站优化外链怎么做
  • 开发做网站公司国内网站空间推荐