新闻详情

新闻详情

首页 / 资讯中心 / 详情

U盘格式介绍及vold进程简介

发布时间:2026/7/7 11:53:49
U盘格式介绍及vold进程简介
为了便于对于U盘设备的调试本文档整理了常见的U盘格式并对其进行说明。1. 技术点分析FAT32、exFAT 和 NTFSUUIDvold进程2. U盘设备2.1 U盘介绍U盘又称USB闪存盘、优盘闪存盘又称优盘是一种半导体存储器件利用Flash闪存芯片作为存储介质具备了防磁、防震、防潮等多种特性加强了数据的安全性。重量很轻体积很小方便携带。常与各种设备进行连接后使用USB接口是最常见的接口。使用时不需要驱动器无须外接电源即插即用支持热插拔带写保护功能。优盘主要可用来在没有联网的电脑之间交流较大的文件还可用来在笔记本电脑上替代软驱。2.2 接口目前市面上U盘主要分为USB-TYPE-A接口和USB-TYPE-C接口Type-A接口主要常见在电脑上Type-c接口是目前主流的手机和笔记本设备接口部分电脑主板也有Type-c接口。如果只是电脑使用只需购买普通U盘即可如果需要手机使用可以购买手机电脑两用U盘一般就含有Type-C接口。除了USB接口还有USB协议这个USB协会跟个小学生协会一样接口乱命名很多人看到usb3.2就以为比3.0高级其实不是的USB3.2Gen1 USB3.1Gen1 USB3.0 速率都是5Gbps也就是500MB/s的速度很多U盘都达不到该水平因此你看到商品宣传时看他读写速度即可不必太过关心USB3.x的版本。不过还好USB4.0版本2更新了USB接口命名规则USB2.0保留原命名其他协议命名为USB4 传输速率如下图所示2.3 U盘格式U盘格式包括三种FAT32、exFAT 和 NTFS2.3.1 FAT32(File Allocation Table 32bit)32位文件分配表FAT32文件系统用4个字节32位空间来表示每个扇区配置文件的情形所以叫FAT32。分区容量最低是512M而上限的话不同的操作系统都不一样。FAT32不支持4G或更大文件。2.3.2 exFAT(Extended File Allocation Table File System)exFATExtended File Allocation Table File System扩展FAT也称作FAT64即扩展文件分配表。exFAT文件系统是微软在windows embeded5.0以上引入的一种适合于闪存的文件系统主要是为了解决FAT32不支持4G或更大文件的问题而推出的。2.3.3 NTFSNew Technology File SystemNTFS文件系统是windows NT核心和高级服务器网络操作系统环境的文件系统。NTFS系统比FAT32的可靠性更高可以支持更大的分区和更大的文件此外还有不少FAT32没有的功能比如压缩分区、文件索引、数据保护和恢复、加密访问等。如果要拷贝超过4G大小的文件就得用NTFS格式。与FAT32相比exFAT能够支持容量为4GB及以上单个文件的传输、查看与编辑2.4 UUID属性说明UUID是linux区别插入U盘设备的重要属性该属性由制造商在U盘制造时定制。在linux下插入U盘设备键入blkid就可以看到U盘的UUID属性如图console:/# blkid/dev/block/sda1:UUID5304-2BFATYPEvfat// U盘设备如果遇到插入的多个U盘个别识别不到单独插入又能识别的情况可以查看是否是由于该属性一直造成的3. vold进程设备挂载3.1 vold进程介绍voldVolume Daemon是Android操作系统中负责设备存储卷管理的后台进程。它负责检测设备并将其挂载到文件系统中以便用户可以访问设备上的文件和数据。下面是vold进程检测设备并进行挂载的一般过程设备检测vold进程会周期性地扫描系统中连接的设备例如SD卡、USB存储设备、外部硬盘等。它使用Linux内核提供的设备节点信息来确定设备是否存在。设备识别一旦检测到设备vold会尝试识别设备的类型和文件系统格式。这通常通过读取设备的分区表或者特定的设备标识符来完成。根据设备类型和文件系统格式的不同vold会采取相应的挂载策略。设备挂载当设备被识别后vold进程会执行设备挂载操作。这包括创建设备的挂载点mount point、配置文件系统参数以及向操作系统发出挂载命令。文件系统准备在设备挂载之前vold需要确保文件系统可用并做好准备工作。这可能包括对文件系统进行修复如果有必要或者执行其他初始化操作。挂载结果处理vold会监听设备挂载的结果。如果挂载成功它会通知其他系统组件和应用程序使它们可以访问和使用挂载的设备。如果挂载失败vold可能会记录错误日志并尝试进行一些恢复操作。[内核空间]SD卡插入硬件检测 ↓[内核空间]生成/dev/block/mmcblk0发送 ueventadd/block/mmcblk0↓[vold进程]NetlinkHandler 收到 uevent ↓[vold进程]VolumeManager::handleBlockEvent()↓[vold进程]autodisknewDisk(devpath,...);// 创建 Disk 对象↓[vold进程]【调用 disk-create()】 │ ├──readMetadata()│ └──readPartitions()→ sgdisk → 识别分区 ↓[vold进程]createPublicVolume(partDevice)// 创建 Volume↓[内核空间]mount()系统调用 ← 图中虚线mount↓[vold进程]广播挂载状态给 StorageManagerService ↓[用户空间]StorageManagerService 更新状态通知 App3.2 设备挂载对于一个U盘设备而言vold进程会创建一个Disk对象并调用create函数读取U盘的每个分区进行挂载//release/system/vold/model/Disk.cppstatus_tDisk::create(){CHECK(!mCreated);mCreatedtrue;autolistenerVolumeManager::Instance()-getListener();if(listener)listener-onDiskCreated(getId(),mFlags);if(isStub()){createStubVolume();returnOK;}readMetadata();readPartitions();returnOK;}readPartitions函数调用了sgdisk命令读取U盘设备分区的信息并解析//release/system/vold/model/Disk.cppstatus_tDisk::readPartitions(){intmaxMinorsgetMaxMinors();if(maxMinors0){return-ENOTSUP;}destroyAllVolumes();// Parse partition tablestd::vectorstd::stringcmd;cmd.push_back(kSgdiskPath);cmd.push_back(--android-dump);cmd.push_back(mDevPath);std::vectorstd::stringoutput;status_tresForkExecvp(cmd,output);// 读取分区信息if(res!OK){LOG(WARNING)sgdisk failed to scan mDevPath;autolistenerVolumeManager::Instance()-getListener();if(listener)listener-onDiskScanned(getId());mJustPartitionedfalse;returnres;}Table tableTable::kUnknown;bool foundPartsfalse;for(constautoline:output){autosplitandroid::base::Split(line,kSgdiskToken);// 解析autoitsplit.begin();if(itsplit.end())continue;if(*itDISK){if(itsplit.end())continue;if(*itmbr){tableTable::kMbr;}elseif(*itgpt){tableTable::kGpt;}else{LOG(WARNING)Invalid partition table *it;continue;}...}分区检测成功后就会调用对应的函数创建卷并挂载分区。//release/system/vold/model/Disk.cppswitch(type){case0x06:// FAT16case0x07:// HPFS/NTFS/exFATcase0x0b:// W95 FAT32 (LBA)case0x0c:// W95 FAT32 (LBA)case0x0e:// W95 FAT16 (LBA)createPublicVolume(partDevice);break;default:// We should still create public volume here// cause some udisk partition types are not matched above// but can be mounted successfullycreatePublicVolume(partDevice);LOG(WARNING)unsupported table kMbr part type type;break;}}elseif(tableTable::kGpt){if(itsplit.end())continue;autotypeGuid*it;if(itsplit.end())continue;autopartGuid*it;if(android::base::EqualsIgnoreCase(typeGuid,kGptBasicData)){createPublicVolume(partDevice);}elseif(android::base::EqualsIgnoreCase(typeGuid,kGptAndroidExpand)){createPrivateVolume(partDevice,partGuid);}3.3 isEntireDiskAsPartition函数解析在解析分区过程中会调用此函数。函数中会检测/dev/block/sd*路径下对应块设备文件的生成主要就是做了这样的一个判断。如果U盘设备接入vold程序执行到此处时没有检测到块设备文件生成则会造成U盘设备挂载失败//release/system/vold/model/Disk.cppbool Disk::isEntireDiskAsPartition(constintpart){intiPosmSysPath.find(/block/);if(iPos0||part1){LOG(INFO)can not find block dir.;returnfalse;}std::string physicalDevStringPrintf(/dev/block/%s,mSysPath.substr(iPos7).c_str());intretry8;while(true){intretaccess(physicalDev.c_str(),F_OK);if(ret){LOG(INFO)fail to access physical dev:physicalDev;retry--;usleep(50000);}else{break;}if(!retry){LOG(INFO)physical dev: physicalDev doesnt exist;returnfalse;}}std::string partDevName;for(inti1;ipart;i){if(mFlagsFlags::kUsb){partDevNameStringPrintf(%s%d,physicalDev.c_str(),i);}elseif(mFlagsFlags::kSd){partDevNameStringPrintf(%sp%d,physicalDev.c_str(),i);}retry4;while(true){intretaccess(partDevName.c_str(),F_OK);if(ret){retry--;usleep(50000);}else{LOG(INFO)now can access :partDevName;returnfalse;}if(!retry){LOG(INFO)physical dev: partDevName doesnt exist;break;}}}LOG(INFO)physical dev: physicalDev[1-part] doesnt exist;returntrue;}4. 总结U盘设备有不同的接口类型和分区格式。比如type-Ctype-ANTFS,FAT等。UUID是linux区分U盘设备分区的属性每个U盘应该具有唯一的UUIDVold挂载U盘设备过程中会去检测/dev/block/sd*路径下设备文件是否生成如果该设备文件未生成会挂载失败。
网站建设 高端定制 企业官网