ANDROID 11 文件系统挂载
源碼:http://aospxref.com/?
系統啟動過程可以參看?Android Init 進程啟動流程研究
第一階段啟動??First stage init
init 的main函數:
//system/core/init/main.cpp using namespace android::init;int main(int argc, char** argv) { #if __has_feature(address_sanitizer)__asan_set_error_report_callback(AsanReportCallback); #endifif (!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); //---> }跟蹤?FirstStageMain
///system/core/init/first_stage_init.cpp int FirstStageMain(int argc, char** argv) {if (REBOOT_BOOTLOADER_ON_PANIC) {InstallRebootSignalHandlers();}boot_clock::time_point start_time = boot_clock::now();std::vector<std::pair<std::string, int>> errors; #define CHECKCALL(x) \if ((x) != 0) errors.emplace_back(#x " failed", errno);// Clear the umask.umask(0);CHECKCALL(clearenv());CHECKCALL(setenv("PATH", _PATH_DEFPATH, 1));// Get the basic filesystem setup we need put together in the initramdisk// on / and then we'll let the rc file figure out the rest.CHECKCALL(mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755"));CHECKCALL(mkdir("/dev/pts", 0755));CHECKCALL(mkdir("/dev/socket", 0755));CHECKCALL(mount("devpts", "/dev/pts", "devpts", 0, NULL)); #define MAKE_STR(x) __STRING(x)CHECKCALL(mount("proc", "/proc", "proc", 0, "hidepid=2,gid=" MAKE_STR(AID_READPROC))); #undef MAKE_STR// Don't expose the raw commandline to unprivileged processes.CHECKCALL(chmod("/proc/cmdline", 0440));std::string cmdline;android::base::ReadFileToString("/proc/cmdline", &cmdline);gid_t groups[] = {AID_READPROC};CHECKCALL(setgroups(arraysize(groups), groups));CHECKCALL(mount("sysfs", "/sys", "sysfs", 0, NULL));CHECKCALL(mount("selinuxfs", "/sys/fs/selinux", "selinuxfs", 0, NULL));CHECKCALL(mknod("/dev/kmsg", S_IFCHR | 0600, makedev(1, 11)));if constexpr (WORLD_WRITABLE_KMSG) {CHECKCALL(mknod("/dev/kmsg_debug", S_IFCHR | 0622, makedev(1, 11)));}CHECKCALL(mknod("/dev/random", S_IFCHR | 0666, makedev(1, 8)));CHECKCALL(mknod("/dev/urandom", S_IFCHR | 0666, makedev(1, 9)));// This is needed for log wrapper, which gets called before ueventd runs.CHECKCALL(mknod("/dev/ptmx", S_IFCHR | 0666, makedev(5, 2)));CHECKCALL(mknod("/dev/null", S_IFCHR | 0666, makedev(1, 3)));// These below mounts are done in first stage init so that first stage mount can mount// subdirectories of /mnt/{vendor,product}/. Other mounts, not required by first stage mount,// should be done in rc files.// Mount staging areas for devices managed by vold// See storage config details at http://source.android.com/devices/storage/CHECKCALL(mount("tmpfs", "/mnt", "tmpfs", MS_NOEXEC | MS_NOSUID | MS_NODEV,"mode=0755,uid=0,gid=1000"));// /mnt/vendor is used to mount vendor-specific partitions that can not be// part of the vendor partition, e.g. because they are mounted read-write.CHECKCALL(mkdir("/mnt/vendor", 0755));// /mnt/product is used to mount product-specific partitions that can not be// part of the product partition, e.g. because they are mounted read-write.CHECKCALL(mkdir("/mnt/product", 0755));// /debug_ramdisk is used to preserve additional files from the debug ramdiskCHECKCALL(mount("tmpfs", "/debug_ramdisk", "tmpfs", MS_NOEXEC | MS_NOSUID | MS_NODEV,"mode=0755,uid=0,gid=0")); #undef CHECKCALLSetStdioToDevNull(argv);// Now that tmpfs is mounted on /dev and we have /dev/kmsg, we can actually// talk to the outside world...InitKernelLogging(argv);if (!errors.empty()) {for (const auto& [error_string, error_errno] : errors) {LOG(ERROR) << error_string << " " << strerror(error_errno);}LOG(FATAL) << "Init encountered errors starting first stage, aborting";}LOG(INFO) << "init first stage started!";auto old_root_dir = std::unique_ptr<DIR, decltype(&closedir)>{opendir("/"), closedir};if (!old_root_dir) {PLOG(ERROR) << "Could not opendir(\"/\"), not freeing ramdisk";}struct stat old_root_info;if (stat("/", &old_root_info) != 0) {PLOG(ERROR) << "Could not stat(\"/\"), not freeing ramdisk";old_root_dir.reset();}auto want_console = ALLOW_FIRST_STAGE_CONSOLE ? FirstStageConsole(cmdline) : 0;if (!LoadKernelModules(IsRecoveryMode() && !ForceNormalBoot(cmdline), want_console)) {if (want_console != FirstStageConsoleParam::DISABLED) {LOG(ERROR) << "Failed to load kernel modules, starting console";} else {LOG(FATAL) << "Failed to load kernel modules";}}if (want_console == FirstStageConsoleParam::CONSOLE_ON_FAILURE) {StartConsole();}if (ForceNormalBoot(cmdline)) {mkdir("/first_stage_ramdisk", 0755);// SwitchRoot() must be called with a mount point as the target, so we bind mount the// target directory to itself here.if (mount("/first_stage_ramdisk", "/first_stage_ramdisk", nullptr, MS_BIND, nullptr) != 0) {LOG(FATAL) << "Could not bind mount /first_stage_ramdisk to itself";}SwitchRoot("/first_stage_ramdisk");}// If this file is present, the second-stage init will use a userdebug sepolicy// and load adb_debug.prop to allow adb root, if the device is unlocked.if (access("/force_debuggable", F_OK) == 0) {std::error_code ec; // to invoke the overloaded copy_file() that won't throw.if (!fs::copy_file("/adb_debug.prop", kDebugRamdiskProp, ec) ||!fs::copy_file("/userdebug_plat_sepolicy.cil", kDebugRamdiskSEPolicy, ec)) {LOG(ERROR) << "Failed to setup debug ramdisk";} else {// setenv for second-stage init to read above kDebugRamdisk* files.setenv("INIT_FORCE_DEBUGGABLE", "true", 1);}}if (!DoFirstStageMount()) { //--->LOG(FATAL) << "Failed to mount required partitions early ...";}struct stat new_root_info;if (stat("/", &new_root_info) != 0) {PLOG(ERROR) << "Could not stat(\"/\"), not freeing ramdisk";old_root_dir.reset();}if (old_root_dir && old_root_info.st_dev != new_root_info.st_dev) {FreeRamdisk(old_root_dir.get(), old_root_info.st_dev);}SetInitAvbVersionInRecovery();setenv(kEnvFirstStageStartedAt, std::to_string(start_time.time_since_epoch().count()).c_str(),1);const char* path = "/system/bin/init";const char* args[] = {path, "selinux_setup", nullptr};auto fd = open("/dev/kmsg", O_WRONLY | O_CLOEXEC);dup2(fd, STDOUT_FILENO);dup2(fd, STDERR_FILENO);close(fd);execv(path, const_cast<char**>(args));// execv() only returns if an error happened, in which case we// panic and never fall through this conditional.PLOG(FATAL) << "execv(\"" << path << "\") failed";return 1; }DoFirstStageMount
//system/core/init/first_stage_mount.cpp // Public functions // ---------------- // Mounts partitions specified by fstab in device tree. bool DoFirstStageMount() {// Skips first stage mount if we're in recovery mode.if (IsRecoveryMode()) {LOG(INFO) << "First stage mount skipped (recovery mode)";return true;}std::unique_ptr<FirstStageMount> handle = FirstStageMount::Create();if (!handle) {LOG(ERROR) << "Failed to create FirstStageMount";return false;}return handle->DoFirstStageMount(); }std::unique_ptr<FirstStageMount> FirstStageMount::Create() {auto fstab = ReadFirstStageFstab();if (IsDtVbmetaCompatible(fstab)) {return std::make_unique<FirstStageMountVBootV2>(std::move(fstab));} else {return std::make_unique<FirstStageMountVBootV1>(std::move(fstab));} }static Fstab ReadFirstStageFstab() {Fstab fstab;//bool ReadFstabFromDt(Fstab* fstab, bool log = true);if (!ReadFstabFromDt(&fstab)) { //???if (ReadDefaultFstab(&fstab)) { //???fstab.erase(std::remove_if(fstab.begin(), fstab.end(),[](const auto& entry) {return !entry.fs_mgr_flags.first_stage_mount;}),fstab.end());} else {LOG(INFO) << "Failed to fstab for first stage mount";}}return fstab; }bool FirstStageMount::DoFirstStageMount() {if (!IsDmLinearEnabled() && fstab_.empty()) {// Nothing to mount.LOG(INFO) << "First stage mount skipped (missing/incompatible/empty fstab in device tree)";return true;}if (!InitDevices()) return false;if (!MountPartitions()) return false;return true; }bool FirstStageMount::InitDevices() {std::set<std::string> devices;GetSuperDeviceName(&devices);if (!GetDmVerityDevices(&devices)) {return false;}if (!InitRequiredDevices(std::move(devices))) {return false;}if (IsDmLinearEnabled()) {auto super_symlink = "/dev/block/by-name/"s + super_partition_name_;if (!android::base::Realpath(super_symlink, &super_path_)) {PLOG(ERROR) << "realpath failed: " << super_symlink;return false;}}return true; }void FirstStageMount::GetSuperDeviceName(std::set<std::string>* devices) {// Add any additional devices required for dm-linear mappings.if (!IsDmLinearEnabled()) {return;}devices->emplace(super_partition_name_); }FirstStageMount::FirstStageMount(Fstab fstab) : need_dm_verity_(false), fstab_(std::move(fstab)) {super_partition_name_ = fs_mgr_get_super_partition_name(); //??? }// Creates devices with uevent->partition_name matching ones in the given set. // Found partitions will then be removed from it for the subsequent member // function to check which devices are NOT created. bool FirstStageMount::InitRequiredDevices(std::set<std::string> devices) {//BlockDevInitializer block_dev_init_;//往/sys目錄下的所有設備發送uevent事件,創建device-mapper設備節點if (!block_dev_init_.InitDeviceMapper()) { //???return false;}if (devices.empty()) {return true;}//創建dts中的vbmeta,vbmeta_system,vbmeta_vendor,boot,super分區設備return block_dev_init_.InitDevices(std::move(devices)); //??? }由于對GetSuperDeviceName不太明白,搜到如下文章 android R啟動找不到super分區問題
//system/core/fs_mgr/fs_mgr_fstab.cpp // Returns fstab entries parsed from the device tree if they exist bool ReadFstabFromDt(Fstab* fstab, bool log) {std::string fstab_buf = ReadFstabFromDt();if (fstab_buf.empty()) {if (log) LINFO << __FUNCTION__ << "(): failed to read fstab from dt";return false;}std::unique_ptr<FILE, decltype(&fclose)> fstab_file(fmemopen(static_cast<void*>(const_cast<char*>(fstab_buf.c_str())),fstab_buf.length(), "r"), fclose);if (!fstab_file) {if (log) PERROR << __FUNCTION__ << "(): failed to create a file stream for fstab dt";return false;}if (!ReadFstabFile(fstab_file.get(), false, fstab)) {if (log) {LERROR << __FUNCTION__ << "(): failed to load fstab from kernel:" << std::endl<< fstab_buf;}return false;}#ifndef NO_SKIP_MOUNTSkipMountingPartitions(fstab); #endifreturn true; }std::string ReadFstabFromDt() {if (!is_dt_compatible() || !IsDtFstabCompatible()) {return {};}//const std::string kDefaultAndroidDtDir("/proc/device-tree/firmware/android/");//get_android_dt_dir 獲取kernel命令行 "androidboot.android_dt_dir" 的鍵值,沒有的話用kDefaultAndroidDtDir//kernel cmdline ----> cat /proc/cmdlinestd::string fstabdir_name = get_android_dt_dir() + "/fstab";std::unique_ptr<DIR, int (*)(DIR*)> fstabdir(opendir(fstabdir_name.c_str()), closedir);if (!fstabdir) return {}; //553沒有dt fstab 直接返回dirent* dp;// Each element in fstab_dt_entries is <mount point, the line format in fstab file>.std::vector<std::pair<std::string, std::string>> fstab_dt_entries;while ((dp = readdir(fstabdir.get())) != NULL) {// skip over name, compatible and .if (dp->d_type != DT_DIR || dp->d_name[0] == '.') continue;// create <dev> <mnt_point> <type> <mnt_flags> <fsmgr_flags>\nstd::vector<std::string> fstab_entry;std::string file_name;std::string value;// skip a partition entry if the status property is present and not set to okfile_name = android::base::StringPrintf("%s/%s/status", fstabdir_name.c_str(), dp->d_name);if (ReadDtFile(file_name, &value)) {if (value != "okay" && value != "ok") {LINFO << "dt_fstab: Skip disabled entry for partition " << dp->d_name;continue;}}file_name = android::base::StringPrintf("%s/%s/dev", fstabdir_name.c_str(), dp->d_name);if (!ReadDtFile(file_name, &value)) {LERROR << "dt_fstab: Failed to find device for partition " << dp->d_name;return {};}fstab_entry.push_back(value);std::string mount_point;file_name =android::base::StringPrintf("%s/%s/mnt_point", fstabdir_name.c_str(), dp->d_name);if (ReadDtFile(file_name, &value)) {LINFO << "dt_fstab: Using a specified mount point " << value << " for " << dp->d_name;mount_point = value;} else {mount_point = android::base::StringPrintf("/%s", dp->d_name);}fstab_entry.push_back(mount_point);file_name = android::base::StringPrintf("%s/%s/type", fstabdir_name.c_str(), dp->d_name);if (!ReadDtFile(file_name, &value)) {LERROR << "dt_fstab: Failed to find type for partition " << dp->d_name;return {};}fstab_entry.push_back(value);file_name = android::base::StringPrintf("%s/%s/mnt_flags", fstabdir_name.c_str(), dp->d_name);if (!ReadDtFile(file_name, &value)) {LERROR << "dt_fstab: Failed to find type for partition " << dp->d_name;return {};}fstab_entry.push_back(value);file_name = android::base::StringPrintf("%s/%s/fsmgr_flags", fstabdir_name.c_str(), dp->d_name);if (!ReadDtFile(file_name, &value)) {LERROR << "dt_fstab: Failed to find type for partition " << dp->d_name;return {};}fstab_entry.push_back(value);// Adds a fstab_entry to fstab_dt_entries, to be sorted by mount_point later.fstab_dt_entries.emplace_back(mount_point, android::base::Join(fstab_entry, " "));}// Sort fstab_dt entries, to ensure /vendor is mounted before /vendor/abc is attempted.std::sort(fstab_dt_entries.begin(), fstab_dt_entries.end(),[](const auto& a, const auto& b) { return a.first < b.first; });std::string fstab_result;for (const auto& [_, dt_entry] : fstab_dt_entries) {fstab_result += dt_entry + "\n";}return fstab_result; }// Loads the fstab file and combines with fstab entries passed in from device tree. bool ReadDefaultFstab(Fstab* fstab) {Fstab dt_fstab;ReadFstabFromDt(&dt_fstab, false);*fstab = std::move(dt_fstab);std::string default_fstab_path;// Use different fstab paths for normal boot and recovery boot, respectivelyif (access("/system/bin/recovery", F_OK) == 0) { //recovery 模式default_fstab_path = "/etc/recovery.fstab";} else { // normal bootdefault_fstab_path = GetFstabPath();}Fstab default_fstab;if (!default_fstab_path.empty()) {ReadFstabFromFile(default_fstab_path, &default_fstab);} else {LINFO << __FUNCTION__ << "(): failed to find device default fstab";}for (auto&& entry : default_fstab) {fstab->emplace_back(std::move(entry));}return !fstab->empty(); }// Identify path to fstab file. Lookup is based on pattern // fstab.<fstab_suffix>, fstab.<hardware>, fstab.<hardware.platform> in // folders /odm/etc, vendor/etc, or /. std::string GetFstabPath() {for (const char* prop : {"fstab_suffix", "hardware", "hardware.platform"}) {std::string suffix;//[ro.boot.hardware]: [HNR553T] 只有hardware滿足條件if (!fs_mgr_get_boot_config(prop, &suffix)) continue;for (const char* prefix : {"/odm/etc/fstab.", "/vendor/etc/fstab.", "/fstab."}) {std::string fstab_path = prefix + suffix;if (access(fstab_path.c_str(), F_OK) == 0) {return fstab_path;}}}return ""; }HNR553T:/proc/device-tree/firmware/android # ls
compatible ?name ?vbmeta
553 的dt沒有fstab
HNR553T:/proc/device-tree # find -name "fstab*"
HNR553T:/proc/device-tree # find -name "fstab"
HNR553T:/proc/device-tree # find -name "*fstab"
HNR553T:/ # cat /proc/cmdline
earlycon=sprd_serial,0x20210000,115200n8 console=ttyS1,115200n8 loglevel=1 init=/init root=/dev/ram0 rw printk.devkmsg=on pcie_ports=compat swiotlb=2560 androidboot.hardware=HNR553T androidboot.dtbo_idx=0 lcd_id=ID8756 lcd_name=lcd_ft8756_txd_mipi_hdplus lcd_base=b0000000 lcd_size=2400x1080 logo_bpix=32 androidboot.ddrsize=6144M androidboot.ddrsize.range=[6144,) androidboot.lwfq.type=-1 androidboot.auto.efuse=-1 androidboot.auto.chipid=UMS9620-AA ?sysdump_magic=80001000 sysdump_re_flag=1 ?androidboot.wdten=0 ?androidboot.dswdten=disable modem=shutdown ?androidboot.meid=1 ?recoverytype=0 ?androidboot.fuse=0 rfboard.id=1 rfhw.id=18432 crystal=5 32k.less=0 pcb.version=0 androidboot.pmic.chipid=7520 cpcmdline=end powerup_reason=Reboot ?androidboot.verifiedbootstate=orange androidboot.flash.locked=0 ?androidboot.serialno=40322211589811 buildvariant=userdebug androidboot.vbmeta.device=PARTUUID=1.0 androidboot.vbmeta.avb_version=1.1 androidboot.vbmeta.device_state=unlocked androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=42560 androidboot.vbmeta.digest=c6f2d4e0d5d12cf691b2968b844c245f73146227c028bcc91d375531b464f3cb androidboot.vbmeta.invalidate_on_error=yes androidboot.veritymode=enforcing androidboot.slot_suffix=_a androidboot.force_normal_boot=1 androidboot.boot_devices=soc/soc:ap-ahb/22000000.ufs bootcause="Reboot into normal" pwroffcause="device power down" charge.shutdown_rtc_time=-1 ?charge.charge_cycle=-1 ?charge.basp=-1 ?charge.total_mah=-1 ?androidboot.vendor.skip.init=0
[ro.boot.flash.locked]: [0]
[ro.boot.force_normal_boot]: [1]
[ro.boot.fuse]: [0]
[ro.boot.hardware]: [HNR553T]
[ro.boot.lwfq.type]: [-1]
HNR553T:/ # ls /odm/etc/fstab.*
ls: /odm/etc/fstab.*: No such file or directory
1|HNR553T:/ # ls /vendor/etc/fstab.*
/vendor/etc/fstab.HNR553T ? ? ?/vendor/etc/fstab.factorytest /vendor/etc/fstab.ums9620_2c11?/vendor/etc/fstab.P50 ? ? ? ? ?/vendor/etc/fstab.ums9520_haps ? ? ? ?/vendor/etc/fstab.ums9620_2h10?/vendor/etc/fstab.cali ? ? ? ? /vendor/etc/fstab.ums9520_haps_flash ?/vendor/etc/fstab.ums9620_2h10_car?/vendor/etc/fstab.charge_mode ?/vendor/etc/fstab.ums9620_1h10 ? ? ? ?/vendor/etc/fstab.ums9620_3c10?/vendor/etc/fstab.enableswap ? /vendor/etc/fstab.ums9620_2c10
HNR553T:/ # ls /fstab.*
ls: /fstab.*: No such file or directory
這樣就找到了唯一符合條件的:/vendor/etc/fstab.HNR553T
事實上,經過一星期的琢磨,這個結論是錯誤的:根據文檔提前裝載分區,提到“將恢復用作 ramdisk?的設備,第一階段 init 在裝載提前裝載分區之前將根操作切換到了?/first_stage_ramdisk,因此設備必須將?fstab?文件放在?$(TARGET_COPY_OUT_RECOVERY)/root/first_stage_ramdisk?中”,通過解包boot.img, 發現first_stage_ramdisk目錄下,沒有文件夾vendor,但可以可以找到“fstab.HNR553T”,這個文件才是第一階段要加載的fstab.
│ ?fstab.HNR553T
│ ?fstab.P50
│ ?fstab.ums9520_haps
│ ?fstab.ums9520_haps_flash
│ ?fstab.ums9620_1h10
│ ?fstab.ums9620_2c10
│ ?fstab.ums9620_2c11
│ ?fstab.ums9620_2h10
│ ?fstab.ums9620_2h10_car
│ ?fstab.ums9620_2h10_uob
│ ?fstab.ums9620_3c10
│
├─avb
│ ? ? ?q-gsi.avbpubkey
│ ? ? ?r-gsi.avbpubkey
│ ? ? ?s-gsi.avbpubkey
│
└─system
? ? └─bin
? ? ? ? ? ? e2fsck
/fstab.HNR553T?
#Dynamic partitions fstab file
#<dev> <mnt_point> <type> <mnt_flags options> ?<fs_mgr_flags>
system /system ext4 ro,barrier=1 wait,avb=vbmeta_system,logical,first_stage_mount,avb_keys=/avb/q-gsi.avbpubkey:/avb/r-gsi.avbpubkey:/avb/s-gsi.avbpubkey,slotselect
vendor /vendor ext4 ro,barrier=1 wait,avb=vbmeta_vendor,logical,first_stage_mount,slotselect
system_ext /system_ext ext4 ro,barrier=1 wait,avb=vbmeta_system_ext,logical,first_stage_mount,slotselect
product /product ext4 ro,barrier=1 wait,avb=vbmeta_product,logical,first_stage_mount,slotselect
/dev/block/by-name/metadata /metadata ? ?ext4 nodev,noatime,nosuid,errors=panic wait,formattable,first_stage_mount,check
HNR553T:/ # cat /vendor/etc/fstab.HNR553T
# Android fstab file.
# The filesystem that contains the filesystem checker binary (typically /system) cannot
# specify MF_CHECK, and must come before any filesystems that do specify MF_CHECK
# <src> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <mnt_point> ?<type> ?<mnt_flags and options> ? ? ? ? ? ? <fs_mgr_flags>
system /system ext4 ro,barrier=1 wait,logical,first_stage_mount,avb_keys=/avb/q-gsi.avbpubkey:/avb/r-gsi.avbpubkey:/avb/s-gsi.avbpubkey,slotselect
system_ext /system_ext ext4 ro,barrier=1 wait,logical,first_stage_mount,slotselect
vendor /vendor ext4 ro,barrier=1 wait,logical,first_stage_mount,slotselect
product /product ext4 ro,barrier=1 wait,logical,first_stage_mount,slotselect
/dev/block/by-name/userdata /data ? ? ? ?f2fs noatime,nosuid,nodev,discard,inline_xattr,inline_data,inlinecrypt,fsync_mode=nobarrier latemount,wait,fileencryption=aes-256-xts:aes-256-cts:v2+inlinecrypt_optimized,keydirectory=/metadata/vold/metadata_encryption,check,reservedsize=128M,checkpoint=fs,formattable
/dev/block/by-name/metadata /metadata ? ?ext4 nodev,noatime,nosuid,errors=panic wait,formattable,first_stage_mount,check
/devices/platform/soc/soc:ipa-apb/25100000.usb3/25100000.dwc3/xhci-hcd.*.auto/usb* ? ? ?auto ? ? ? ? vfat defaults voldmanaged=usbdisk:auto
/devices/platform/soc/soc:ap-ahb/22210000.sdio/mmc_host/mmc1/mmc1:*/block/mmcblk1 ? ? ?auto ? ? ? ? vfat defaults voldmanaged=sdcard0:auto,noemulatedsd
/dev/block/by-name/prodnv ? ?/mnt/vendor ext4 noatime,nosuid,nodev,nomblk_io_submit,noauto_da_alloc wait,check
/dev/block/by-name/cache ? ?/cache ? ? ? ext4 noatime,nosuid,nodev,nomblk_io_submit,noauto_da_alloc wait,check
# Should after mount prodnv for prodnv wholly occupying /mnt/vendor
/dev/block/by-name/socko /mnt/vendor/socko ext4 ro,noatime,nosuid,nodev,nomblk_io_submit,noauto_da_alloc wait,avb=socko,slotselect
/dev/block/by-name/odmko /mnt/vendor/odmko ext4 ro,noatime,nosuid,nodev,nomblk_io_submit,noauto_da_alloc wait,avb=odmko,slotselect
/dev/block/by-name/misc ? ? /misc ? ? ? ?emmc ? ?defaults ? ?defaults
#/dev/block/memdisk.0 ? ?/system ? ? ?ext4 rw,barrier=1 ? ? ? ? ? ? ? ? ? ? ? ? ?wait
#/dev/block/memdisk.1 ? ?/data ? ? ? ?ext4 noatime,nosuid,nodev,noauto_da_alloc,journal_async_commit,errors=panic wait
?
總結
以上是生活随笔為你收集整理的ANDROID 11 文件系统挂载的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Ajax上传文件及携带参数
- 下一篇: c语言话费查询系统,MTN CELL C