ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Android 9.0 支持NTFS和Exfat 格式U盘开发

2020-06-20 19:41:10  阅读:1473  来源: 互联网

标签:NTFS 06 U盘 17 1619 19 Exfat 16 exfat


前言

最近有个需求要求在Android 9.0上面支持NTFS和Exfat 格式的U盘。网上有很多资料都是基于Android 4.4 的系统,系统版本太陈旧没有办法借鉴,通过两周的摸索终于搞定了这个功能,走了很多弯路,这里也写一篇博客记录下此功能开发流程,希望对有同样困惑的程序猿有帮助,起码可以让你少加很多班,哈哈哈。

集成方案

在Linux平台上支持exFAT,分为三个阶段:最初是一个exFAT的补丁,可以只读的使用exFAT;之后通过FUSE方式支持了exFAT,但是其性能并不很好;现在由Android代码中移植来的exfat-nofuse则是由微软开发的,并不依赖FUSE,不但能支持读写,而且性能也不错。经过测试发现Android 9.0 除了集成fuse 文件系统源码还需要集成no-fuse 的exfat 驱动源码。源码都可以在github上下载,解决掉编译问题就可以了。文章末尾我会放上已经解决编译问题的源码链接。

集成步骤

1、下载Exfat 的no-fuse 驱动源码集成

Github 上面关于no-fuse 源码有很多,主要是针对linux的,Android也可以集成。我用的是这个链接 :github no-fuse驱动链接
GitHub上针对Linux 是放在kernel/fs 目录的,我的是NXP Android 9.0 的系统,集成目录是:**vendor/nxp-opensource/kernel_imx/fs** ,下载nofuse 驱动修改文件名为exfat放到该目录下。同时需要修改Mikefile 和config 配置文件。这一块只需要集成就好了,源码不用修改可以直接使用。不清楚怎么配置的可以问问驱动的同事。

diff --git a/vendor/nxp-opensource/kernel_imx/arch/arm64/configs/android_f202_p_car_defconfig b/vendor/nxp-opensource/kernel_imx/arch/arm64/configs/android_f202_p_car_defconfig
index 0841989..28523fe 100755
--- a/vendor/nxp-opensource/kernel_imx/arch/arm64/configs/android_f202_p_car_defconfig
+++ b/vendor/nxp-opensource/kernel_imx/arch/arm64/configs/android_f202_p_car_defconfig
@@ -512,6 +512,9 @@ CONFIG_FUSE_FS=y
 CONFIG_CUSE=y
 CONFIG_OVERLAY_FS=y
 CONFIG_VFAT_FS=y
+CONFIG_EXFAT_FS=y
+CONFIG_EXFAT_DEFAULT_CODEPAGE=437
+CONFIG_EXFAT_DEFAULT_IOCHARSET="utf8"
 CONFIG_TMPFS_POSIX_ACL=y
 CONFIG_HUGETLBFS=y
 CONFIG_SDCARD_FS=y
diff --git a/vendor/nxp-opensource/kernel_imx/fs/Kconfig b/vendor/nxp-opensource/kernel_imx/fs/Kconfig
old mode 100644
new mode 100755
index 121fabf..75002af
--- a/vendor/nxp-opensource/kernel_imx/fs/Kconfig
+++ b/vendor/nxp-opensource/kernel_imx/fs/Kconfig
@@ -126,6 +126,7 @@ menu "DOS/FAT/NT Filesystems"
 
 source "fs/fat/Kconfig"
 source "fs/ntfs/Kconfig"
+source "fs/exfat/Kconfig"
 
 endmenu
 endif # BLOCK
diff --git a/vendor/nxp-opensource/kernel_imx/fs/Makefile b/vendor/nxp-opensource/kernel_imx/fs/Makefile
old mode 100644
new mode 100755
index 1e34e4b..254cb71
--- a/vendor/nxp-opensource/kernel_imx/fs/Makefile
+++ b/vendor/nxp-opensource/kernel_imx/fs/Makefile
@@ -79,6 +79,7 @@ obj-$(CONFIG_HUGETLBFS)		+= hugetlbfs/
 obj-$(CONFIG_CODA_FS)		+= coda/
 obj-$(CONFIG_MINIX_FS)		+= minix/
 obj-$(CONFIG_FAT_FS)		+= fat/
+obj-$(CONFIG_EXFAT_FS)          += exfat/
 obj-$(CONFIG_BFS_FS)		+= bfs/
 obj-$(CONFIG_ISO9660_FS)	+= isofs/
 obj-$(CONFIG_HFSPLUS_FS)	+= hfsplus/ # Before hfs to find wrapped HFS+

