Vold study after a period of time, just want to mmcblock built into SDcard method record.
It was because to do this function to learn vold mechanism, posted before the blog:
android--4.2 Vold Mount Management _ Main body construction Main (i)
android--4.2 Vold Mount Management _commandlistener (ii)
android--4.2 Vold Mount Management _volumemanager (iii)
android--4.2 Vold Mount Management _netlinkmanager (iv)
android--4.2 Vold Mount Management _directvolume/volume (Fri)
android--4.2 Vold Mount Management _mountservice (vi)
android--4.2 Vold Mount Management _kernel_usb_uevent (vii)
Personally think the above context, Vold should be regarded as the basic grasp, the details of which need to be studied separately.
Writing is not easy, reproduced please specify the source: http://blog.csdn.net/jscese/article/details/39692953
I. Preparation:
Different platform of the MMC partition scheme and burn write eMMC method is not the same, in short, a piece of area to be used when sdcard mount, and remember block serial number, Android partition type in Linux production is generally EXT4 format.
You can add macro controls to the BOARDCONDIF.MK:
Board_mmcblk_as_sdcard: = 13#jscese open mmcblk0p13 as SDcard to Mount 140724#
and add the Compile option in/SYSTEM/VOLD/ANDROID.MK:
Ifneq ($ (Board_mmcblk_as_sdcard),) common_cflags: =-dmmcblk_as_sdcard=$ (Board_mmcblk_as_sdcard) endifLOCAL_ CFLAGS: = $ (common_cflags)
Two. Vold Mount:
Add special handling to the handleblockevent in/system/vold/volumemanager.cpp.
The core is added as follows:
const char *devtype = Evt->findparam ("Devtype"); const char *DN = Evt->findparam ("Devname"); int major =-1; int minor =-1; BOOL Israwdisk = false; BOOL ispartition = false; int partidx =-1; BOOL Issdcard = false; Major = Atoi (Evt->findparam ("major")); Minor = Atoi (Evt->findparam ("minor")); if (major = = 179) {if (strncmp (DN, "Mmcblk0", 7) = = 0) {//Determine if it is an MMC block#ifndef mmcblk_as_sdcard return;# endif} if (strcmp (DN, "mmcblk0p13") = = 0) slogd ("Jscese display in Vm-handle-issdcard = true\n"); Issdcard = true; } snprintf (device,255, "/dev/block/vold/%d:%d", Major,minor); if (strcmp (Devtype, "disk") = = 0) {//According to the device type on the line to determine the const char *nparts = Evt->findparam ("Nparts"); if (nparts) {int disknumparts = atoi (nparts); Israwdisk = (Disknumparts = = 0); } else {return; }} else {const char *tmp = Evt->findparam ("Partn"); if (tmp = = NULL) {return; } PARTIDX = Atoi (TMP);//if (strcmp (DN, "mmcblk0p14") = = 0) slogd ("Jscese Display in Vm-handle-ispa Rtition = true\n "); Ispartition = true; }
The above is the kernel sent from the event information to do some screening, the following need for device and volume special processing:
if (Israwdisk | | ispartition) {//first find uuid from cache uuidcache::entry *entry = uuidcache.searchent RY (device); /dev UUID Cache if (evt->getaction () = = Netlinkevent::nlactionadd) {mode_t mode = 0660 | S_IFBLK; dev_t dev = (major << 8) | Minor If device has been now added, not add again if (entry! = NULL && Entry->uuid! = null) { Return } if (Mknod (device, mode, dev) < 0) {//Does not create node if (errno! = eexist) {Retu RN; }} if (!getvolumeuuid (device, UUID, 255)) {//Get UUID #ifdef netlink_debug SLOG D ("Can not get" the UUID of%s when device Add ", device); #endif return; The}//volume container adds processing to the above uuid for (it = Mvolumes->begin (); It! = Mvolumes->end (); ++it) {if ( strcmp (UUID, (*it)->getlabel ()) = = 0) {(*it)->handleblockevent (EVT); Hit = true; if (evt->getaction () = = Netlinkevent::nlactionadd) {//if device is added at before, so caches its u UID and device path again uuidcache.addentry (DEVICE,UUID); (*it)->setdevicepath (device); } ... } }} if (!hit) {static char index = ' a '-1; char * mountpoint = NULL; const char *DP = NULL; Directvolume * volume = NULL; #ifdef netlink_debug SLOGW ("No volumes handled block event for '%s '", Devpath); #endif if (evt->getaction ()! = Netlinkevent::nlactionadd) {return; } DP = Evt->findparam ("DEVPATH"); if (DP = = NULL) {return; } slogd ("Jscese display in VMS for 1 mvolumes and Issdcard ==%d, ispartition+=%d \ n", issdcard,ispartition); /* Determine its mount point */if (Issdcard) {//based on the above filter if (ISRawdisk) {asprintf (&mountpoint, "/mnt/sdcard_external"); } else if (ispartition) {#ifdef Mmcblk_as_sdcard if (partidx = = Mmcblk_as_sdcard) {//Boardconfig as defined in bloc K to set mount point asprintf (&mountpoint, "/mnt/sdcard"); SLOGD ("Jscese display set Mountpoint fuck Mmcblock%d as sdcard\n", PARTIDX); } #else if (partidx = = 1) {//external SD card mount point changed to/mnt/sdcard_external asprintf (&mountpoint, "/mnt/sdcard_external"); } else {asprintf (&mountpoint, "/mnt/usb/%s", DN); } #endif}} volume = new Directvolume (THIS,UUID,MOUNTPOINT,PARTIDX); Cache the device path of device volume->setdevicepath (device); Free (mountpoint); Mvolumeslock.lock (); Addvolume (volume); Mvolumeslock.unlock (); Cache the UUID of device uuidcache.addentry (device, UUID); if (Volume->handleblockevent (evt)!=0) {slogd ("New add volume fail to handle the event of%s", Devpath); } }
The cache interface for the UUID is as follows:
static bool Getvolumeuuid (const char* Path, char* buf, int size) {Blkid_cache cache = NULL; Blkid_dev dev = NULL; Blkid_tag_iterate iter = NULL; const char *type = NULL, *value = NULL; BOOL ret = FALSE; if (path = = NULL | | buf = NULL | | Size < 0) {return false; } if (Blkid_get_cache (&cache, NULL) < 0) {return false; } dev = blkid_get_dev (cache, path, blkid_dev_normal); if (dev = = NULL) {return false; iter = Blkid_tag_iterate_begin (dev); while (Blkid_tag_next (ITER, &type, &value) = = 0) {if (strcmp (type, "UUID") = = 0) {int n = Strle n (value); if (n > Size) {n = size; } ret = true; strncpy (Buf,value,n); Buf[n] = ' + '; }} blkid_tag_iterate_end (ITER); Blkid_put_cache (cache); return ret;} Class Uuidcache {public:struct Entry {char *device; Char *uuid; }; Uuidcache () { Uuidcache = new Entrycollection (); } ~uuidcache () {delete uuidcache; } void AddEntry (const char *device, const char *uuid) {Entry *entry = NULL; if (device = = NULL | | uuid = = NULL) {return; } entry = Searchentry (device); if (entry = = NULL) {entry = new entry (); Entry->device = StrDup (device); Uuidcache->push_back (entry); } else {if (entry->uuid! = NULL) {free (ENTRY->UUID); }} entry->uuid = StrDup (UUID); } Entry *searchentry (const char *device) {Entrycollection::iterator it; for (it = Uuidcache->begin (); It! = Uuidcache->end (); ++it) {if (*it)->device! = NULL && str CMP ((*it)->device, device) = = 0) {return (*it); }} return NULL; }private:typedef android::list<entry *> entrycollection; Entrycollection *uuidcache;}; Static Uuidcache Uuidcache;
Transfer into the Directvolume, no longer do analysis, the previous article has resolved.
The last execution is in the MountVol in the mounted Volume.cpp. The modifications are added as follows:
if (primarystorage) {//special case the primary SD card. For this we grant write access to the SDCARD_RW group. GID = AID_SDCARD_RW; } else {//for secondary external storage We keep things locked up. GID = AID_MEDIA_RW; } sloge ("Jscese display in Volume-mountvol devicepath==%s, gid ==%d \ n", Devicepath,gid); bool Isfatfs = true; bool Isntfsfs = true; bool Isextfs = true; if (isfatfs) {sloge ("Jscese Fat::d omount \ n"); if (Fat::d omount (DevicePath, "/mnt/secure/staging", False, False, False, Aid_system, GID, 0002, true)) {Sloge ("%s failed to mount via VFAT (%s) \ n", DevicePath, Strerror (errno)); Isfatfs = false; } else {Isntfsfs = false; Isextfs = false; }}/*===jscese add for format Mmcblock Ext4_type to Vfat_type as SDcard 140805=====*/#ifdef mmcblk_as_sDcard if (!isfatfs) {char checkmmcblokpath[255];//sprintf (DevicePath, "/dev/block/vol D/%d:%d ", MAJOR (Devicenodes[i]), MINOR (Devicenodes[i])); sprintf (Checkmmcblokpath, "/dev/block/vold/%d:%d", Sd_major,mmcblk_as_sdcard); Sloge ("Jscese volume::mountvol format checkmmcblockpath=%s, devicepath==%s, mountpoint==%s\n", CheckmmcblokPath, Devicepath,getmountpoint ()); if (!strcmp ("/mnt/sdcard", Getmountpoint ())) {if (!strcmp (Checkmmcblokpath,devicepath)) {setState (volume::state_idle); Sloge ("Jscese volume::mountvol format 1 label==%s\n", Getlabel ()); if (Formatvol () ==0) {setState (volume::state_checking); Sloge ("Jscese volume::mountvol format over \ n"); if (Fat::d omount (DevicePath, "/mnt/secure/staging", False, False, False, Aid_system, GID, 0002, True) {Sloge ("%s failed to Mount via VFAT 2 (%s) \ n ", DevicePath, Strerror (errno)); Isfatfs = false; } else {isfatfs=true; Isntfsfs = false; Isextfs = false; }}}}} #endif/*===============end================*/
The Fat form is mounted first, and the first time the system is run, because the SDcard block is in the EXT4 format, it is sure to return false, this time in the code
FormatvolFormat, then fat form mount!
Because I found that if the/mnt/sdcard is mounted in the Ext4 form, then the creation of the file in the partition can only be read and written by the creator, and the permissions are not defined according to/mnt/sdcard.
At this time each application process in/mnt/sdcard created folder, other users do not have access to, lost SDcard due value!
So here to format to fat, and then the creation of the partition in the full load point is/mnt/sdcard to rule!
The upper frame does not have to be changed so that a block of MMC can be built into SDcard for application use, while externally inserted sdcard will be mounted to/mnt/sdcard_external.
android--4.2 Vold Mount Management _mmcblk built-in-dual sdcard (eight)