Android recovery分区表

写在前面

这篇文章以imx6q的android5.1为例,介绍recovery分区表的配置和加载

分区表加载

//bootable/recovery/roots.cpp
void load_volume_table()
{
    int i;
    int ret;

    fstab = fs_mgr_read_fstab("/etc/recovery.fstab");          //由此看见,recovery.fstab为recovery的分区表文件
    if (!fstab) {
        LOGE("failed to read /etc/recovery.fstab\n");
        return;
    }

    ret = fs_mgr_add_entry(fstab, "/tmp", "ramdisk", "ramdisk");
    if (ret < 0 ) {
        LOGE("failed to add /tmp entry to fstab\n");
        fs_mgr_free_fstab(fstab);
        fstab = NULL;
        return;
    }

    printf("recovery filesystem table\n");        //在/cache/recovery/last_log 文件中可以看到此log
    printf("=========================\n");
    for (i = 0; i < fstab->num_entries; ++i) {
        Volume* v = &fstab->recs[i];
        printf("  %d %s %s %s %lld\n", i, v->mount_point, v->fs_type,
               v->blk_device, v->length);
    }
    printf("\n");
}

recovery.fstab的生成

通过查看recovery的源码,知道了recovery加载的分区表是recovery.fstab,然后在device目录下进行查找,竟然没有找到。
一般编译recovery.img的指令只make recoveryimage,所以猜测分区表的加载可能是在Makefile中指定的,然后去查找/build/core/Makefile文件,果然。