集成完后 编译make bootimagemake dtboimage 烧录这两个镜像文件后 cat proc/filesystems 可以看到多了exfat格式,说明no-fuse驱动集成OK了。

在这里插入图片描述

2、集成Exfat fuse文件系统源码

一、下载exfat文件系统源码修改名称为 exfat 集成到 external 目录下。源码下载: CyanogenMod /android_external_exfat

二、还有一个fuse 目录文件放到external 目录下,可以参考的我的源码链接。

build/make/target/product/base.mk 添加编译选项
    fsck.exfat \
    mkfs.exfat \
    mount.exfat \
    libfuse_static \

三、处理交差编译问题
编译的时候会有很多wrerror,这里面不用慌,我们直接用下面的标签把警告的报错都屏蔽掉,如果还有其他警告报错可以继续添加。其他Makefile 的报错可以参考我的makefile 文件修改。

LOCAL_CFLAGS := \
	-D_FILE_OFFSET_BITS=64 \
	-DFUSE_USE_VERSION=26 \
	-Wno-error=format-security \
	-Wno-sign-compare \
	-Wno-unused-parameter \
	-Wno-pointer-arith \
	-Wno-address-of-packed-member \
	-Wno-missing-field-initializers \
	-Wno-logical-not-parentheses

报错解决完后 make -j128 全编一下可以看到 system/bin 下面有 mount.exfat、mkfs.exfat 、mkfs.exfat三个文件说明这一步OK 了。

在这里插入图片描述

3、挂载验证

其实做完前面两步已经OK了,因为android 9.0 vold代码里面是已经有了exfat 格式的挂载逻辑代码。vold 里面不用做任何修改,如果没有这些代码的话就需要从4.4里面移植过来了。
-->system/vold/model/PublicVolume.cpp


