android usb mass storage EMMC转化为SD卡(四)

在/etc下有一个重要的文件vold.fstab. system/vold/main.cpp会解析这个文件,new出DirectVolume对象.并加入到VolumeManager里统一管理.

所以我们需要在这里加入我们的EMMC分区

## Vold 2.0 fstab for HTC Dream or Sapphire
#
## - San Mehat ([email protected])
## 

#######################
## Regular device mount
##
## Format: dev_mount <label> <mount_point> <part> <sysfs_path1...> 
## label        - Label for the volume
## mount_point  - Where the volume will be mounted
## part         - Partition # (1 based), or 'auto' for first usable partition.
## <sysfs_path> - List of sysfs paths to source devices
######################

# Mounts the first usable partition of the specified device
dev_mount sdcardext /mnt/sdcard/sdcard_ext auto /devices/platform/sdhc.0

# Internal SDcard
dev_mount sdcard /mnt/sdcard 7 /devices/platform/sdhc.2/mmc_host/mmc0

#Mount Otg Udisk
dev_mount udisk /mnt/udisk auto /devices/platform/otg.


Internal SDcard部分是自己手动加的,dev_mount是动作.  sdcard是标签 , /mnt/sdcard是挂载点. 7是分区号(如果是第一个分区用auto即可). 后面是sysfs中代表的设备.


源代码修改部分太长了.贴一下diff文件

MountService.java文件

diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java
index 419d3b9..23dcb0f 100644 (file)
--- a/services/java/com/android/server/MountService.java
+++ b/services/java/com/android/server/MountService.java
@@ -1014,7 +1014,7 @@ class MountService extends IMountService.Stub
         }
 
         final String path = Environment.getExternalStorageDirectory().getPath();
