日期:2026-10-17
起因:评估把网络共享迁移到 Android 设备时,发现“内核模块”是整个方案的硬约束。顺着这个问题往下查,发现它不是一个设备的问题,而是四种操作系统在内核扩展机制上的路线差异,最终集中体现在 Android 这个最尴尬的位置上。
本文整理内核模块的加载机制、四种系统的驱动模型对比,以及 Android 为什么卡在中间。文中 Android 设备以“未开源内核源码的机型”代称。

目录

  1. 问题从哪来

  2. 内核能力的两种形态与加载约束

  3. 四种系统的驱动模型

  4. 对比:谁能扩展内核,谁有用户态出口

  5. 难题:Android 是唯一“两头不靠”的系统

  6. 实测边界

  7. 设计原则

  8. 总结

1. 问题从哪来

评估把网络共享方案迁移到 Android 设备时,遇到一个绕不过去的约束:需要 NFS 挂载,但没有 nfs.ko 模块,也没有内核源码可以自己编译。

顺着这个问题往下查:

  • Linux 桌面为什么能加模块?因为有源码和 headers。

  • Windows 也锁内核,为什么没人觉得受限?因为有 UMDF 用户态驱动框架。

  • macOS 为什么能废弃 kext?因为有 DriverKit 作为替代。

  • 鸿蒙为什么没有“模块”问题?因为驱动本来就不在内核里。

四个系统都在回答同一个问题:驱动代码跑在哪,谁有权往里加东西? 答案各不相同。而 Android 的答案是:继承了宏内核的架构,锁死了模块能力,又没有提供用户态出口。

2. 内核能力的两种形态与加载约束

2.1 两种形态

形态编译选项运行方式能否事后补充
编译进内核CONFIG_X=y开机即加载出厂定死
内核模块CONFIG_X=m生成 .ko,按需加载需要匹配的模块文件

2.2 模块加载的四道约束

约束说明
vermagic模块编译时的内核版本字符串必须与 uname -r 匹配
符号依赖模块引用的内核符号必须在 /proc/kallsyms 中导出
ABI 兼容内核数据结构、函数签名在版本间变化,跨版本模块运行时崩溃
模块签名CONFIG_MODULE_SIG_FORCE=y 时,未签名模块被拒绝

四道约束全过,模块才能加载。没有内核源码,就无法为新版本重新编译模块。

3. 四种系统的驱动模型

3.1 Linux:宏内核,模块运行在内核态

Linux 是宏内核。模块加载后运行在内核空间,拥有完整内核权限。

自由度来自源码和工具链的可得性:

  • 发行版提供 linux-headers 包;

  • DKMS 可以在内核升级后自动重编第三方模块;

  • 主流发行版默认不强制模块签名。

代价是模块与内核版本强绑定,且驱动 bug 的爆炸半径是整个系统。

3.2 Windows:混合内核,内核态与用户态驱动并存

Windows 的驱动模型分两层:

框架运行位置崩溃影响
WDM / KMDF内核态可能蓝屏(BSOD)
UMDF用户态(沙盒进程)仅进程崩溃,系统不受影响

UMDF 的意义:对于不需要直接操作硬件的设备类(传感器、摄像头、USB 协议设备),可以完全避开内核态风险。微软官方文档把“提高系统稳定性”列为 UMDF 的首要优势。

所以 Windows 的“内核锁死”只锁内核态驱动。用户态驱动是官方提供的出口。

3.3 macOS:从 kext 到 DriverKit,主动把驱动推出内核

macOS 内核(XNU)是 Mach 与 BSD 的混合体。历史上驱动以 kext 形式运行在内核态。

但从 macOS Catalina(10.15)开始,Apple 系统性废弃 kext,推动驱动迁移到用户态:

机制运行位置状态
kext内核态逐步淘汰
DriverKit(dext)用户态官方替代
System Extension用户态安全/网络等功能

Apple 的规则很直接:从 macOS 11 开始,如果存在等效的 System Extension 或 DriverKit 方案,内核就不会加载 kext。

macOS 在用架构手段把驱动推出内核,用稳定性换一点性能开销。

3.4 鸿蒙:微内核,驱动完全在用户态

鸿蒙内核是微内核,只保留进程调度、内存管理、IPC 等最核心功能。文件系统、驱动、网络服务全部运行在用户态。

驱动在鸿蒙上的运行方式:

  • 加载到用户态执行;

  • 被限制在 EL0 权限(用户态特权级),无法提升到内核 EL1 层;

  • 每个用户态服务或驱动拥有独立地址空间,只通过 IPC 互通。

即使一个驱动被攻破,攻击者拿到的也只是 EL0 权限,无法触及内核。代价是 IPC 通信开销,通过零拷贝、异步 IPC 和 HDF 框架缓解。

鸿蒙的“内核模块”问题不存在——驱动从一开始就不在内核里。

4. 对比:谁能扩展内核,谁有用户态出口

