欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

安卓文件系统挂载的流程

最编程 2024-01-06 21:14:53
...

1、init进程

system/core/init/man.cpp

int main(int argc, char** argv) {
#if __has_feature(address_sanitizer)
    __asan_set_error_report_callback(AsanReportCallback);
#endif
    // Boost prio which will be restored later
    setpriority(PRIO_PROCESS, 0, -20);
    if (!strcmp(basename(argv[0]), "ueventd")) {
        return ueventd_main(argc, argv);
    }
if (argc > 1) {
        if (!strcmp(argv[1], "subcontext")) {
            android::base::InitLogging(argv, &android::base::KernelLogger);
            const BuiltinFunctionMap& function_map = GetBuiltinFunctionMap();

            return SubcontextMain(argc, argv, &function_map);
        }
if (!strcmp(argv[1], "selinux_setup")) {
    //权限相关
            return SetupSelinux(argv);
        }

        if (!strcmp(argv[1], "second_stage")) {
        //第二阶段
            return SecondStageMain(argc, argv);
        }
    }
//第一阶段
 return FirstStageMain(argc, argv);
}    

2、加载开机脚本init.rc

/system/core/init/init.cpp

int SecondStageMain(int argc, char** argv) {
......
//加载开机脚本init.rc
LoadBootScripts(am, sm);
......
} 

解析脚本:

static void LoadBootScripts(ActionManager& action_manager, ServiceList& service_list) {
    Parser parser = CreateParser(action_manager, service_list);

    std::string bootscript = GetProperty("ro.boot.init_rc", "");
    if (bootscript.empty()) {
        parser.ParseConfig("/system/etc/init/hw/init.rc");
        if (!parser.ParseConfig("/system/etc/init")) {
            late_import_paths.emplace_back("/system/etc/init");
        }
// late_import is available only in Q and earlier release. As we don't
        // have system_ext in those versions, skip late_import for system_ext.
        parser.ParseConfig("/system_ext/etc/init");
        if (!parser.ParseConfig("/vendor/etc/init")) {
            late_import_paths.emplace_back("/vendor/etc/init");
        }
if (!parser.ParseConfig("/odm/etc/init")) {
            late_import_paths.emplace_back("/odm/etc/init");
        }
        if (!parser.ParseConfig("/product/etc/init")) {
            late_import_paths.emplace_back("/product/etc/init");
        }
} else {
        parser.ParseConfig(bootscript);
    }
}

3、mount_all去挂载分区mount的阶段分为mount_all --early和mount_all --late

/device/qcom/sc171/init.target.rc

on fs
    start hwservicemanager
    mkdir /mnt/vendor/spunvm 0660 system system
    mount_all --early
    chown root system /mnt/vendor/persist
    chmod 0771 /mnt/vendor/persist
    restorecon_recursive /mnt/vendor/persist
    mkdir /mnt/vendor/persist/data 0700 system system

on fs && property:ro.boot.product.vendor.sku=lahaina
    mkdir /mnt/vendor/spunvm 0660 system system
    wait /dev/block/bootdevice/by-name/spunvm
    mount vfat /dev/block/bootdevice/by-name/spunvm /mnt/vendor/spunvm rw noatime shortname=lower,uid=1000,gid=1000,dmask=007,fmask=007,context=u:object_r:vendor_spunvm_file:s0

on post-fs
    # set RLIMIT_MEMLOCK to 64MB
    setrlimit 8 67108864 67108864

on late-fs
    wait_for_prop hwservicemanager.ready true
    #exec_start wait_for_keymaster
    mount_all --late

/system/core/init/buildins.cpp

{"mount_all",               {0,     kMax, {false,  do_mount_all}}},
{"mount",                   {3,     kMax, {false,  do_mount}}},
{"perform_apex_config",     {0,     0,    {false,  do_perform_apex_config}}},
{"umount",                  {1,     1,    {false,  do_umount}}},
{"umount_all",              {0,     1,    {false,  do_umount_all}}}, 

调用do_mount_all

