1. 项目概述与核心价值最近在RK3568平台上折腾Android 13系统有个需求挺常见怎么让开发板直接访问我Windows电脑上的共享文件夹无论是调试时传输大文件还是想直接播放电脑里的媒体资源如果能像访问本地存储一样操作网络共享效率会高很多。传统的ADB推拉文件或者U盘拷贝在频繁操作和大文件场景下体验确实不够丝滑。这个需求的核心就是要在Android系统上实现CIFSCommon Internet File System协议的网络文件系统挂载。CIFS是SMBServer Message Block协议的一个实现也是Windows网络共享的“标准语言”。在Linux内核的Android系统上通过内核模块支持CIFS就能将远程的Windows共享目录“映射”成本地的一个目录路径应用可以无感地读写其中的文件。以瑞芯微的iTOP-RK3568开发板为例它搭载了四核Cortex-A55处理器性能足以应对轻量级的网络文件系统操作。在Android 13系统上实现这一功能不仅对开发者调试、文件管理有直接帮助对于构建基于RK3568的智能终端如广告机、数字标牌、工控设备也很有意义——可以方便地从中心服务器更新内容。接下来我会详细拆解从环境准备、内核配置、到挂载调试的全过程并分享几个我踩过坑才总结出来的关键技巧。2. 整体方案设计与思路拆解2.1 为什么选择CIFS协议在Linux/Android环境下访问网络存储常见的协议有NFS和CIFS/SMB。NFS在Unix/Linux世界更原生性能可能稍好但Windows默认并不开启NFS服务需要额外安装功能。而CIFS/SMB协议是Windows网络邻居和文件共享的基石几乎每台Windows电脑都默认支持。为了让开发板能无缝访问最常见的Windows共享选择CIFS协议是更通用、更便捷的方案。Android系统本质上是一个运行在Linux内核之上的特殊用户空间。因此在Android上挂载CIFS共享其底层原理与在标准Linux上并无二致需要内核支持CIFS文件系统模块并在用户空间通过mount命令或相应API发起挂载请求。难点在于很多Android设备厂商为了系统精简和安全默认内核编译时并未将CIFS支持编译进去或者仅编译为模块但未在系统中提供。2.2 iTOP-RK3568开发板方案选型对于iTOP-RK3568开发板我们通常有两种路径来实现CIFS挂载使用预编译的内核模块如果存在最理想的情况是开发板供应商已经提供了编译好的CIFS内核模块.ko文件。我们只需要将其推送到设备加载模块然后执行挂载命令即可。这种方式最快捷但依赖于供应商的支持。自行编译内核或内核模块如果供应商未提供或者提供的模块与当前系统内核版本不匹配我们就需要获取RK3568 Android 13对应的内核源码自行配置并编译出包含CIFS支持的内核或内核模块。考虑到通用性和学习价值本文将重点阐述第二种方案即从源码编译开始。这个过程虽然步骤较多但能让你彻底掌握如何为特定Android内核添加功能这项技能在嵌入式开发中非常有用。我们会基于瑞芯微官方或开发板供应商提供的SDK进行。2.3 操作流程总览整个实现过程可以梳理为以下几个关键阶段我将按顺序详细展开环境准备搭建用于编译RK3568内核的Linux开发环境获取正确的内核源码。内核配置与编译在内核配置中开启CIFS支持并编译生成新的内核镜像或模块。镜像烧写与验证将新编译的内核烧录到iTOP-RK3568开发板并启动验证。Windows共享设置在PC端设置一个用于测试的共享文件夹并确保网络互通。Android端挂载操作在开发板的Android系统上执行挂载命令访问Windows共享。问题排查与优化解决可能遇到的权限、网络、稳定性等问题并探讨自动化挂载方案。注意内核编译和烧写存在一定风险操作不当可能导致设备无法启动。请务必在开始前备份重要数据并确保你有能力通过MaskRom模式等救砖手段恢复设备。3. 环境准备与内核源码获取3.1 编译环境搭建内核编译推荐在Linux系统下进行。你可以使用实体机安装Ubuntu 20.04 LTS或22.04 LTS也可以使用虚拟机。建议分配至少8GB内存和100GB硬盘空间编译过程比较消耗资源。首先安装必要的编译工具链和依赖包sudo apt update sudo apt install -y git-core gnupg flex bison build-essential zip curl zlib1g-dev \ libc6-dev-i386 libncurses5 lib32ncurses5-dev x11proto-core-dev libx11-dev \ lib32z1-dev libgl1-mesa-dev libxml2-utils xsltproc unzip fontconfig python3 \ device-tree-compiler u-boot-tools对于RK3568我们通常使用Android官方或Rockchip定制的交叉编译工具链如aarch64-linux-android-4.9。这个工具链一般包含在完整的Android SDK中。3.2 获取内核源码你需要从开发板供应商如iTOP或瑞芯微官方渠道获取与你的Android 13系统版本完全匹配的内核源码。通常供应商会提供一个SDK包里面包含了kernel/目录。假设你已经拿到了SDK将其解压。内核源码的路径通常类似于path/to/sdk/kernel/。进入该目录cd path/to/sdk/kernel在开始配置前先确定当前内核的配置文件。对于RK3568配置文件名通常是rockchip_defconfig或其变体如rk3568-android.config。你可以通过查看arch/arm64/configs/目录下的文件来确认。ls arch/arm64/configs/ | grep -i rk3568假设找到的配置是rk3568_android_defconfig。这个文件定义了该开发板内核编译的默认选项。4. 内核配置与CIFS模块编译4.1 加载默认配置并启动菜单配置首先导入默认的板级配置并启动图形化或文本配置界面进行修改# 清理之前的编译中间文件如果是首次可跳过 make ARCHarm64 CROSS_COMPILEaarch64-linux-android- mrproper # 应用默认配置 make ARCHarm64 CROSS_COMPILEaarch64-linux-android- rk3568_android_defconfig # 启动menuconfig配置界面 make ARCHarm64 CROSS_COMPILEaarch64-linux-android- menuconfigCROSS_COMPILE指定了交叉编译工具链的前缀。你需要根据SDK中工具链的实际路径和名称进行调整例如如果工具链gcc的完整路径是/path/to/toolchain/bin/aarch64-linux-android-gcc那么CROSS_COMPILE就应该是/path/to/toolchain/bin/aarch64-linux-android-。执行menuconfig命令后会进入一个基于ncurses的文本图形配置界面。4.2 定位并启用CIFS支持在menuconfig界面中使用键盘方向键导航按/键可以搜索配置项。我们输入“CIFS”进行搜索。搜索结果会显示CONFIG_CIFS等相关选项及其所在位置。通常CIFS相关的配置位于File systems --- Network File Systems --- * CIFS support (advanced network filesystem, SMB3.0, SMB2.1, SMB2 and also SMB1.1)使用方向键进入File systems-Network File Systems菜单。在这里你会看到CIFS support选项。按空格键可以切换其状态 不编译。M编译为内核模块.ko文件运行时动态加载。*直接编译进内核镜像。选择建议编译为模块 (M): 这是更灵活的选择。模块可以单独加载和卸载不会增大内核镜像的体积方便调试和更新。对于我们的需求推荐此选项。编译进内核 (*): 功能永远可用无需手动加载模块但内核镜像会稍大。将光标移动到CIFS support上按M键使其显示为M。选中后其下的子选项如CIFS statisticsExtended attributes等也会变为可配置状态。对于基本功能保持默认即可但建议将CIFS extended attributes (experimental)和CIFS POSIX Extensions也选为M以支持更完整的文件属性。此外为了支持更现代的SMB2.1、SMB3.0协议Windows 8/10/11默认使用确保CIFS SMB2 and SMB3 support (experimental)也被启用同样设为M。配置完成后按左右键选择 Save 直接按回车使用默认的.config文件名保存配置然后选择 Exit 退出menuconfig。4.3 编译内核模块现在开始编译我们配置好的内核模块# 编译内核模块。 -j$(nproc) 表示使用所有CPU核心并行编译加快速度。 make ARCHarm64 CROSS_COMPILEaarch64-linux-android- -j$(nproc) modules编译过程需要一段时间。完成后我们需要的CIFS模块文件.ko会在对应的内核源码子目录中生成。CIFS主模块通常位于fs/cifs/cifs.ko同时其依赖的其他模块如nls_utf8.ko用于UTF-8编码支持也会被编译出来它们通常位于fs/nls/目录下。实操心得编译时如果遇到错误首先检查CROSS_COMPILE路径是否正确以及工具链版本是否与内核源码匹配。错误信息通常是定位问题的关键。另一个常见问题是依赖缺失回顾“环境准备”步骤确保所有开发包都已安装。4.4 提取与整理模块文件编译完成后我们需要将生成的.ko文件从复杂的源码目录结构中找出来。可以使用find命令find . -name *.ko -type f | grep -E (cifs|nls_utf8) | head -10假设我们找到了以下关键模块fs/cifs/cifs.kofs/nls/nls_utf8.ko(CIFS访问中文目录/文件可能需要)将这些模块文件复制到一个单独的目录方便后续打包推送到开发板mkdir ../cifs_modules cp fs/cifs/cifs.ko ../cifs_modules/ cp fs/nls/nls_utf8.ko ../cifs_modules/ # 可能还需要其他依赖如 fs/ksmbd/ksmbd.ko (如果配置了ksmbd客户端)根据编译日志和模块依赖决定。可以使用modinfo命令查看模块的依赖关系# 需要在x86主机上使用对应的工具链中的工具或者将模块放到设备上用modinfo查看 # 这里演示概念cifs.ko 可能依赖 nls_utf8.ko5. 烧录新内核与模块部署5.1 编译内核镜像并烧录如果我们只编译了模块而内核本身配置没有其他改动那么理论上不需要重新烧录整个内核镜像boot.img或kernel.img。因为模块是独立文件只要内核版本uname -r输出与模块编译时使用的内核版本完全一致模块就可以被加载。如何确认版本一致性在开发板的Android系统上通过ADB执行adb shell cat /proc/version # 或 adb shell uname -r记下输出的内核版本号例如4.19.232-g5c3b2a9d。在编译主机上编译完内核后源码根目录会生成一个包含版本信息的头文件或Module.symvers。但最保险的方法是用同一个源码树、同一个配置既编译出当前设备运行的内核镜像也编译出模块。因此更推荐的做法是在menuconfig配置并保存后完整编译内核镜像如boot.img# 在SDK的根目录通常有编译Android和内核的脚本例如 build.sh 或 mkimage.sh # 这里给出通用思路具体请参考你的SDK文档 # 可能命令类似于 source build/envsetup.sh lunch rk3568_xxx-userdebug # 选择对应的产品午餐项 make bootimage -j$(nproc)编译完成后在out/target/product/rk3568_xxx/目录下会找到新的boot.img。使用瑞芯微的烧写工具如RKDevTool或fastboot仅烧录这个boot.img到开发板。务必确保只烧录boot分区避免擦除用户数据。5.2 推送模块文件到开发板将之前整理好的cifs_modules目录整个推送到开发板的/data/local/tmp/目录这个目录通常有读写权限adb push cifs_modules /data/local/tmp/5.3 加载内核模块通过ADB shell连接到开发板并加载模块。注意可能需要先加载依赖模块adb shell # 切换到模块所在目录 cd /data/local/tmp/cifs_modules # 加载依赖模块如果需要 insmod nls_utf8.ko # 加载CIFS主模块 insmod cifs.ko如果加载成功不会有任何输出。可以使用lsmod命令查看已加载的模块lsmod | grep cifs应该能看到cifs模块信息。重要提示默认情况下Android系统可能处于安全策略SELinux的 enforcing 模式这会阻止非系统分区加载内核模块。如果insmod失败并提示权限不足需要先获取root权限adb root或者将SELinux切换到permissive模式临时adb shell su # 如果已root setenforce 0 # 临时设置为宽容模式生产环境慎用调试完成后应恢复为setenforce 1。6. Windows共享设置与网络连通性测试6.1 设置Windows共享文件夹在Windows电脑上选择一个文件夹例如D:\ShareForRK3568右键点击 - “属性” - “共享”选项卡 - “高级共享”。勾选“共享此文件夹”。可以设置共享名例如RKShare。点击“权限”按钮确保至少给用于访问的用户或Everyone赋予“读取”或“更改/读取”权限。为了测试方便可以暂时给Everyone“完全控制”权限但生产环境务必使用最小权限原则。点击“确定”保存。此外需要确保Windows的网络发现和文件共享功能已开启。在“网络和共享中心” - “更改高级共享设置”中确保当前网络配置文件下“启用网络发现”和“启用文件和打印机共享”是打开状态。6.2 获取Windows主机的IP地址在Windows命令行cmd中执行ipconfig找到你当前连接网络的IPv4地址例如192.168.1.100。记下这个地址。6.3 测试网络连通性在RK3568开发板的Android shell中测试是否能ping通Windows主机ping -c 4 192.168.1.100如果收到回复说明网络层是通的。如果ping不通检查开发板和Windows主机是否在同一局域网段防火墙是否阻止了ICMP回显请求ping。对于Windows防火墙可能需要创建入站规则允许ICMPv4。7. Android端CIFS共享挂载实战7.1 创建本地挂载点在Android设备上需要创建一个目录作为“挂载点”远程共享的内容将出现在这个目录下。选择一个有权限的目录例如在/mnt或/storage下创建# 在Android shell中执行 mkdir -p /mnt/windows_share7.2 执行挂载命令挂载CIFS共享的基本命令格式如下mount -t cifs //Windows_IP/Share_Name /mnt/windows_share -o usernameYourUserName,passwordYourPassword,vers3.0让我们分解这个命令-t cifs: 指定文件系统类型为CIFS。//192.168.1.100/RKShare: 这是CIFS共享的UNC路径。192.168.1.100是Windows IPRKShare是共享名。/mnt/windows_share: 本地挂载点路径。-o: 引入挂载选项。username: Windows用户名。如果Windows登录使用了Microsoft账户可能是邮箱前缀如果是本地账户就是账户名。如果共享文件夹允许匿名访问可以尝试usernameguest,password密码为空。password: 对应用户的密码。vers3.0: 指定SMB协议版本。3.0是较新且高效的版本也支持2.1或2.0。如果遇到兼容性问题可以尝试降低版本如vers2.1。务必指定版本这是避免很多奇怪问题的关键。示例假设用户名为testuser密码为123456mount -t cifs //192.168.1.100/RKShare /mnt/windows_share -o usernametestuser,password123456,vers3.0如果命令执行后没有报错并且立刻返回到提示符通常意味着挂载成功。7.3 验证挂载结果使用df命令或mount命令查看已挂载的文件系统df -h | grep cifs # 或 mount | grep cifs你应该能看到一行记录显示//192.168.1.100/RKShare被挂载到了/mnt/windows_share。现在可以尝试列出挂载点内的文件ls -la /mnt/windows_share/如果能看到你在Windows共享文件夹里放置的文件恭喜你挂载成功了7.4 挂载选项详解与高级配置基本的挂载命令可能不够稳定或功能不全。下面是一些常用且重要的挂载选项iocharsetutf8: 指定字符集为UTF-8这对于正确显示中文、日文等非ASCII字符的文件名至关重要。通常与内核模块nls_utf8.ko配合使用。-o username...,password...,vers3.0,iocharsetutf8uid和gid: 指定挂载后文件/目录的默认所有者和所属组。在Android上你可以设置为shell用户或root用户的ID。查看当前shell的idid输出中uid2000(shell)那么uid2000。设置后你创建的文件权限会更合理。-o ...,uid2000,gid2000file_mode和dir_mode: 指定新建文件和目录的默认权限八进制。例如file_mode0644,dir_mode0755是常见的设置。noserverino: 一个非常重要的选项。CIFS服务器Windows和客户端对文件唯一标识符inode的处理方式可能不同这会导致ls -i命令显示错误的inode甚至引起某些应用程序问题。添加此选项可以让客户端自己生成稳定的inode号。-o ...,noserverinorw/ro: 读写或只读挂载默认为rw。soft/hard: 指定网络中断时的行为。soft会在重试失败后让系统调用返回错误hard会一直重试默认。对于移动设备soft可能更合适避免应用卡死。一个相对健壮的挂载命令示例mount -t cifs //192.168.1.100/RKShare /mnt/windows_share -o usernametestuser,password123456,vers3.0,iocharsetutf8,uid2000,gid2000,file_mode0644,dir_mode0755,noserverino,soft8. 常见问题排查与实战技巧8.1 挂载失败mount: No such device问题现象执行mount命令时提示mount: No such device。原因分析内核中没有CIFS文件系统支持。可能模块未加载或者编译进内核的CIFS支持未启用。解决方案检查CIFS模块是否已加载lsmod | grep cifs。如果未加载尝试手动加载insmod /path/to/cifs.ko并检查依赖模块如nls_utf8是否已加载。如果模块加载失败检查内核版本是否匹配以及SELinux是否阻止。8.2 挂载失败mount: Operation not permitted问题现象提示权限不足。原因分析SELinux限制这是Android上最常见的原因。即使有root权限SELinux的enforcing模式也会阻止非系统域进程执行挂载操作。挂载点路径权限创建的挂载点目录所属用户或权限不对。解决方案临时方案调试用将SELinux切换到宽容模式setenforce 0。挂载成功后可以切回setenforce 1。永久方案需修改系统需要修改SELinux策略文件*.te为你的应用或shell域添加挂载CIFS的权限。这涉及到Android系统重新编译比较复杂。检查挂载点确保/mnt/windows_share目录存在并且当前用户有进入和执行权限。8.3 挂载失败mount: Permission denied问题现象提示权限被拒绝。原因分析这通常指的是CIFS服务器Windows拒绝了连接请求而非本地Android权限问题。解决方案检查Windows共享权限确认你使用的用户名和密码正确并且该用户在Windows上对此共享文件夹有访问权限。可以尝试在Windows上用另一台电脑访问此共享验证凭据和权限。检查Windows防火墙确保Windows防火墙允许SMB入站连接。可以在“高级安全Windows防火墙”中为“文件和打印机共享(SMB-In)”规则启用对应网络类型的配置文件专用、公用。尝试匿名访问使用usernameguest,password空密码尝试挂载。如果成功说明是凭据问题。指定SMB协议版本明确指定vers2.1或vers3.0。某些旧版Windows或特定配置可能对协议版本有要求。8.4 可以挂载但无法显示/写入中文文件名问题现象英文文件正常中文文件名显示为乱码或问号。原因分析字符编码不匹配。Windows通常使用UTF-16或本地代码页而Linux默认可能是UTF-8。解决方案确保加载了nls_utf8.ko模块。在挂载命令中明确指定iocharsetutf8选项。如果还不行可以尝试Windows侧的设置在Windows注册表中为SMB服务器启用Unicode支持需谨慎操作或者尝试在挂载时使用iocharsetcp936对应GBK简体中文但UTF-8是更通用的解决方案。8.5 连接不稳定偶尔断开问题现象挂载成功后一段时间不操作再访问时可能卡住或报错。原因分析网络波动、Windows电源管理导致网卡休眠、或SMB会话超时。解决方案使用hard挂载选项默认但结合合理的超时设置hard,timeo600,retrans2。timeo是超时时间十分之一秒为单位retrans是重试次数。在Windows电源管理设置中禁用“允许计算机关闭此设备以节约电源”针对网络适配器。在挂载命令中添加nostrictsync选项这可以缓解某些缓存同步导致的延迟。考虑使用soft选项让应用更快得到错误反馈而不是无限等待。8.6 开机自动挂载对于产品化需求可能需要开机自动挂载CIFS共享。在标准Linux中可以修改/etc/fstab。但在Android中/etc/fstab通常用于系统分区且早期启动阶段网络可能未就绪。推荐方案编写一个init服务脚本.rc文件在net服务启动后执行挂载。这需要修改Android系统的启动镜像boot.img或vendor_boot.img并重新编译系统。对于开发者调试一个更简单但不优雅的方法是将编译好的.ko模块文件放到系统分区如/vendor/lib/modules/并确保开机脚本如init.rc或init.${hardware}.rc中加载它们。创建一个shell脚本包含加载模块和挂载命令放在/data/local/下。利用Android的init机制在post-fs-data阶段此时/data已挂载或late-init阶段通过exec或service来执行这个脚本。由于这涉及系统定制具体步骤取决于你的Android系统版本和厂商定制程度这里不展开。一个取巧的办法是利用Magisk模块它可以在不修改系统镜像的情况下在启动时注入脚本。8.7 性能优化建议协议版本使用vers3.0或更高SMB3.0在性能和安全性上优于旧版本。大文件读写可以尝试调整rsize和wsize参数即读写缓冲区大小。例如rsize1048576,wsize10485761MB。但并非越大越好需要根据网络质量测试。缓存CIFS客户端有缓存机制。对于读多写少的场景默认设置尚可。对于频繁写入如果对数据一致性要求不是极端实时可以添加cachestrict或cacheloose选项来调整缓存行为。网络质量这是最大的影响因素。确保开发板和Windows主机之间是稳定的有线或高速Wi-Fi连接。9. 安全考量与生产环境建议在调试阶段我们为了方便可能会使用简单密码甚至匿名访问。但在实际生产部署中必须考虑安全最小权限原则在Windows端为CIFS访问创建专用用户并仅授予该用户对特定共享文件夹的必要权限只读或读写。强密码避免使用弱密码。禁用SMB1SMB1协议存在严重安全漏洞且效率低下。在Windows上应禁用SMB1并在挂载时使用vers2.1或vers3.0。网络隔离如果可能将提供共享的Windows主机和RK3568设备置于独立的VLAN或子网中限制访问来源。避免存储凭据在脚本中硬编码用户名密码是危险的。可以考虑使用凭据文件credentials/path/to/secret.txt并妥善设置该文件的权限仅root可读。在Android环境下也可以探索使用Keystore系统来安全地存储凭据。SELinux策略在产品化时应编写正确的SELinux策略仅允许特定的系统服务或应用域进行CIFS挂载操作而不是简单地setenforce 0。整个流程从内核编译到成功挂载步骤虽多但脉络清晰。最关键的是确保内核模块与运行内核版本一致以及处理好Android特有的SELinux权限问题。一旦打通RK3568开发板就能像本地磁盘一样方便地访问Windows网络资源为各种嵌入式应用场景打开了新的可能性。
RK3568 Android 13挂载Windows共享文件夹:CIFS内核编译与实战指南
1. 项目概述与核心价值最近在RK3568平台上折腾Android 13系统有个需求挺常见怎么让开发板直接访问我Windows电脑上的共享文件夹无论是调试时传输大文件还是想直接播放电脑里的媒体资源如果能像访问本地存储一样操作网络共享效率会高很多。传统的ADB推拉文件或者U盘拷贝在频繁操作和大文件场景下体验确实不够丝滑。这个需求的核心就是要在Android系统上实现CIFSCommon Internet File System协议的网络文件系统挂载。CIFS是SMBServer Message Block协议的一个实现也是Windows网络共享的“标准语言”。在Linux内核的Android系统上通过内核模块支持CIFS就能将远程的Windows共享目录“映射”成本地的一个目录路径应用可以无感地读写其中的文件。以瑞芯微的iTOP-RK3568开发板为例它搭载了四核Cortex-A55处理器性能足以应对轻量级的网络文件系统操作。在Android 13系统上实现这一功能不仅对开发者调试、文件管理有直接帮助对于构建基于RK3568的智能终端如广告机、数字标牌、工控设备也很有意义——可以方便地从中心服务器更新内容。接下来我会详细拆解从环境准备、内核配置、到挂载调试的全过程并分享几个我踩过坑才总结出来的关键技巧。2. 整体方案设计与思路拆解2.1 为什么选择CIFS协议在Linux/Android环境下访问网络存储常见的协议有NFS和CIFS/SMB。NFS在Unix/Linux世界更原生性能可能稍好但Windows默认并不开启NFS服务需要额外安装功能。而CIFS/SMB协议是Windows网络邻居和文件共享的基石几乎每台Windows电脑都默认支持。为了让开发板能无缝访问最常见的Windows共享选择CIFS协议是更通用、更便捷的方案。Android系统本质上是一个运行在Linux内核之上的特殊用户空间。因此在Android上挂载CIFS共享其底层原理与在标准Linux上并无二致需要内核支持CIFS文件系统模块并在用户空间通过mount命令或相应API发起挂载请求。难点在于很多Android设备厂商为了系统精简和安全默认内核编译时并未将CIFS支持编译进去或者仅编译为模块但未在系统中提供。2.2 iTOP-RK3568开发板方案选型对于iTOP-RK3568开发板我们通常有两种路径来实现CIFS挂载使用预编译的内核模块如果存在最理想的情况是开发板供应商已经提供了编译好的CIFS内核模块.ko文件。我们只需要将其推送到设备加载模块然后执行挂载命令即可。这种方式最快捷但依赖于供应商的支持。自行编译内核或内核模块如果供应商未提供或者提供的模块与当前系统内核版本不匹配我们就需要获取RK3568 Android 13对应的内核源码自行配置并编译出包含CIFS支持的内核或内核模块。考虑到通用性和学习价值本文将重点阐述第二种方案即从源码编译开始。这个过程虽然步骤较多但能让你彻底掌握如何为特定Android内核添加功能这项技能在嵌入式开发中非常有用。我们会基于瑞芯微官方或开发板供应商提供的SDK进行。2.3 操作流程总览整个实现过程可以梳理为以下几个关键阶段我将按顺序详细展开环境准备搭建用于编译RK3568内核的Linux开发环境获取正确的内核源码。内核配置与编译在内核配置中开启CIFS支持并编译生成新的内核镜像或模块。镜像烧写与验证将新编译的内核烧录到iTOP-RK3568开发板并启动验证。Windows共享设置在PC端设置一个用于测试的共享文件夹并确保网络互通。Android端挂载操作在开发板的Android系统上执行挂载命令访问Windows共享。问题排查与优化解决可能遇到的权限、网络、稳定性等问题并探讨自动化挂载方案。注意内核编译和烧写存在一定风险操作不当可能导致设备无法启动。请务必在开始前备份重要数据并确保你有能力通过MaskRom模式等救砖手段恢复设备。3. 环境准备与内核源码获取3.1 编译环境搭建内核编译推荐在Linux系统下进行。你可以使用实体机安装Ubuntu 20.04 LTS或22.04 LTS也可以使用虚拟机。建议分配至少8GB内存和100GB硬盘空间编译过程比较消耗资源。首先安装必要的编译工具链和依赖包sudo apt update sudo apt install -y git-core gnupg flex bison build-essential zip curl zlib1g-dev \ libc6-dev-i386 libncurses5 lib32ncurses5-dev x11proto-core-dev libx11-dev \ lib32z1-dev libgl1-mesa-dev libxml2-utils xsltproc unzip fontconfig python3 \ device-tree-compiler u-boot-tools对于RK3568我们通常使用Android官方或Rockchip定制的交叉编译工具链如aarch64-linux-android-4.9。这个工具链一般包含在完整的Android SDK中。3.2 获取内核源码你需要从开发板供应商如iTOP或瑞芯微官方渠道获取与你的Android 13系统版本完全匹配的内核源码。通常供应商会提供一个SDK包里面包含了kernel/目录。假设你已经拿到了SDK将其解压。内核源码的路径通常类似于path/to/sdk/kernel/。进入该目录cd path/to/sdk/kernel在开始配置前先确定当前内核的配置文件。对于RK3568配置文件名通常是rockchip_defconfig或其变体如rk3568-android.config。你可以通过查看arch/arm64/configs/目录下的文件来确认。ls arch/arm64/configs/ | grep -i rk3568假设找到的配置是rk3568_android_defconfig。这个文件定义了该开发板内核编译的默认选项。4. 内核配置与CIFS模块编译4.1 加载默认配置并启动菜单配置首先导入默认的板级配置并启动图形化或文本配置界面进行修改# 清理之前的编译中间文件如果是首次可跳过 make ARCHarm64 CROSS_COMPILEaarch64-linux-android- mrproper # 应用默认配置 make ARCHarm64 CROSS_COMPILEaarch64-linux-android- rk3568_android_defconfig # 启动menuconfig配置界面 make ARCHarm64 CROSS_COMPILEaarch64-linux-android- menuconfigCROSS_COMPILE指定了交叉编译工具链的前缀。你需要根据SDK中工具链的实际路径和名称进行调整例如如果工具链gcc的完整路径是/path/to/toolchain/bin/aarch64-linux-android-gcc那么CROSS_COMPILE就应该是/path/to/toolchain/bin/aarch64-linux-android-。执行menuconfig命令后会进入一个基于ncurses的文本图形配置界面。4.2 定位并启用CIFS支持在menuconfig界面中使用键盘方向键导航按/键可以搜索配置项。我们输入“CIFS”进行搜索。搜索结果会显示CONFIG_CIFS等相关选项及其所在位置。通常CIFS相关的配置位于File systems --- Network File Systems --- * CIFS support (advanced network filesystem, SMB3.0, SMB2.1, SMB2 and also SMB1.1)使用方向键进入File systems-Network File Systems菜单。在这里你会看到CIFS support选项。按空格键可以切换其状态 不编译。M编译为内核模块.ko文件运行时动态加载。*直接编译进内核镜像。选择建议编译为模块 (M): 这是更灵活的选择。模块可以单独加载和卸载不会增大内核镜像的体积方便调试和更新。对于我们的需求推荐此选项。编译进内核 (*): 功能永远可用无需手动加载模块但内核镜像会稍大。将光标移动到CIFS support上按M键使其显示为M。选中后其下的子选项如CIFS statisticsExtended attributes等也会变为可配置状态。对于基本功能保持默认即可但建议将CIFS extended attributes (experimental)和CIFS POSIX Extensions也选为M以支持更完整的文件属性。此外为了支持更现代的SMB2.1、SMB3.0协议Windows 8/10/11默认使用确保CIFS SMB2 and SMB3 support (experimental)也被启用同样设为M。配置完成后按左右键选择 Save 直接按回车使用默认的.config文件名保存配置然后选择 Exit 退出menuconfig。4.3 编译内核模块现在开始编译我们配置好的内核模块# 编译内核模块。 -j$(nproc) 表示使用所有CPU核心并行编译加快速度。 make ARCHarm64 CROSS_COMPILEaarch64-linux-android- -j$(nproc) modules编译过程需要一段时间。完成后我们需要的CIFS模块文件.ko会在对应的内核源码子目录中生成。CIFS主模块通常位于fs/cifs/cifs.ko同时其依赖的其他模块如nls_utf8.ko用于UTF-8编码支持也会被编译出来它们通常位于fs/nls/目录下。实操心得编译时如果遇到错误首先检查CROSS_COMPILE路径是否正确以及工具链版本是否与内核源码匹配。错误信息通常是定位问题的关键。另一个常见问题是依赖缺失回顾“环境准备”步骤确保所有开发包都已安装。4.4 提取与整理模块文件编译完成后我们需要将生成的.ko文件从复杂的源码目录结构中找出来。可以使用find命令find . -name *.ko -type f | grep -E (cifs|nls_utf8) | head -10假设我们找到了以下关键模块fs/cifs/cifs.kofs/nls/nls_utf8.ko(CIFS访问中文目录/文件可能需要)将这些模块文件复制到一个单独的目录方便后续打包推送到开发板mkdir ../cifs_modules cp fs/cifs/cifs.ko ../cifs_modules/ cp fs/nls/nls_utf8.ko ../cifs_modules/ # 可能还需要其他依赖如 fs/ksmbd/ksmbd.ko (如果配置了ksmbd客户端)根据编译日志和模块依赖决定。可以使用modinfo命令查看模块的依赖关系# 需要在x86主机上使用对应的工具链中的工具或者将模块放到设备上用modinfo查看 # 这里演示概念cifs.ko 可能依赖 nls_utf8.ko5. 烧录新内核与模块部署5.1 编译内核镜像并烧录如果我们只编译了模块而内核本身配置没有其他改动那么理论上不需要重新烧录整个内核镜像boot.img或kernel.img。因为模块是独立文件只要内核版本uname -r输出与模块编译时使用的内核版本完全一致模块就可以被加载。如何确认版本一致性在开发板的Android系统上通过ADB执行adb shell cat /proc/version # 或 adb shell uname -r记下输出的内核版本号例如4.19.232-g5c3b2a9d。在编译主机上编译完内核后源码根目录会生成一个包含版本信息的头文件或Module.symvers。但最保险的方法是用同一个源码树、同一个配置既编译出当前设备运行的内核镜像也编译出模块。因此更推荐的做法是在menuconfig配置并保存后完整编译内核镜像如boot.img# 在SDK的根目录通常有编译Android和内核的脚本例如 build.sh 或 mkimage.sh # 这里给出通用思路具体请参考你的SDK文档 # 可能命令类似于 source build/envsetup.sh lunch rk3568_xxx-userdebug # 选择对应的产品午餐项 make bootimage -j$(nproc)编译完成后在out/target/product/rk3568_xxx/目录下会找到新的boot.img。使用瑞芯微的烧写工具如RKDevTool或fastboot仅烧录这个boot.img到开发板。务必确保只烧录boot分区避免擦除用户数据。5.2 推送模块文件到开发板将之前整理好的cifs_modules目录整个推送到开发板的/data/local/tmp/目录这个目录通常有读写权限adb push cifs_modules /data/local/tmp/5.3 加载内核模块通过ADB shell连接到开发板并加载模块。注意可能需要先加载依赖模块adb shell # 切换到模块所在目录 cd /data/local/tmp/cifs_modules # 加载依赖模块如果需要 insmod nls_utf8.ko # 加载CIFS主模块 insmod cifs.ko如果加载成功不会有任何输出。可以使用lsmod命令查看已加载的模块lsmod | grep cifs应该能看到cifs模块信息。重要提示默认情况下Android系统可能处于安全策略SELinux的 enforcing 模式这会阻止非系统分区加载内核模块。如果insmod失败并提示权限不足需要先获取root权限adb root或者将SELinux切换到permissive模式临时adb shell su # 如果已root setenforce 0 # 临时设置为宽容模式生产环境慎用调试完成后应恢复为setenforce 1。6. Windows共享设置与网络连通性测试6.1 设置Windows共享文件夹在Windows电脑上选择一个文件夹例如D:\ShareForRK3568右键点击 - “属性” - “共享”选项卡 - “高级共享”。勾选“共享此文件夹”。可以设置共享名例如RKShare。点击“权限”按钮确保至少给用于访问的用户或Everyone赋予“读取”或“更改/读取”权限。为了测试方便可以暂时给Everyone“完全控制”权限但生产环境务必使用最小权限原则。点击“确定”保存。此外需要确保Windows的网络发现和文件共享功能已开启。在“网络和共享中心” - “更改高级共享设置”中确保当前网络配置文件下“启用网络发现”和“启用文件和打印机共享”是打开状态。6.2 获取Windows主机的IP地址在Windows命令行cmd中执行ipconfig找到你当前连接网络的IPv4地址例如192.168.1.100。记下这个地址。6.3 测试网络连通性在RK3568开发板的Android shell中测试是否能ping通Windows主机ping -c 4 192.168.1.100如果收到回复说明网络层是通的。如果ping不通检查开发板和Windows主机是否在同一局域网段防火墙是否阻止了ICMP回显请求ping。对于Windows防火墙可能需要创建入站规则允许ICMPv4。7. Android端CIFS共享挂载实战7.1 创建本地挂载点在Android设备上需要创建一个目录作为“挂载点”远程共享的内容将出现在这个目录下。选择一个有权限的目录例如在/mnt或/storage下创建# 在Android shell中执行 mkdir -p /mnt/windows_share7.2 执行挂载命令挂载CIFS共享的基本命令格式如下mount -t cifs //Windows_IP/Share_Name /mnt/windows_share -o usernameYourUserName,passwordYourPassword,vers3.0让我们分解这个命令-t cifs: 指定文件系统类型为CIFS。//192.168.1.100/RKShare: 这是CIFS共享的UNC路径。192.168.1.100是Windows IPRKShare是共享名。/mnt/windows_share: 本地挂载点路径。-o: 引入挂载选项。username: Windows用户名。如果Windows登录使用了Microsoft账户可能是邮箱前缀如果是本地账户就是账户名。如果共享文件夹允许匿名访问可以尝试usernameguest,password密码为空。password: 对应用户的密码。vers3.0: 指定SMB协议版本。3.0是较新且高效的版本也支持2.1或2.0。如果遇到兼容性问题可以尝试降低版本如vers2.1。务必指定版本这是避免很多奇怪问题的关键。示例假设用户名为testuser密码为123456mount -t cifs //192.168.1.100/RKShare /mnt/windows_share -o usernametestuser,password123456,vers3.0如果命令执行后没有报错并且立刻返回到提示符通常意味着挂载成功。7.3 验证挂载结果使用df命令或mount命令查看已挂载的文件系统df -h | grep cifs # 或 mount | grep cifs你应该能看到一行记录显示//192.168.1.100/RKShare被挂载到了/mnt/windows_share。现在可以尝试列出挂载点内的文件ls -la /mnt/windows_share/如果能看到你在Windows共享文件夹里放置的文件恭喜你挂载成功了7.4 挂载选项详解与高级配置基本的挂载命令可能不够稳定或功能不全。下面是一些常用且重要的挂载选项iocharsetutf8: 指定字符集为UTF-8这对于正确显示中文、日文等非ASCII字符的文件名至关重要。通常与内核模块nls_utf8.ko配合使用。-o username...,password...,vers3.0,iocharsetutf8uid和gid: 指定挂载后文件/目录的默认所有者和所属组。在Android上你可以设置为shell用户或root用户的ID。查看当前shell的idid输出中uid2000(shell)那么uid2000。设置后你创建的文件权限会更合理。-o ...,uid2000,gid2000file_mode和dir_mode: 指定新建文件和目录的默认权限八进制。例如file_mode0644,dir_mode0755是常见的设置。noserverino: 一个非常重要的选项。CIFS服务器Windows和客户端对文件唯一标识符inode的处理方式可能不同这会导致ls -i命令显示错误的inode甚至引起某些应用程序问题。添加此选项可以让客户端自己生成稳定的inode号。-o ...,noserverinorw/ro: 读写或只读挂载默认为rw。soft/hard: 指定网络中断时的行为。soft会在重试失败后让系统调用返回错误hard会一直重试默认。对于移动设备soft可能更合适避免应用卡死。一个相对健壮的挂载命令示例mount -t cifs //192.168.1.100/RKShare /mnt/windows_share -o usernametestuser,password123456,vers3.0,iocharsetutf8,uid2000,gid2000,file_mode0644,dir_mode0755,noserverino,soft8. 常见问题排查与实战技巧8.1 挂载失败mount: No such device问题现象执行mount命令时提示mount: No such device。原因分析内核中没有CIFS文件系统支持。可能模块未加载或者编译进内核的CIFS支持未启用。解决方案检查CIFS模块是否已加载lsmod | grep cifs。如果未加载尝试手动加载insmod /path/to/cifs.ko并检查依赖模块如nls_utf8是否已加载。如果模块加载失败检查内核版本是否匹配以及SELinux是否阻止。8.2 挂载失败mount: Operation not permitted问题现象提示权限不足。原因分析SELinux限制这是Android上最常见的原因。即使有root权限SELinux的enforcing模式也会阻止非系统域进程执行挂载操作。挂载点路径权限创建的挂载点目录所属用户或权限不对。解决方案临时方案调试用将SELinux切换到宽容模式setenforce 0。挂载成功后可以切回setenforce 1。永久方案需修改系统需要修改SELinux策略文件*.te为你的应用或shell域添加挂载CIFS的权限。这涉及到Android系统重新编译比较复杂。检查挂载点确保/mnt/windows_share目录存在并且当前用户有进入和执行权限。8.3 挂载失败mount: Permission denied问题现象提示权限被拒绝。原因分析这通常指的是CIFS服务器Windows拒绝了连接请求而非本地Android权限问题。解决方案检查Windows共享权限确认你使用的用户名和密码正确并且该用户在Windows上对此共享文件夹有访问权限。可以尝试在Windows上用另一台电脑访问此共享验证凭据和权限。检查Windows防火墙确保Windows防火墙允许SMB入站连接。可以在“高级安全Windows防火墙”中为“文件和打印机共享(SMB-In)”规则启用对应网络类型的配置文件专用、公用。尝试匿名访问使用usernameguest,password空密码尝试挂载。如果成功说明是凭据问题。指定SMB协议版本明确指定vers2.1或vers3.0。某些旧版Windows或特定配置可能对协议版本有要求。8.4 可以挂载但无法显示/写入中文文件名问题现象英文文件正常中文文件名显示为乱码或问号。原因分析字符编码不匹配。Windows通常使用UTF-16或本地代码页而Linux默认可能是UTF-8。解决方案确保加载了nls_utf8.ko模块。在挂载命令中明确指定iocharsetutf8选项。如果还不行可以尝试Windows侧的设置在Windows注册表中为SMB服务器启用Unicode支持需谨慎操作或者尝试在挂载时使用iocharsetcp936对应GBK简体中文但UTF-8是更通用的解决方案。8.5 连接不稳定偶尔断开问题现象挂载成功后一段时间不操作再访问时可能卡住或报错。原因分析网络波动、Windows电源管理导致网卡休眠、或SMB会话超时。解决方案使用hard挂载选项默认但结合合理的超时设置hard,timeo600,retrans2。timeo是超时时间十分之一秒为单位retrans是重试次数。在Windows电源管理设置中禁用“允许计算机关闭此设备以节约电源”针对网络适配器。在挂载命令中添加nostrictsync选项这可以缓解某些缓存同步导致的延迟。考虑使用soft选项让应用更快得到错误反馈而不是无限等待。8.6 开机自动挂载对于产品化需求可能需要开机自动挂载CIFS共享。在标准Linux中可以修改/etc/fstab。但在Android中/etc/fstab通常用于系统分区且早期启动阶段网络可能未就绪。推荐方案编写一个init服务脚本.rc文件在net服务启动后执行挂载。这需要修改Android系统的启动镜像boot.img或vendor_boot.img并重新编译系统。对于开发者调试一个更简单但不优雅的方法是将编译好的.ko模块文件放到系统分区如/vendor/lib/modules/并确保开机脚本如init.rc或init.${hardware}.rc中加载它们。创建一个shell脚本包含加载模块和挂载命令放在/data/local/下。利用Android的init机制在post-fs-data阶段此时/data已挂载或late-init阶段通过exec或service来执行这个脚本。由于这涉及系统定制具体步骤取决于你的Android系统版本和厂商定制程度这里不展开。一个取巧的办法是利用Magisk模块它可以在不修改系统镜像的情况下在启动时注入脚本。8.7 性能优化建议协议版本使用vers3.0或更高SMB3.0在性能和安全性上优于旧版本。大文件读写可以尝试调整rsize和wsize参数即读写缓冲区大小。例如rsize1048576,wsize10485761MB。但并非越大越好需要根据网络质量测试。缓存CIFS客户端有缓存机制。对于读多写少的场景默认设置尚可。对于频繁写入如果对数据一致性要求不是极端实时可以添加cachestrict或cacheloose选项来调整缓存行为。网络质量这是最大的影响因素。确保开发板和Windows主机之间是稳定的有线或高速Wi-Fi连接。9. 安全考量与生产环境建议在调试阶段我们为了方便可能会使用简单密码甚至匿名访问。但在实际生产部署中必须考虑安全最小权限原则在Windows端为CIFS访问创建专用用户并仅授予该用户对特定共享文件夹的必要权限只读或读写。强密码避免使用弱密码。禁用SMB1SMB1协议存在严重安全漏洞且效率低下。在Windows上应禁用SMB1并在挂载时使用vers2.1或vers3.0。网络隔离如果可能将提供共享的Windows主机和RK3568设备置于独立的VLAN或子网中限制访问来源。避免存储凭据在脚本中硬编码用户名密码是危险的。可以考虑使用凭据文件credentials/path/to/secret.txt并妥善设置该文件的权限仅root可读。在Android环境下也可以探索使用Keystore系统来安全地存储凭据。SELinux策略在产品化时应编写正确的SELinux策略仅允许特定的系统服务或应用域进行CIFS挂载操作而不是简单地setenforce 0。整个流程从内核编译到成功挂载步骤虽多但脉络清晰。最关键的是确保内核模块与运行内核版本一致以及处理好Android特有的SELinux权限问题。一旦打通RK3568开发板就能像本地磁盘一样方便地访问Windows网络资源为各种嵌入式应用场景打开了新的可能性。