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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章