在/etc下有一个重要的文件vold.fstab. system/vold/main.cpp会解析这个文件,new出DirectVolume对象.并加入到VolumeManager里统一管理.
所以我们需要在这里加入我们的EMMC分区
## Vold 2.0 fstab for HTC Dream or Sapphire
#
## - San Mehat (san@android.com)
##
#######################
## 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"