static Result<void> do_mount_all(const BuiltinArguments& args) {
    auto mount_all = ParseMountAll(args.args);
    if (!mount_all.ok()) return mount_all.error();

    const char* prop_post_fix = "default";
 bool queue_event = true;
    if (mount_all->mode == MOUNT_MODE_EARLY) {
        prop_post_fix = "early";
        queue_event = false;
    } else if (mount_all->mode == MOUNT_MODE_LATE) {
        prop_post_fix = "late"
}

    std::string prop_name = "ro.boottime.init.mount_all."s + prop_post_fix;
    android::base::Timer t;

    Fstab fstab;
    if (mount_all->fstab_path.empty()) {
        if (!ReadDefaultFstab(&fstab)) {
            return Error() << "Could not read default fstab";
        } 
} else {
        if (!ReadFstabFromFile(mount_all->fstab_path, &fstab)) {
            return Error() << "Could not read fstab";
        }
    }
//mount所有分区
    auto mount_fstab_result = fs_mgr_mount_all(&fstab, mount_all->mode);
    SetProperty(prop_name, std::to_string(t.duration().count()));

4、调用fs_mgr_mount_all回去解析fstab.default文件去挂载相应的分区

/system/core/fs_mgr/fs_mgr.cpp

fstab.defalut---/device/qcom/sc171/default/fstab.default

 5、mount_all --early和mount_all --late

分区是在early的阶段挂载还是在late取决于fstab.default中对于每个分区fs_mgr_flags中first_stage_mount和latemount属性的配置,

  • 如果配置了first_stage_mount则在early的阶段进行挂载
  • 配置了latemount则在late阶段挂载
#<src>                                                 <mnt_point>            <type>  <mnt_flags and options>                            <fs_mgr_flags>
system                                                  /system                ext4    ro,barrier=1,discard                                 wait,slotselect,avb=vbmeta_system,logical,first_stage_mount,avb_keys=/avb/q-gsi.avbpubkey:/avb/r-gsi.avbpubkey:/avb/s-gsi.avbpubkey
system_ext                                              /system_ext            ext4    ro,barrier=1,discard                                 wait,slotselect,avb=vbmeta_system,logical,first_stage_mount
product                                                 /product               ext4    ro,barrier=1,discard                                 wait,slotselect,avb=vbmeta_system,logical,first_stage_mount
vendor                                                  /vendor                ext4    ro,barrier=1,discard                                 wait,slotselect,avb,logical,first_stage_mount
odm                                                     /odm                   ext4    ro,barrier=1,discard                                 wait,slotselect,avb,logical,first_stage_mount
/dev/block/by-name/metadata                             /metadata              ext4    noatime,nosuid,nodev,discard                         wait,check,formattable,first_stage_mount
/dev/block/bootdevice/by-name/persist                   /mnt/vendor/persist    ext4    noatime,nosuid,nodev,barrier=1                       wait
/dev/block/bootdevice/by-name/userdata                  /data                  ext4    noatime,nosuid,nodev,barrier=1,noauto_da_alloc,discard    latemount,wait,formattable,encryptable=footer,quota,reservedsize=128M
/dev/block/bootdevice/by-name/misc                      /misc                  emmc    defaults                                             defaults
/devices/platform/soc/8804000.sdhci/mmc_host*           /storage/sdcard1       vfat    nosuid,nodev                                         wait,voldmanaged=sdcard1:auto,encryptable=footer
/devices/platform/soc/1da4000.ufshc_card/host*          /storage/sdcard1       vfat    nosuid,nodev                                         wait,voldmanaged=sdcard1:auto,encryptable=footer
/*.ssusb/*.dwc3/xhci-hcd.*.auto*   /storage/usbotg        vfat    nosuid,nodev                                         wait,voldmanaged=usbotg:auto
/devices/platform/soc/*.hsusb/*.dwc3/xhci-hcd.*.auto*   /storage/usbotg        vfat    nosuid,nodev                                         wait,voldmanaged=usbotg:auto
/dev/block/bootdevice/by-name/modem                     /vendor/firmware_mnt   vfat    ro,shortname=lower,uid=1000,gid=1000,dmask=227,fmask=337,context=u:object_r:firmware_file:s0 wait,slotselect
/dev/block/bootdevice/by-name/dsp                       /vendor/dsp            ext4    ro,nosuid,nodev,barrier=1                            wait,slotselect
/dev/block/bootdevice/by-name/bluetooth                 /vendor/bt_firmware    vfat    ro,shortname=lower,uid=1002,gid=3002,dmask=227,fmask=337,context=u:object_r:bt_firmware_file:s0 wait,slotselect
/dev/block/bootdevice/by-name/qmcs                      /mnt/vendor/qmcs       vfat    noatime,nosuid,nodev,context=u:object_r:vendor_qmcs_file:s0   wait,check,formattable
/dev/block/bootdevice/by-name/data2                     /mnt/data2              ext4    discard                                              latemount
/dev/block/bootdevice/by-name/data3                     /mnt/data3              ext4    discard                                              latemount