系统内核架构驱动运行位置扩展内核的路径用户态出口
Linux 桌面宏内核内核态有源码、有 headers、DKMS无(驱动只能在内核态)
嵌入式 Linux宏内核内核态厂商提供 kmod-* 包无
Windows混合内核KMDF 内核态 / UMDF 用户态内核态驱动受签名约束UMDF
macOS混合内核kext 内核态 / DriverKit 用户态kext 逐步淘汰DriverKit / System Extension
鸿蒙微内核全部用户态驱动本来就不在内核里架构本身
Android(未开源内核源码的机型)宏内核内核态无源码、无 headers、签名强制无

关键差异不在“内核锁不锁”,而在锁了之后有没有别的路走。

  • Linux 桌面:不锁,能加模块。

  • Windows:锁内核态驱动,但 UMDF 提供用户态出口。

  • macOS:主动收缩内核边界,DriverKit 是官方替代路径。

  • 鸿蒙:驱动从一开始就在用户态。

  • Android:锁死模块能力,同时没有用户态驱动框架。

5. 难题:Android 是唯一“两头不靠”的系统

Android 的处境是四个系统里唯一“两头不靠”的:

架构上,它继承了 Linux 的宏内核。 驱动和文件系统必须编译进内核或加载模块,没有 Windows UMDF、macOS DriverKit、鸿蒙微内核那样的用户态驱动框架。任何需要内核级能力的任务,只能走模块这条路。

生态上,模块这条路被锁死了。 对于未开源内核源码的机型,三重限制叠加:

text

第一重:内核出厂一次性编译,厂商不再更新
第二重:内核源码不公开,无法自行编译模块
第三重:模块签名强制,未签名模块被拒绝

结果是:出厂没编译的能力,永久不可用。

替代上,它没有官方的用户态出口。 Windows 用户可以完全不碰内核态驱动,macOS 用户有 DriverKit,鸿蒙的驱动本来就在用户态。Android 没有等价物——想加功能,要么走模块(走不通),要么靠用户态程序(FUSE、TUN)自己凑,而用户态替代能覆盖的功能是有限的。

所以真正的难题不是“Android 没有某个模块”,而是:

未开源内核源码的 Android 机型,是唯一一个既不能加内核模块、也没有用户态驱动框架的系统。

这不是一个可以绕过或变通的技术障碍,而是架构选择、生态策略、厂商行为三者叠加后的结构性结果。

6. 实测边界

6.1 未 root 的 Android 设备(Android 12,5.10 内核,proot 容器)

内核能力实测结论
NFS 客户端(/proc/net/rpc)不存在无
NFS 服务端(/proc/fs/nfsd)目录存在但空有残留无服务
mount / proot无 CAP_SYS_ADMIN(CapBnd=0)任何内核挂载都不可行
FUSEAndroid 必有(/sdcard 模拟就是它)用户态挂载可行

6.2 已 root 的 Android 设备(arm64,chroot)

项情况
架构arm64
root + chroot有 CAP_SYS_ADMIN / CAP_NET_ADMIN
内核源码不公开 → NFS/cifs 模块永久不可用
TUNAndroid 必有(VPN 功能)→ root 后可开真 tun0

6.3 Debian 机顶盒(armv7l)

项实测
内核模块Debian 真内核,apt install 即装
cpufreq不存在
cpuidle不存在 → CPU 永远满频

机顶盒是“有内核自由 + NFS 能力”的设备,适合承担内核级任务。

6.4 NFS 与 SMB 的路径差异

项目NFSSMB/CIFS
内核版nfs.ko(必须内核模块)cifs.ko(必须内核模块)
用户态替代无挂载级替代(libnfs 只能读写不能挂载)rclone / sshfs(FUSE)能挂载
Android 上的路径死路,只能换协议FUSE 用户态挂载

FUSE 用户态挂载比内核版慢约 30-50%,但配置同步、文档类 KB 级场景感知不到差距。

7. 设计原则

text

1. 只用"出厂必带"的内核能力:socket / TUN / FUSE
2. 不依赖"需要加载模块"的能力:NFS 挂载 / cifs / 新文件系统
3. 网络共享:
   - 有内核自由度的设备继续当 NFS 服务器
   - 受限设备用 sshfs / rclone / rsync(FUSE 用户态)
4. 组网:root 设备用 TUN,无 root 设备走普通 socket 服务
5. 把需要内核自由度的任务分配给有自由度的设备

判断标准很简单:这个功能需不需要内核模块?需要,就永久做不到。不需要,就看用户态能不能凑。

8. 总结

四种系统在内核扩展机制上的路线:

系统路线结果
Linux宏内核,模块可加载自由
Windows混合内核,UMDF 用户态出口锁内核但不锁功能
macOS主动把驱动推出内核锁内核但不锁功能
鸿蒙微内核,驱动本来就在用户态架构本身解决
Android(未开源内核源码的机型)宏内核 + 生态锁死 + 无用户态出口两头不靠

Android 的难题不是单一技术限制,而是四种系统里唯一一个“继承了宏内核架构、锁死了模块能力、又没有提供用户态驱动框架”的组合。这个边界画死之后,设计上唯一能做的,是把它当作一个固定约束,然后把需要内核自由度的任务分配给有自由度的设备。


本文基于实际设备实测与各系统官方文档整理。不同机型、内核版本和系统版本下细节可能不同,请以实际环境为准。

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