Android USB drive feature implementation and analysis
The U-disk function realizes the result: the U disk will be displayed as USB storage in Settings storage.
The ready-to-work kernel needs to support USB host, support the FUSE file system, and configure it in the FS option (config_fuse_fs=y).
Configuration configuration for Android init.<board>.rc
Mkdir/storage/udisk0 0000 System System Mkdir/mnt/media_rw/udisk0 0700 MEDIA_RW MEDIA_RW
Service fuse_udisk0/system/bin/sdcard-u 1023-g 1023-w 1023-d/mnt/media_rw/udisk0/storage/udisk0 class Late_star T disabled
Configure Fstab.<board>
/BLOCK/SDA /mnt/media_rw/udisk0 vfat defaults voldmanaged=udisk0:auto
Configure Overlay
<storage android:mountpoint= "/storage/udisk0" android:storagedescription= "@string/storage_usb" Android:primary= "false" android:removable= "true"/>
Mount Process:
/dev/block/vold/8:1/mnt/media_rw/udisk0 VFAT rw,dirsync,nosuid,nodev,noexec,relatime,uid=1023,gid=1023,fmask= 0007,dmask=0007,allow_utime=0020,codepage=437,iocharset=iso8859-1,shortname=mixed,utf8,errors=remount-ro 0 0/dev /fuse/storage/udisk0 Fuse Rw,nosuid,nodev,relatime,user_id=1023,group_id=1023,default_permissions,allow_other 0 0
[email protected]:/# logcat-s Vold mountservice---------beginning Of/dev/log/main---------beginning Of/dev/log /systemi/vold (820): Vold 2.1 (The Revenge) firing Upd/vold (820): Volume sdcard1 State changing-1 (Initializin g), 0 (No-media) d/vold (820): Volume sdcard1 State changing-1 (Initializing), 0 (No-media) d/vold (820 ): Volume udisk0 State changing-1 (Initializing), 0 (No-media) d/vold (820): Volume udisk0 State changing 0 (no- Media), 2 (Pending) D/vold (820): Volume udisk0 State changing 2 (Pending), 1 (idle-unmounted) D/vold (8 : Volume sdcard1 State changing 0 (No-media), 2 (Pending) D/vold (820): Volume sdcard1 State changing 2 (Pendi NG), 1 (idle-unmounted) D/mountservice (1587): Got storage path:/storage/sdcard0 description:internal storage Primar Y:true removable:false emulated:true mtpreserve:50 allowmassstorage:false maxfilesize:0d/mountservice (1587): AddVol Umelocked () Storagevolume:D/mountservice (1587): mstorageid=65537 mpath=/storage/emulated/0 mdescriptionid=17040662 D/MountService (1587): Mprimary=true mremovable=false memulated=true mmtpreservespace=50 d/mountservice (1587): MAllowMassStorage=false MMax Filesize=0 mowner=userhandle{0} muuid=null d/mountservice (1587): Muserlabel=null mstate=null D/MountService (1587): g OT storage path:/storage/sdcard1 DESCRIPTION:SD card primary:false removable:true emulated:false mtpreserve:0 AllowM Assstorage:false Maxfilesize:4294967296d/mountservice (1587): addvolumelocked () Storagevolume:d/mountservice (1587) : Mstorageid=0 mpath=/storage/sdcard1 mdescriptionid=17040663 mprimary=false d/mountservice (1587): MRemovable=tru E memulated=false mmtpreservespace=0 mallowmassstorage=false d/mountservice (1587): mmaxfilesize=4294967296 mOwner=nu ll Muuid=null muserlabel=null mstate=null D/mountservice (1587): Got storage path:/storage/udisk0 description:usb Storag E Primary:false Removable:truE emulated:false mtpreserve:0 allowmassstorage:false maxfilesize:0d/mountservice (1587): addVolumeLocked () StorageVol Ume:d/mountservice (1587): mstorageid=0 mpath=/storage/udisk0 mdescriptionid=17040664 mPrimary=false D/MountService ( 1587): Mremovable=true memulated=false mmtpreservespace=0 mallowmassstorage=false D/MountService (1587): MMaxFileS Ize=0 mowner=null muuid=null muserlabel=null mstate=null w/mountservice (1587): Duplicate state Transition (unmounted-&G T unmounted) For/storage/sdcard1d/mountservice (1587): Volume State changed for/storage/sdcard1 (unmounted-removed) W/mountservice (1587): Duplicate state Transition (unmounted-unmounted) For/storage/udisk0i/vold (820):/dev/b Lock/vold/8:1 being considered for volume Udisk0d/vold (820): Volume udisk0 State changing 1 (idle-unmounted)-3 (Checking) D/mountservice (1587): Volume State changed for/storage/udisk0 (unmounted) checking (d/mountservice): 1587 Ageintent Intent {act=android.intent.action.media_checking dat=file:///storage/udisk0 (have extras)} to Userhandle{-1}i/vold (820): Filesystem Check completed Okd/vold (820): Blkid identified as/dev/block/vold/8:1:uuid= "402e-0ee3" type= "VFAT" d/v Old (820): Volume udisk0 State changing 3 (Checking), 4 (mounted) D/mountservice (1587): Volume state changed for /storage/udisk0 (checking-mounted) D/mountservice (1587): sendstorageintent Intent {act= Android.intent.action.MEDIA_MOUNTED Dat=file:///storage/udisk0 (have extras)} to Userhandle{-1}w/mountservice (1587): Duplicate state Transition (mounted-mounted) for/storage/emulated/0
Vold parse fstab file in Android 4.4, Vold will parse vold.
Property_get ("Ro.hardware", Propbuf, ""); snprintf (fstab_filename, sizeof (fstab_filename), Fstab_prefix "%s", propbuf); Fstab = Fs_mgr_read_fstab (fstab_filename); if (!fstab) { Sloge ("Failed to open%s\n", fstab_filename); return-1; }
Which #define FSTAB_PREFIX "/fstab." Therefore, the configuration of the Fatab file must be placed in the root directory, Vold is the background process of Android, will always listen to Fatab inside the item marked as Voldmanaged if there is no tag, then skip. Items that are not marked. It can be handled by the Mount command of INIT, but it will not listen, so you can put the recovery and the cache directory in such a way that you just start the Mount directory entry in Fatab and leave it to init for the Mount command processing, such as Samsung Device/samsung/man Ta/fstab.manta
# Android Fstab file.#<src> <mnt_point> <type> <mnt_flags and Options> <fs_mgr_flags># the filesystem that contains the filesystem C Hecker binary (typically/system) cannot# specify Mf_check, and must come before any filesystems this do specify mf_check/ Dev/block/platform/dw_mmc.0/by-name/system/system Ext4 ro wait/dev/block/ Platform/dw_mmc.0/by-name/cache/cache Ext4 Noatime,nosuid,nodev,nomblk_io_submit,errors=panic W Ait,check/dev/block/platform/dw_mmc.0/by-name/userdata/data Ext4 NOATIME,NOSUID,NODEV,NOMBLK_IO_SUBM It,errors=panic Wait,check,encryptable=/dev/block/platform/dw_mmc.0/by-name/metadata/dev/block/platform/dw_ Mmc.0/by-name/efs/factory Ext4 Noatime,nosuid,nodev,ro wait/dev/block/p Latform/dw_mmc.0/by-name/boot/boot eMMC defaults defaults/dev/block/platform/dw_mmc.0/by-name/recovery /recovery eMMC Defaults Defaults/dev/block/platform/dw_mmc.0/by-name/misc /misc eMMC Defaults defaults/dev/block/mmcblk0boot0 /bootloader eMMC Defaults defaults
Call mount on system boot:
On FS mkdir/factory 0775 Radio Radio Mount_all/fstab.manta
Similarly, the Mount command for Init, which is marked as voldmanaged, is also ignored by the Mount commands of the project INIT, which is different from the Mount management of Vold, and cannot be mixed.
Mountservice and Vold Joint mount U disk Mountservice and Vold will establish socket communication, the specific mount operation is issued orders, to Vold to complete. Mountservice will parse our configured storage_list.xml.
private void readstoragelistlocked () { mvolumes.clear (); Mvolumestates.clear (); Resources resources = Mcontext.getresources (); int id = com.android.internal.r.xml.storage_list; Xmlresourceparser parser = resources.getxml (ID); AttributeSet attrs = xml.asattributeset (parser); try { xmlutils.begindocument (parser, tag_storage_list); while (true) { xmlutils.nextelement (parser);
Vold gets a change to the device in the list will send the state changes event, Mountservice in onEvent processing a variety of different state, which gets to the device insertion, will perform the mount operation:
if (code = = voldresponsecode.volumediskinserted) { new Thread ("mountservice#volumediskinserted") { @Override Public void Run () { try { int rc; if (rc = domountvolume (path)) = storageresultcode.operationsucceeded) { SLOG.W (TAG, String.Format ("insertion Mount failed (%d) ", RC)); } } catch (Exception ex) { SLOG.W (TAG, "Failed to mount Media on insertion", ex);}} . Start ();
Domountvolume just sends the Mount command to Vold
private int Domountvolume (String path) { int rc = storageresultcode.operationsucceeded; Final Storagevolume volume; Synchronized (Mvolumeslock) { volume = mvolumesbypath.get (path); } if (debug_events) slog.i (TAG, "domountvolume:mouting" + path); try { Mconnector.execute ("volume", "Mount", path);
Finally Vold inside the corresponding mount operation, our U-disk is the VFAT format, I only tested this format, the Linux format is not tested, because Vold only support fat and EXT4
int Volumemanager::mountvolume (const char *label) { Volume *v = lookupvolume (label); if (!v) { errno = ENOENT; return-1; } return V->mountvol ();}
if (Fat::d omount (DevicePath, Getmountpoint (), False, False, False, AID_MEDIA_RW, AID_MEDIA_RW, 0007, True)) { Sloge ("%s failed to mount via VFAT (%s) \ n", DevicePath, Strerror (errno)); Continue