......
$(INSTALLED_RECOVERYIMAGE_TARGET): $(MKBOOTFS) $(MKBOOTIMG) $(MINIGZIP) \
        $(INSTALLED_RAMDISK_TARGET) \
        $(INSTALLED_BOOTIMAGE_TARGET) \
        $(recovery_binary) \
        $(recovery_initrc) $(recovery_sepolicy) $(recovery_kernel) \
        $(INSTALLED_2NDBOOTLOADER_TARGET) \
        $(recovery_build_prop) $(recovery_resource_deps) \
        $(recovery_fstab) \
        $(RECOVERY_INSTALL_OTA_KEYS)
    @echo ----- Making recovery image ------
    $(hide) rm -rf $(TARGET_RECOVERY_OUT)
    $(hide) mkdir -p $(TARGET_RECOVERY_OUT)
    $(hide) mkdir -p $(TARGET_RECOVERY_ROOT_OUT)/etc $(TARGET_RECOVERY_ROOT_OUT)/tmp
    @echo Copying baseline ramdisk...
    $(hide) cp -R $(TARGET_ROOT_OUT) $(TARGET_RECOVERY_OUT)
    @echo Modifying ramdisk contents...
    $(hide) rm -f $(TARGET_RECOVERY_ROOT_OUT)/init*.rc
    $(hide) cp -f $(recovery_initrc) $(TARGET_RECOVERY_ROOT_OUT)/
    $(hide) rm -f $(TARGET_RECOVERY_ROOT_OUT)/sepolicy
    $(hide) cp -f $(recovery_sepolicy) $(TARGET_RECOVERY_ROOT_OUT)/sepolicy
    $(hide) -cp $(TARGET_ROOT_OUT)/init.recovery.*.rc $(TARGET_RECOVERY_ROOT_OUT)/
    $(hide) cp -f $(recovery_binary) $(TARGET_RECOVERY_ROOT_OUT)/sbin/
    $(hide) mkdir -p $(TARGET_RECOVERY_ROOT_OUT)/res
    $(hide) rm -rf $(TARGET_RECOVERY_ROOT_OUT)/res/*
    $(hide) cp -rf $(recovery_resources_common)/* $(TARGET_RECOVERY_ROOT_OUT)/res
    $(hide) cp -f $(recovery_font) $(TARGET_RECOVERY_ROOT_OUT)/res/images/font.png
    $(hide) $(foreach item,$(recovery_resources_private), \
      cp -rf $(item) $(TARGET_RECOVERY_ROOT_OUT)/)
    $(hide) $(foreach item,$(recovery_fstab), \
      cp -f $(item) $(TARGET_RECOVERY_ROOT_OUT)/etc/recovery.fstab)          //可以知道是拷贝$(recovery_fstab)这个文件为recovery/root/etc/recovery.fstab
    $(hide) cp $(RECOVERY_INSTALL_OTA_KEYS) $(TARGET_RECOVERY_ROOT_OUT)/res/keys
    $(hide) cat $(INSTALLED_DEFAULT_PROP_TARGET) $(recovery_build_prop) \
            > $(TARGET_RECOVERY_ROOT_OUT)/default.prop
    $(hide) $(MKBOOTFS) $(TARGET_RECOVERY_ROOT_OUT) | $(MINIGZIP) > $(recovery_ramdisk)
    for dtsplat in $(TARGET_BOARD_DTS_CONFIG); do \
        DTS_PLATFORM=`echo $$dtsplat | cut -d':' -f1`; \
        DTS_BOARD=`echo $$dtsplat | cut -d':' -f2`; \
  ......

然后通过$(info xxx)这个函数再makefile中进行打印,查找recovery_fstab的定义,发现recovery_fstab是由变量TARGET_RECOVERY_FSTAB决定的

ifeq ($(TARGET_USERIMAGES_USE_UBIFS),true)
ifdef TARGET_RECOVERY_FSTAB
recovery_fstab := $(TARGET_RECOVERY_FSTAB)
else
recovery_fstab := $(strip $(wildcard $(TARGET_DEVICE_DIR)/recovery_nand.fstab))
endif
else
ifdef TARGET_RECOVERY_FSTAB
recovery_fstab := $(TARGET_RECOVERY_FSTAB)
else
recovery_fstab := $(strip $(wildcard $(TARGET_DEVICE_DIR)/recovery.fstab))
endif
endif

然后去查找TARGET_RECOVERY_FSTAB这个变量,发现是在device/fsl/platform中定义的

ifeq ($(BUILD_TARGET_DEVICE),sd)
ADDITIONAL_BUILD_PROPERTIES += \
                        ro.boot.storage_type=sd
ifneq ($(BUILD_TARGET_FS),f2fs)
TARGET_RECOVERY_FSTAB = device/fsl/sabresd_6dq/fstab_sd.freescale
# build for ext4
PRODUCT_COPY_FILES +=   \
    device/fsl/sabresd_6dq/fstab_sd.freescale:root/fstab.freescale
else
TARGET_RECOVERY_FSTAB = device/fsl/sabresd_6dq/fstab_sd-f2fs.freescale
# build for f2fs
PRODUCT_COPY_FILES +=   \
    device/fsl/sabresd_6dq/fstab_sd-f2fs.freescale:root/fstab.freescale
endif # BUILD_TARGET_FS
else
ADDITIONAL_BUILD_PROPERTIES += \
                        ro.boot.storage_type=emmc
ifneq ($(BUILD_TARGET_FS),f2fs)
#TARGET_RECOVERY_FSTAB = device/fsl/sabresd_6dq/fstab.freescale   //原路径
TARGET_RECOVERY_FSTAB = bootable/recovery/etc/fstab.freescale     //recovery的分区表和正常启动的分区表设置为为不同文件
# build for ext4
PRODUCT_COPY_FILES +=   \
    device/fsl/sabresd_6dq/fstab.freescale:root/fstab.freescale         
else
TARGET_RECOVERY_FSTAB = device/fsl/sabresd_6dq/fstab-f2fs.freescale
# build for f2fs
PRODUCT_COPY_FILES +=   \
    device/fsl/sabresd_6dq/fstab-f2fs.freescale:root/fstab.freescale
endif # BUILD_TARGET_FS
endif # BUILD_TARGET_DEVICE

从上面可以看出,recovery和正常启动的分区表是一样的,但是对udisk和sd卡的挂载在正常启动中是好的,在recovery中无法挂载,所以我把recovery的分区表独立出来,然后udisk的挂载设置为sda4.

这里提一下正常启动时,分区表的加载
大家都知道,kernel加载结束后,会根据init.rc进行各个”服务”的启动,init.rc中有一项关于fs文件系统的”服务”

//device/fsl/sabresd_6dq/init.rc     路径
on fs
# mount ext4 partitions
    mount_all /fstab.freescale

你可能感兴趣的:(Android recovery分区表)