status_t PublicVolume::doMount() {
    std::string sysPath= getSysPath();   
    readMetadata();
	LOG(DEBUG) << "PublicVolume::doMount sysPath= "<< sysPath<<",mFsType="<< mFsType<<"is exfat support:"<<exfat::IsSupported();
    if (mFsType == "vfat" && vfat::IsSupported()) {
        if (vfat::Check(mDevPath)) {
            LOG(ERROR) << getId() << " failed filesystem check";
            //return -EIO;
        }
    } else if (mFsType == "exfat") {
        if (exfat::Check(mDevPath)) {
            LOG(ERROR) << getId() << " failed filesystem check";
            return -EIO;
        }

-->system/vold/fs/Exfat.cpp

status_t Mount(const std::string& source, const std::string& target, int ownerUid, int ownerGid,
               int permMask) {
    int mountFlags = MS_NODEV | MS_NOSUID | MS_DIRSYNC | MS_NOATIME | MS_NOEXEC;
    auto mountData = android::base::StringPrintf("uid=%d,gid=%d,fmask=%o,dmask=%o", ownerUid,
                                                 ownerGid, permMask, permMask);

    if (mount(source.c_str(), target.c_str(), "exfat", mountFlags, mountData.c_str()) == 0) {
        return 0;
    }

    PLOG(ERROR) << "Mount failed; attempting read-only";
    mountFlags |= MS_RDONLY;
    if (mount(source.c_str(), target.c_str(), "exfat", mountFlags, mountData.c_str()) == 0) {
        return 0;
    }
	//rc = mount(c_source, c_target, "exfat", flags, mountData);
    std::string exec;
    exec = exfatMountPath;
    exec = exec + " " + c_source + " " + c_target;
    rc = system(exec.c_str());
    if (rc == 0) {
    SLOGI("exfat Filesystem mounted OK");
    } else {
    SLOGE("exfat Filesystem mounted failed");
    errno = EROFS;
}


    return -1;
}

看如下log说明Exfat 格式挂载大功告成了,可以Happy 起来了。

6-19 17:16:45.211  1619  1625 D vold    : VolumeManager::handleBlockEvent devName=sda1,devType=partition,eventPath=/devices/platform/5b0d0000.usb/ci_hdrc.0/usb3/3-1/3-1:1.0/host0/target0:0:0/0:0:0:0/block/sda/sda1
06-19 17:16:45.211  1619  1619 V vold    : /system/bin/blkid
06-19 17:16:45.211  1619  1619 V vold    :     -c
06-19 17:16:45.211  1619  1619 V vold    :     /dev/null
06-19 17:16:45.211  1619  1619 V vold    :     -s
06-19 17:16:45.211  1619  1619 V vold    :     TYPE
06-19 17:16:45.211  1619  1619 V vold    :     -s
06-19 17:16:45.211  1619  1619 V vold    :     UUID
06-19 17:16:45.211  1619  1619 V vold    :     -s
06-19 17:16:45.211  1619  1619 V vold    :     LABEL
06-19 17:16:45.211  1619  1619 V vold    :     /dev/block/vold/public:8,1
06-19 17:16:45.271  1619  1619 V vold    : /dev/block/vold/public:8,1: LABEL="disk" UUID="F45F-72A6" TYPE="exfat" 
06-19 17:16:45.271  1619  1619 V vold    : 
06-19 17:16:45.272  1619  1619 W vold    : getId()=public:8,1,mFsType=exfat,mFsUuid=F45F-72A6,mFsLabel=disk: No such file or directory
06-19 17:16:45.273  1619  1619 D vold    : PublicVolume::doMount sysPath= /sys/devices/platform/5b0d0000.usb/ci_hdrc.0/usb3/3-1/3-1:1.0/host0/target0:0:0/0:0:0:0/block/sda,mFsType=exfat
06-19 17:16:45.273  1619  1619 V vold    : /system/bin/fsck.exfat
06-19 17:16:45.273  1619  1619 V vold    :     /dev/block/vold/public:8,1
06-19 17:16:45.273 24631 24631 I Binder:1619_2: type=1400 audit(0.0:992): avc: denied { entrypoint } for path="/system/bin/mount.exfat" dev="dm-0" ino=3620 scontext=u:r:fsck_untrusted:s0 tcontext=u:object_r:system_file:s0 tclass=file permissive=1
06-19 17:16:45.294  1619  1619 I fsck.exfat: exFAT multi-call binary, mod/build 1.0.4 by Lurker
06-19 17:16:45.294  1619  1619 I fsck.exfat: exfatfsck 1.1.1
06-19 17:16:45.307  1619  1619 I fsck.exfat: Checking file system on /dev/block/vold/public:8,1.
06-19 17:16:45.309  1619  1619 I fsck.exfat: File system version           1.0
06-19 17:16:45.309  1619  1619 I fsck.exfat: Sector size                 512 bytes
06-19 17:16:45.310  1619  1619 I fsck.exfat: Cluster size                 32 KB
06-19 17:16:45.310  1619  1619 I fsck.exfat: Volume size                  15 GB
06-19 17:16:45.310  1619  1619 I fsck.exfat: Used space                 3401 MB
06-19 17:16:45.310  1619  1619 I fsck.exfat: Available space              11 GB
06-19 17:16:45.362  1619  1619 I fsck.exfat: Totally 27 directories and 29 files.
06-19 17:16:45.362  1619  1619 I fsck.exfat: File system checking finished.
06-19 17:16:45.365  1619  1619 I fsck.exfat: No errors found.
06-19 17:16:45.367  1619  1619 I vold    : Check OK
06-19 17:16:45.367  1619  1619 E vold    : +++++doMount [ /storage/udisk/ ]
06-19 17:16:45.368  1619  1619 D vold    : PublicVolume::doMount mDevPath=/dev/block/vold/public:8,1,mRawPath=/mnt/media_rw/udisk/
06-19 17:16:45.453  1619  1619 V vold    : Waiting for FUSE to spin up...

4、我的GitHub源码链接

最后放上的GitHub源码链接,里面有修改好的源码,有需要的老铁可以参考一下,记得 Star 一下啦。

我的GitHub 链接 :
Shawnsongs/Android_P_external_exfat_ntfs-3g

结语

这里特别要感谢下 lostnc 的exfat博客,这是整个百度上面第一个写的Android 9.0 集成exfat 文件系统的博客,其中关于同时采用 fuseno-fuse 方式支持exfat 的方案证明是唯一可行的。同时也感谢github 上几位开源贡献者的文件系统和驱动源码。虽然Android 不支持Exfat 和Ntfs 文件系统,但是有更多开发者将自己的经验和方案分享出来,这些需求还是可以自己开发的,这也是我写这篇博客的初衷。

参考博客链接

1、Android9.0支持exFat格式u盘识别
2、Android 7.0支持exfat文件系统

标签:NTFS,06,U盘,17,1619,19,Exfat,16,exfat
来源: https://blog.csdn.net/An_Times/article/details/106858104

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有