-        final String pathext = "/mnt/sdcard/sdcard_ext";
+        final String pathext = Environment.getExternalStorageDirectory().getPath() + "/sdcard_ext";
         if (avail == false && getVolumeState(path).equals(Environment.MEDIA_SHARED)) {
             /*
              * USB mass storage disconnected while enabled
@@ -1328,7 +1328,7 @@ class MountService extends IMountService.Stub
          * If the volume is mounted and we're enabling then unmount it
          */
         String path = Environment.getExternalStorageDirectory().getPath();
-        String pathext = "/mnt/sdcard/sdcard_ext";
+        String pathext = Environment.getExternalStorageDirectory().getPath() + "/sdcard_ext";
         String vs = getVolumeState(path);
         String method = "ums";
         if (enable && vs.equals(Environment.MEDIA_MOUNTED)) {
@@ -1401,17 +1401,38 @@ class MountService extends IMountService.Stub
     }
 
     public int mountVolume(String path) {
-        validatePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
 
+               String pathext = Environment.getExternalStorageDirectory().getPath() + "/sdcard_ext";
+               int mountcode;
+        
+        validatePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
+               
         waitForReady();
-        return doMountVolume(path);
+               mountcode = doMountVolume(path);
+               if (mountcode != StorageResultCode.OperationSucceeded) {
+                       Slog.d(TAG, "Failed to remount " + path +
+                        " when mount externalstorage ");
+                /*
+                 * Even though the mount failed, the unshare didn't so don't indicate an error.
+                 * The mountVolume() call will have set the storage state and sent the necessary
+                 * broadcasts.
+                 */
+                       return mountcode;
+        }
+               if(Environment.getExternalStorageDirectory().getPath().compareTo(path) == 0)
+               {
+                       Slog.d(TAG, "Mount internal sdcard success path : " + path + "then ready to mount external sdcard");
+                       mountcode = doMountVolume(pathext);
+               }        
+               return mountcode;
     }
 
     public void unmountVolume(String path, boolean force, boolean removeEncryption) {
         validatePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
         waitForReady();
-
+               String pathext = Environment.getExternalStorageDirectory().getPath() + "/sdcard_ext";
         String volState = getVolumeState(path);
+               Slog.i(TAG, "Environment ExternalStorage is  " + Environment.getExternalStorageDirectory().getPath());
         if (DEBUG_UNMOUNT) {
             Slog.i(TAG, "Unmounting " + path
                     + " force = " + force
@@ -1425,7 +1446,16 @@ class MountService extends IMountService.Stub
             // TODO return valid return code when adding observer call back.
             return;
         }
-        UnmountCallBack ucb = new UnmountCallBack(path, force, removeEncryption);
+               Slog.i(TAG, "Unmounting " + path
+                    + " force = " + force
+                    + " removeEncryption = " + removeEncryption);
+               UnmountCallBack ucb = new UnmountCallBack(path, force, removeEncryption);
+               if(Environment.getExternalStorageDirectory().getPath().compareTo(path) == 0)
+               {
+                       Slog.d(TAG, "Unmounting " + path + " must first unmount external sd " + pathext);
+               UnmountCallBack ucbext = new UnmountCallBack(pathext, force, removeEncryption);
+               mHandler.sendMessage(mHandler.obtainMessage(H_UNMOUNT_PM_UPDATE, ucbext));
+               }
         mHandler.sendMessage(mHandler.obtainMessage(H_UNMOUNT_PM_UPDATE, ucb));
     }
这里的修改主要就是添加对mount和unmount的顺序处理.

DirectVolume.h文件

diff --git a/DirectVolume.h b/DirectVolume.h
index de1ed8b..3af15eb 100644 (file)
--- a/DirectVolume.h
+++ b/DirectVolume.h
@@ -21,13 +21,13 @@
 
 #include "Volume.h"
 
-#define MAX_PARTS 4
+#define MAX_PARTS 12
 
 typedef android::List<char *> PathCollection;
 
 class DirectVolume : public Volume {
 public:
-    static const int MAX_PARTITIONS = 4;
+    static const int MAX_PARTITIONS = 12;
 protected:
     PathCollection *mPaths;
     int            mDiskMajor

android原生的默认最大分区数是4,这里需要修改为一个大于7的数.否则vold取分区表数组的时候会越界.

Volume.cpp文件

diff --git a/Volume.cpp b/Volume.cpp
index 2ff7d1d..6bf8935 100644 (file)
--- a/Volume.cpp
+++ b/Volume.cpp
@@ -290,7 +290,7 @@ int Volume::mountVol() {
     int n, i, rc = 0;
     char errmsg[255];
     const char* externalStorage = getenv("EXTERNAL_STORAGE");
-    bool primaryStorage = externalStorage && !strcmp(getMountpoint(), externalStorage);
+    bool primaryStorage = externalStorage && (!strcmp(getMountpoint(), externalStorage) || (!strcmp(getMountpoint(), "/mnt/sdcard/sdcard_ext")));
     char decrypt_state[PROPERTY_VALUE_MAX];
     char crypto_state[PROPERTY_VALUE_MAX];
     char encrypt_progress[PROPERTY_VALUE_MAX];
@@ -394,16 +394,20 @@ int Volume::mountVol() {
         errno = 0;
         setState(Volume::State_Checking);
 
-        if (Fat::check(devicePath)) {
-            if (errno == ENODATA) {
-                SLOGW("%s does not contain a FAT filesystem\n", devicePath);
-                continue;
+        if (MINOR(deviceNodes[i]) == 0) {
+            SLOGE("hijack the org proceed ");
+        } else {
+            if (Fat::check(devicePath)) {
+                if (errno == ENODATA) {
+                    SLOGW("%s does not contain a FAT filesystem\n", devicePath);
+                    continue;
+                }
+                errno = EIO;
+                /* Badness - abort the mount */
+                SLOGE("%s failed FS checks (%s)", devicePath, strerror(errno));
+                setState(Volume::State_Idle);
+                return -1;
             }
-            errno = EIO;
-            /* Badness - abort the mount */
-            SLOGE("%s failed FS checks (%s)", devicePath, strerror(errno));
-            setState(Volume::State_Idle);
-            return -1;
         }

需要修改一下deviceNodes数组中的元素为空的情况.如果为空就没必要进行FAT文件格式的检查.以免通知栏提示NOFS标签.

VolumeManager.cpp文件

diff --git a/VolumeManager.cpp b/VolumeManager.cpp
index 5cc1f39..d5e6a6e 100644 (file)
--- a/VolumeManager.cpp
+++ b/VolumeManager.cpp
@@ -46,6 +46,8 @@
 
 #define MASS_STORAGE_FILE_PATH  "/sys/class/android_usb/android0/f_mass_storage/lun/file"
 
+#define EXT_MASS_STORAGE_FILE_PATH  "/sys/class/android_usb/android0/f_mass_storage/lun2/file"
+
 VolumeManager *VolumeManager::sInstance = NULL;
 
 VolumeManager *VolumeManager::Instance() {
@@ -928,7 +930,6 @@ int VolumeManager::shareVolume(const char *label, const char *method) {
         errno = ENOENT;
         return -1;
     }
-
     /*
      * Eventually, we'll want to support additional share back-ends,
      * some of which may work while the media is mounted. For now,
@@ -967,16 +968,30 @@ int VolumeManager::shareVolume(const char *label, const char *method) {
     snprintf(nodepath,
              sizeof(nodepath), "/dev/block/vold/%d:%d",
              MAJOR(d), MINOR(d));
+    if (strcmp(label, "/mnt/sdcard")) {
+        SLOGE("ready to share external sdcard");;
+        if ((fd = open(EXT_MASS_STORAGE_FILE_PATH, O_WRONLY)) < 0) {
+             SLOGE("Unable to open ums lun2 file (%s)", strerror(errno));
+             return -1;
+        }
 
-    if ((fd = open(MASS_STORAGE_FILE_PATH, O_WRONLY)) < 0) {
-        SLOGE("Unable to open ums lunfile (%s)", strerror(errno));
-        return -1;
-    }
+        if (write(fd, nodepath, strlen(nodepath)) < 0) {
+            SLOGE("Unable to write to ums lun2 file (%s)", strerror(errno));
+            close(fd);
+            return -1;
+        }
+    } else {
+        SLOGE("ready to share internal sdcard");
+        if ((fd = open(MASS_STORAGE_FILE_PATH, O_WRONLY)) < 0) {
+             SLOGE("Unable to open ums lunfile (%s)", strerror(errno));
+             return -1;
+        }
 
-    if (write(fd, nodepath, strlen(nodepath)) < 0) {
-        SLOGE("Unable to write to ums lunfile (%s)", strerror(errno));
-        close(fd);
-        return -1;
+        if (write(fd, nodepath, strlen(nodepath)) < 0) {
+            SLOGE("Unable to write to ums lunfile (%s)", strerror(errno));
+            close(fd);
+            return -1;
+        }
     }
 
     close(fd);
@@ -1001,7 +1016,8 @@ int VolumeManager::shareVolume(const char *label, const char *method) {
 
 int VolumeManager::unshareVolume(const char *label, const char *method) {
     Volume *v = lookupVolume(label);
-
+    int fd;
+    char ch = 0;
     if (!v) {
         errno = ENOENT;
         return -1;
@@ -1017,17 +1033,31 @@ int VolumeManager::unshareVolume(const char *label, const char *method) {
         return -1;
     }
 
-    int fd;
-    if ((fd = open(MASS_STORAGE_FILE_PATH, O_WRONLY)) < 0) {
-        SLOGE("Unable to open ums lunfile (%s)", strerror(errno));
-        return -1;
-    }
+    if (strcmp(label, "/mnt/sdcard")) {
+        SLOGE("ready to unshare external sdcard");
+        if ((fd = open(EXT_MASS_STORAGE_FILE_PATH, O_WRONLY)) < 0) {
+             SLOGE("Unable to open ums lun2 file (%s)", strerror(errno));
+             return -1;
+        }
 
-    char ch = 0;
-    if (write(fd, &ch, 1) < 0) {
-        SLOGE("Unable to write to ums lunfile (%s)", strerror(errno));
-        close(fd);
-        return -1;
+        if (write(fd, &ch, 1) < 0) {
+            SLOGE("Unable to write to ums lun2 file (%s)", strerror(errno));
+            close(fd);
+            return -1;
+        }
+    } else {
+        SLOGE("ready to unshare internal sdcard");
+
+        if ((fd = open(MASS_STORAGE_FILE_PATH, O_WRONLY)) < 0) {
+             SLOGE("Unable to open ums lunfile (%s)", strerror(errno));
+             return -1;
+        }
+
+        if (write(fd, &ch, 1) < 0) {
+            SLOGE("Unable to write to ums lunfile (%s)", strerror(errno));
+            close(fd);
+            return -1;
+        }
     }
 
     close(fd);

VolumeManager.cpp中需要对UMS进行处理.开启大容量存储的时候,分别把内外置sd卡在vold中的设备号写入一下两个路径上

#define MASS_STORAGE_FILE_PATH  "/sys/class/android_usb/android0/f_mass_storage/lun/file"
 
#define EXT_MASS_STORAGE_FILE_PATH  "/sys/class/android_usb/android0/f_mass_storage/lun2/file"

你可能感兴趣的:(android usb mass storage EMMC转化为SD卡(四))