
Kernel 完成初始化之后会挂载并解包initramfs(ramdisk)作为临时根文件系统Kernel_init 执行 /init/init 的init_first_stage以下是 ramdisk/init 的构建规则LOCAL_MODULE : init_first_stage LOCAL_MODULE_STEM : init ... LOCAL_MODULE_PATH : $(TARGET_RAMDISK_OUT)FirstStageMainFirstStageMain ├─ 1. 初始化最小环境挂载早期必须的伪文件系统 /dev, /proc, /sys, /sys/fs/selinux ├─ 2. 处理设备节点、设备事件 mknod: /dev/kmsg, random, urandom, ptms, null... ├─ 3. 准备挂载早期目录并启用 kernel logmount: /mnt, /mnt/vendor, product | InitKernelLogging ├─ 4. 解析启动模式加载内核模块LoadKernelModules 会根据 /lib/modules、 recovery 加载模块 | 这个步骤可以为了之后的块设备、dm、fs 提供模块依赖。 └─ 5. 最关键的一步 执行 DoFirstStageMountDoFirstStageMount (AOSP14)DoFirstStageMount的本质就是uevented、SELinux、SecondStage、Zygote、System_Server都还没起来之前由 First Stage Init 自己读 fstab创建设备节点建立dynamic-partition/snapshot/dm-verity设备并把 /system, /vendor, /product, /metadata 等 early 分区挂好保证/system/bin/initandselinue_setup能够完整执行。DoFirstStageMount ├─ FirstStageMount::Create 创建 FirstStageMount 对象 | ├─ ReadFstabFromDt/ReadDefaultFstab: 优先从设备树读取若 DT 中不存在则走 default。正因此 fstab 中明确要求挂载的分区如 /system,/vendor,/product 会被first stage处理 | └─ 创建 FirstStageMountVBootV2: 根据 avb flag / DT vbmeta 选择 VBootV2 | ├─ DoCreateDevices 挂载前的准备 | ├─ InitDevices: 收集 First Stage Mount 所需的物理分区、super分区、vbmeta分区然后创建/dev/block节点。初始化device-mappersuper物理设备及first stage所需物理分区。 | ├─ 优先挂载 /metadata: 必须早于动态分区 snapshot | ├─ CreateLogicalPartitions: 创建逻辑分区,若 fstab 中有 logical flag即视为启用dynamic partitions会判断创建logical snapshot分区。 | ├─ DoFirstStageMount | ├─ MountPartions: 核心挂载流程 | | ├─ TrySwitchSystemAsBoot: 处理/system特殊性 | | | ├─ UseDsuIfPresent: 若当前需要boot GSU/GKI会把fstab转换到DSU镜像。 | | | ├─ PreloadAvbKeys: 在切root之前预读ramdisk上的AVB key因为在切到/system时原来的ramdisk可能会不可见。 | | | └─ 查找/system fstab entry: 若fstab中有/system则先挂载/system再SwitchRoot(/system) | | └─ MountPartition (other first_stage_mount 条目) | | ├─/system前面已处理跳过 | | ├─overlay: 延后处理 | | └─emmc: emmc是raw partition条目不需要实际的mountemmc是用AVB链式验证的时候探测的。 Android 11: DoFirstStageMount ├─ InitDevices └─ MountPartitions ├─ metadata ├─ logical partitions └─ normal mounts对比 AOSP14 平台Android 11 版本把DoCreateDevices的职责直接内联到了MountPartitions()的前半部分。编译产物对于 RK3568 AOSP11 平台first_stage_init.cpp实际上编译进的是init_first_stage并且BOARD_BOOT_HEADER_VERSION : 2 BOARD_USES_AB_IMAGE : false BOARD_ROCKCHIP_VIRTUAL_AB_ENABLE : false ... BOARD_MKBOOTIMG_ARGS --second $(TARGET_PREBUILT_RESOURCE)其中BOARD_BOOT_HEADER_VERSION: 2表示使用 Android Boot Image Header v2 格式# Are we building a vendor boot image BUILDING_VENDOR_BOOT_IMAGE : ifdef BOARD_BOOT_HEADER_VERSION ifneq ($(call math_gt_or_eq,$(BOARD_BOOT_HEADER_VERSION),3),) ifneq ($(TARGET_NO_VENDOR_BOOT),true) BUILDING_VENDOR_BOOT_IMAGE : true endif endif endif明确配置BOARD_BOOT_HEADER_VERSION ≥ 3的时候才会设置BUILDING_VENDOR_BOOT_IMAGE为 true即配置为 2 的时候不会生成vendor_boot.img。Header 小于 3 的时候ramdisk放在boot.img大于等于 3 的时候进入vendor_boot镜像构建逻辑。