Chapter 35: Android Linux Kernel and Apple XNU
读完本章,读者应能把一次移动 App 的硬件能力请求放回两类 kernel 体系中定位:Android 侧沿着 Framework API → Binder → system service / native service → HAL → Linux kernel → vendor driver / hardware 追踪,Apple 侧沿着 Framework API → XPC / daemon → XNU → IOKit / DriverKit → hardware 追踪。
本章的贯穿材料是一段相机预览请求。应用代码只看到“打开相机、取得预览帧、失败时收到权限或设备占用错误”。系统内部需要完成调用转发、权限判断、进程身份识别、设备独占、buffer 传递、功耗约束和错误返回。kernel 在这个路径中承担资源所有权和硬件边界职责,但两大平台把这些职责包装成完全不同的上层控制策略。
Android 使用基于 Linux 的 kernel,并在其上叠加 AOSP framework、Binder IPC、HAL、SELinux、cgroup、GKI/KMI 和厂商模块边界。Android 官方文档说明,Android kernel 基于 upstream Linux LTS,Google 将 LTS kernel 与 Android-specific patches 组合成 Android Common Kernels,5.10 及以上的 ACK 又进入 GKI 体系,用 KMI 连接通用 kernel 与 vendor modules(Android Kernel overview,2026-04-10)。
Apple 使用 XNU。公开文档把 XNU kernel environment 描述为 Mach、BSD、I/O Kit、文件系统和网络组件的组合(Apple Kernel Architecture Overview,2013-08-08)。iOS、iPadOS、watchOS、visionOS 的完整 daemon 链路包含大量私有实现,本章只使用公开 Darwin / XNU 文档、公开 DriverKit / IOKit 文档和可观察平台行为,不把私有服务内部细节当成确定事实。
35.1 Android Linux Kernel 的系统位置
Android Linux kernel 位于应用沙箱、Android Framework、system service、native service、HAL 和 vendor driver 的下方。它提供通用 OS 资源:进程调度、虚拟内存、文件系统、网络栈、设备节点、中断、DMA、驱动、cgroup、SELinux enforcement、Binder driver 和电源管理原语。上层服务把这些原语包装成应用可调用的能力。
以相机预览为例,App 调用 CameraManager 或相机库时,调用首先进入 Android framework。framework 通过 Binder 访问相机相关系统服务或 native service。服务检查调用者身份、运行时权限、前后台状态、相机占用状态和设备 policy。通过检查后,服务再进入 camera provider HAL。HAL 访问厂商相机栈、ISP 相关驱动、buffer 分配路径和硬件设备。kernel 在这里负责设备文件、内存映射、DMA buffer、调度、同步原语和访问控制。
这个位置决定了 Android kernel 的阅读方式。读相机、音频、传感器、定位、网络这类能力时,起点通常在 framework 或 service;kernel 是请求到达硬件边界后的资源执行层。kernel 可以拒绝一个非法设备访问,可以记录 SELinux denial,可以回收内存,可以调度线程,可以让 Binder transaction 进入目标进程。用户看到的“无权限、相机被占用、后台受限、预览失败、设备过热降级”往往由 service policy、HAL 状态和 kernel 结果共同形成。
Android kernel 还有一个平台维护职责:把 Linux LTS、Android common patches、GKI、vendor modules 和 KMI 组合成可升级边界。GKI 把硬件无关的核心 kernel 与硬件相关 vendor module 分开;KMI 用符号列表描述 vendor module 依赖的 kernel 函数和全局数据。这个边界让 Android 设备厂商可以在 SoC/board 差异较大的环境中维护驱动,同时让平台方控制 common kernel 的兼容范围。
所以 Android kernel 的系统位置可以压缩成一句判断:它是 Android 平台的底层资源所有者,同时也是 HAL 和 vendor driver 接入硬件的执行边界。读者排查硬件能力失败时,应先定位上层服务是否允许请求,再看 HAL 是否可用,最后把 kernel 侧证据放到设备访问、SELinux、Binder、内存、电源或驱动错误中解释。
35.2 Android Kernel、HAL、Binder Driver、SELinux、Power Management 的组合关系
Android kernel 在移动平台中很少单独出现。它通常与 HAL、Binder driver、SELinux、cgroup、wakelock/power policy 和 vendor driver 一起工作。HAL 是硬件厂商实现设备能力的标准接口层,Android 官方 HAL 文档把 HAL 定义为带标准接口的抽象层,让硬件厂商实现底层设备特性,上层代码无需跟随硬件实现改动(Hardware abstraction layer overview,2026-04-10)。
Binder 是 Android 上层系统服务的主通信路径。开发者 API 文档把 Binder 描述为轻量远程过程调用机制的核心对象(Android Binder API reference)。在系统内部,Binder driver 维护跨进程 transaction、引用、线程唤醒和调用者身份传递。相机请求进入服务时,服务能知道调用者 UID/PID、包身份和权限上下文,后续策略判断才有基础。
SELinux 给 Android 提供强制访问控制。Android 官方安全文档说明,Android 使用 SELinux 对所有进程实施 MAC,即使进程具备 root/superuser privileges 也受策略约束;enforcing mode 下,未允许动作会被阻止并记录到 kernel log 和 logcat(Security-Enhanced Linux in Android,2024-08-26)。这解释了一个常见现象:某个 HAL 进程拥有 Linux UID 权限,仍然可能因为 SELinux domain 缺少访问某个 device node 或 service 的 allow rule 而失败。
相机预览请求可以用下面的顺序追踪。图只展示责任链,不表示所有设备都使用完全相同的服务名和驱动名。
这个图中的关键点是“组合关系”。Binder 解决跨进程调用和身份传递;SELinux 解决进程 domain 与对象 label 的强制访问;cgroup 和 scheduler 解决线程资源分配;power management 解决设备唤醒、runtime PM、频率和功耗状态;HAL 解决厂商设备协议与上层接口之间的适配;vendor driver 解决寄存器、中断、DMA 和硬件队列。
Power management 在移动 OS 中会改变请求结果。前台预览、后台摄像头访问、屏幕熄灭、热限制、低电量和持续高帧率预览,会触发不同的资源策略。kernel 侧负责 wakelock、suspend blocker、runtime PM、thermal governor、cpufreq/devfreq、display/GPU/camera driver 电源状态。上层 service 决定哪些场景允许持续占用能力,kernel 负责让设备状态和调度状态落地。
排查 Android 相机类问题时,可复用的判断顺序是:先看 App 是否具备 runtime permission 和前台状态,再看 service 是否授予设备所有权,再看 Binder transaction 是否到达目标进程,再看 HAL 是否注册并通过 VINTF/manifest 检查,再看 SELinux 是否阻止 HAL 或 service 访问设备,再看 kernel driver 是否返回 timeout、I/O error、buffer sync error 或 thermal 降级。这个顺序把上层 policy 和 kernel 证据放在同一条链上,减少把所有失败都归因到驱动的误判。
35.3 Apple XNU 的系统位置:Mach、BSD、IOKit
Apple XNU 的系统位置可以从三块公开组件理解:Mach 提供任务、线程、虚拟内存、调度和 IPC 抽象;BSD 提供 POSIX 进程模型、文件描述符、socket、VFS、网络和传统 UNIX 接口;IOKit 提供面向设备驱动的对象模型、设备匹配、事件处理和电源管理。Apple 的 Kernel Programming Guide 明确写到 OS X kernel environment 包含 Mach kernel、BSD、I/O Kit、文件系统和网络组件,并且这些组件经常被合称为 kernel。
把相机预览放到 Apple 路径中,App 通常从 AVFoundation 等公开 framework 进入。权限提示与隐私授权由系统隐私框架和相关服务协调。framework 会通过 XPC 或其它系统 IPC 访问系统 daemon。daemon 持有设备能力、策略状态和硬件会话。底层进入 XNU、IOKit / DriverKit 或厂商驱动边界。公开文档没有给出 iOS 相机私有 daemon 的完整内部路径,因此正文只给出架构角色:framework 是公开 API 表面,daemon 是能力代理,XNU 是资源与 IPC/进程/文件/网络基础,IOKit / DriverKit 是设备驱动边界。
Apple 架构的核心差异是平台控制面更集中。Android 将大量硬件差异显式放在 HAL、VINTF、vendor partition 和 GKI/vendor module 边界中;Apple 垂直整合硬件、OS、framework 和应用分发,公开给开发者的是稳定 framework、entitlement、sandbox、privacy prompt、background mode 和 App Store policy。XNU 承担 kernel 角色,但开发者通常通过 framework 和系统 daemon 间接触达它。
下面的图展示同一类相机请求在 Apple 侧的责任角色。图中的 daemon 是角色名,表示持有相机能力的系统服务进程,不指定私有实现名称。
XNU 的阅读入口通常来自三类现象。第一类是进程、线程、调度、内存和 IPC 行为,这类问题应从 Mach task/thread/port 和 BSD process 的关系读起。第二类是文件、网络、socket、descriptor、POSIX 行为,这类问题应从 BSD layer 读起。第三类是设备、驱动、电源、匹配和硬件事件,这类问题应从 IOKit / DriverKit 读起。相机预览同时触发三类入口:App 进程与 daemon 通信依赖 IPC,设备会话依赖驱动模型,frame buffer 与内存调度依赖 kernel 资源管理。
Apple 平台的公开边界要求读者保留两个判断。可以公开确认的是 XNU 由 Mach、BSD、IOKit 等组件形成 kernel environment;可以从平台行为和公开 API 推断的是 framework/daemon/kernel/driver 的责任分层;缺少公开证据的是具体私有 daemon 的内部类、私有 IPC message 格式和设备厂商驱动实现。
35.4 Mach 负责的任务、线程、Port 与消息机制
Mach 是 XNU 中负责低层资源抽象的一组机制。Apple 文档把 task 定义为资源所有权单位,包含虚拟地址空间、port right namespace 和一个或多个 thread;thread 是 task 内的 CPU 执行单位;port 是受 port right 控制的单向通信端点;IPC 包括 message queue、RPC、notification、semaphore 和 lock set(Mach Overview,2013-08-08)。
在 App 请求相机预览时,Mach 相关概念首先出现在进程与服务通信中。App process 在 Mach 层对应 task,主线程和 capture queue 线程对应 thread。系统 daemon 也有自己的 task 和 thread。App 访问服务时,通信能力最终会落到某种端口权利、消息传递或上层封装。XPC 是开发者更常见的高层 IPC 接口,但 XNU 底层的能力模型仍要回到 task、thread、port right 和 message。
Port right 是理解 Apple IPC 安全边界的关键。持有 send right 的 task 才能向某个 port 发送消息;持有 receive right 的 task 才能接收该 port 上的消息。port right 可以通过 IPC 复制或移动,这等于把某种访问能力传给另一个 task。这个能力模型让系统可以把“是否能访问某个服务对象”表达成“是否持有相应权利,以及服务端是否接受当前身份与策略状态”。
Mach message 可以携带数据、内存范围副本、port right 和发送者安全 token 等内容。Apple 文档说明,message send 是异步传输,接收 task 后续执行 receive 操作;同一个 port 可以有多个发送者和单一接收者。相机请求中的“请求打开设备、回传结果、传递共享 buffer 权利、通知错误”都可以放进这个消息模型解释,但具体高层格式由 framework、daemon 和私有协议决定。
Mach 还负责虚拟内存、copy-on-write、线程调度和时钟等待。对移动 OS 来说,这些机制直接影响 App 体验。相机预览期间,frame buffer、共享内存、线程优先级、实时性、回调队列和 UI 响应都依赖底层调度与内存行为。用户看到的卡顿可能来自 framework 队列阻塞,也可能来自 daemon 处理延迟、buffer 交付延迟或 thermal 状态导致的调度能力下降。
读 Mach 时可按这个判断顺序展开:先确认对象是 task、thread、port、memory object 还是 message;再确认谁持有资源或 port right;然后确认消息从哪个 task 到哪个 task;最后把调度、内存和安全 token 放回用户可见结果。这个顺序适合分析 XPC 调用延迟、服务连接失败、daemon 崩溃、capture session 迟迟没有回调等现象。
35.5 BSD Layer 负责的进程模型、文件系统、网络与 POSIX 接口
BSD layer 给 XNU 提供传统 UNIX/POSIX 语义。Apple 的 BSD Overview 说明,BSD 部分主要来自 FreeBSD,并提供进程与保护、用户和组 ID、process creation/termination、signals、descriptor、files、pipes、sockets、resource controls、process priorities、read/write、file-system operations、process control 和 networking operations(BSD Overview,2013-08-08)。
这层解释了为什么 Apple 平台上的 App、daemon 和系统工具仍然能使用很多 POSIX 行为。进程有 PID,文件访问经由 file descriptor,网络通信使用 socket,VFS 统一文件系统入口,resource limit 和 priority 参与资源控制。Mach 提供低层 task/thread/port 抽象,BSD 则把这些抽象包装成开发者和系统组件更熟悉的 process、pthread、descriptor、socket 和 syscall 语义。
相机预览请求中,BSD layer 的作用通常较隐蔽。App 不会通过 POSIX open 直接打开相机硬件;它会调用 AVFoundation。系统 daemon 内部仍可能使用文件描述符、socket、进程状态、credential 和资源限制等 BSD 设施。日志、崩溃、文件缓存、临时文件、网络上传、后台状态恢复,也会沿着 BSD 提供的接口和内核数据结构运行。
BSD layer 也是 Apple sandbox 和权限执行的重要基础之一。应用沙箱、容器目录、文件访问、网络访问和进程凭证都要落到 kernel 可执行的对象上。用户授权“允许访问照片”“允许访问相机”“允许本地网络”时,决策通常在 framework 与系统服务层完成;执行落地会涉及 BSD credential、sandbox policy、文件系统权限、socket policy、Mach port right 和 daemon 自身的授权状态。
对比 Android 可以看到层级差异。Android App 也有 Linux UID、file descriptor、socket、VFS 和 syscall,但 Android 把应用能力更多地放在 Binder service、permission manager、SELinux domain、HAL 和 cgroup 中组织。Apple XNU 则把 Mach capability、BSD POSIX 语义、sandbox、entitlement 和 daemon 管理合在同一平台控制面中。两者都拥有 UNIX/POSIX 资源模型,但上层能力开放方式不同。
读 BSD layer 时可使用三个问题。第一,当前现象是否表现为文件、socket、进程、signal、descriptor 或 POSIX API 行为。第二,当前对象属于 App、daemon、extension 还是系统进程。第三,失败结果来自文件/网络资源边界、sandbox/entitlement、credential、resource limit,还是上层服务拒绝。这个顺序能把“文件打不开、网络请求失败、后台下载终止、扩展进程退出”放回 XNU 的 BSD 责任范围。
35.6 IOKit / DriverKit 与 Apple 设备驱动边界
IOKit 是 Apple 设备驱动模型的公开核心。Apple 的 Kernel Architecture Overview 说明,I/O Kit 提供面向驱动开发的 framework,支持多类设备,使用受限 C++ 子集实现对象化 I/O 架构,并提供 plug and play、动态设备管理、按需加载驱动和电源管理等能力。IOKit Fundamentals 进一步说明,IOKit 是 Apple 面向设备驱动的 object-oriented framework,并涵盖设备匹配、I/O Registry、driver lifecycle、work loop、event source、DMA 约束和 power management(IOKit Fundamentals,2014-04-09)。
IOKit 的核心概念是 provider/client 关系和 I/O Registry。硬件、bus、controller、driver、nub、user client 以对象形式进入 registry。系统通过匹配规则选择合适 driver,把设备生命周期、事件、请求队列、电源状态和用户态访问接口组织起来。相机、触摸、音频、蓝牙、USB、存储和传感器都可以用“设备对象被匹配,驱动管理状态,上层 client 通过受控接口访问能力”的模型理解。
DriverKit 是 Apple 推动用户态驱动的一条路径。对移动 OS 架构来说,这个趋势的意义是降低驱动故障对 kernel 的冲击范围,把更多设备控制逻辑移出 kernel address space。公开 DriverKit 页面给出的能力入口较简略,但 macOS 近年确实把部分驱动开发引导到 user space extension 模型;iOS 具体设备栈细节仍受平台私有实现限制。本章使用它作为边界趋势:Apple 通过 framework、daemon、entitlement、DriverKit / IOKit 控制硬件访问面。
相机预览在 Apple 侧不会让第三方 App 直接触达 IOKit driver。App 使用 AVFoundation,授权由隐私系统处理,设备会话由系统 daemon 管理,底层驱动和硬件资源由 XNU/IOKit/DriverKit 相关组件协调。这个链路把硬件能力变成平台可授权、可仲裁、可撤销、可审计的能力。App 只得到 capture session、sample buffer、error callback 和状态变化。
IOKit / DriverKit 还承担电源管理边界。移动设备的相机、ISP、display、GPU 和 sensor 都有功耗域、时钟、buffer 队列和热限制。驱动层需要响应设备打开、关闭、suspend、resume、stream start、stream stop、interrupt、DMA complete 等事件。上层服务决定会话策略,驱动层让硬件状态变化生效。用户看到的黑屏预览、帧率降低、相机占用、过热停止录制,都可能跨越 framework、daemon、driver 和 thermal policy。
读 IOKit / DriverKit 时可按“设备匹配 → 驱动生命周期 → 用户态访问接口 → 事件处理 → buffer / DMA → 电源状态 → 错误返回”展开。这个顺序适合把设备故障归类为匹配失败、驱动启动失败、权限/entitlement 拒绝、设备占用、硬件超时、buffer 同步错误或热限制触发。
35.7 同样承担 Kernel 角色,不同平台控制策略
Android Linux kernel 和 Apple XNU 都承担 kernel 角色:管理 CPU、内存、进程/线程、IPC、文件、网络、设备、驱动、电源和安全边界。差异来自平台控制策略。Android 需要服务大量 SoC、OEM、board 和 vendor driver 组合,所以它把硬件差异显式放在 HAL、VINTF、vendor partition、GKI、KMI 和 vendor module 边界中。Apple 控制硬件、OS、framework 和分发渠道,所以它把更多差异收敛在私有 daemon、framework、entitlement、sandbox、IOKit / DriverKit 和系统策略中。
资源所有权维度上,Android App 资源身份通常由 Linux UID、package identity、SELinux domain、cgroup 和 Binder caller identity 共同表达。Apple App 资源身份通常由 bundle identity、code signing、entitlement、sandbox profile、Mach task/port right、BSD credential 和 daemon 授权状态共同表达。两者都使用 kernel 机制执行隔离,但开发者看到的公开入口分别是 Android permission / Binder service 与 Apple framework / entitlement / privacy prompt。
驱动模型维度上,Android 把大量设备差异放入 vendor driver 与 HAL。GKI/KMI 试图稳定 common kernel 与 vendor module 之间的接口。Apple 把设备驱动模型纳入 IOKit / DriverKit 和垂直整合硬件栈,第三方 App 通过 framework 间接使用硬件能力。Android 的开放适配面更显式,Apple 的公开能力面更集中。
IPC 维度上,Android 以 Binder 为系统服务调用主干,service manager、AIDL/HIDL、Binder driver 和 SELinux 共同形成服务访问路径。Apple 以 Mach port/message 为底层能力模型,上层大量使用 XPC、launchd、framework delegate/callback 和系统 daemon。Android 调试常看 Binder transaction、service、HAL 和 SELinux;Apple 分析常看 framework 状态、XPC/daemon、entitlement、sandbox、crash/jetsam 和公开 XNU 抽象。
安全策略维度上,Android 强调 permission、SELinux、UID sandbox、signature、Verified Boot、GKI/vendor 边界和 Play/OEM policy 的组合。Apple 强调 code signing、entitlement、sandbox、privacy prompt、TCC 类授权、App Store review、Secure Enclave / secure boot 以及私有服务控制面的组合。kernel 在两边都是强制执行点之一,但完整安全结果由多层策略共同产生。
把相机预览请求放回两边对比,Android 的关键问题是:App 调用是否被 framework 和 service 允许,Binder 身份是否正确,HAL 是否注册且可用,SELinux 是否允许服务与 HAL/设备通信,driver 是否正常返回 buffer。Apple 的关键问题是:App 是否具备授权状态和必要 entitlement,framework session 是否建立,系统 daemon 是否授予设备会话,XNU/IOKit/DriverKit 侧是否完成设备访问,失败是否表现为权限错误、设备占用、进程终止、隐私撤销或热限制。
最终可复用的判断顺序是:先确定用户可见现象,再定位公开 API 表面,然后找系统服务或 daemon 所有者,再检查权限和身份,再进入 IPC、HAL/driver 或 IOKit/DriverKit 边界,最后用 kernel 证据解释资源、调度、电源或设备错误。这个顺序能同时覆盖 Android 和 Apple,又保留两者的控制策略差异。
最小自检任务
题目:一个视频会议 App 在 Android 上打开相机时偶发失败,在 iPhone 上同类场景表现为系统提示相机被占用或无法建立 capture session。请分别写出 Android 和 Apple 的责任链,并说明应该优先定位哪些边界。
答案要点
Android 侧应写出 App → Framework API → Binder → Camera Service / native service → permission 与 lifecycle policy → Camera HAL → Linux kernel → vendor driver / camera hardware。优先定位 runtime permission、前后台状态、service 设备仲裁、Binder 调用是否到达、HAL 是否注册、SELinux denial、buffer / DMA / fence、driver timeout 和 thermal / power 降级。核心判断是:用户看到的打开失败通常由 service policy、HAL 状态和 kernel driver 结果共同形成,kernel 证据需要放回 Binder、SELinux、HAL 和电源策略组合中解释。
Apple 侧应写出 App → AVFoundation 等 Framework → privacy authorization / entitlement / sandbox → XPC / system daemon → XNU → IOKit / DriverKit → hardware。优先定位授权状态、capture session 配置、系统 daemon 设备所有权、App lifecycle、entitlement / sandbox、XPC 连接、进程终止或 jetsam、设备占用和热限制。核心判断是:公开 API 暴露的是 framework 结果,XNU 的 Mach/BSD/IOKit 角色需要通过公开文档与可观察行为推断,私有 daemon 内部细节不作为答案前提。
本章知识点总结
- Android 位置:Android kernel 是 AOSP framework、system service、HAL、vendor driver 与应用沙箱下方的资源所有者。
- ACK 与 GKI:Android Common Kernel 基于 Linux LTS 加 Android patches,GKI/KMI 把通用 kernel 与 vendor module 边界稳定下来。
- HAL 边界:HAL 把厂商硬件实现包装成上层可调用的标准接口,硬件差异主要在 HAL 与 vendor driver 中消化。
- Binder 主干:Binder 负责 Android 跨进程调用、身份传递、线程唤醒和系统服务访问路径。
- SELinux 执行:Android SELinux 对进程和对象实施强制访问控制,root 权限进程仍受 domain policy 约束。
- 电源协同:Android power management 通过 wakelock、runtime PM、thermal、cgroup 和服务策略共同影响硬件请求结果。
- XNU 组合:Apple XNU kernel environment 由 Mach、BSD、IOKit、文件系统和网络组件共同组成。
- Mach 抽象:Mach 用 task、thread、port right、message 和 memory object 表达资源、执行与 IPC 能力。
- BSD 语义:BSD layer 提供 POSIX 进程、descriptor、file system、socket、network、signal 和 resource control。
- IOKit 驱动:IOKit 用对象化设备模型、设备匹配、I/O Registry、driver lifecycle、事件和电源管理组织硬件访问。
- Apple 边界:Apple App 通常通过 framework、privacy policy、XPC/daemon 和 entitlement 间接触达 XNU 与驱动层。
- 对比顺序:分析跨平台硬件能力问题时,应先看 API 和服务所有者,再看权限身份,随后进入 IPC、HAL/driver 或 IOKit/DriverKit,最后解释 kernel 证据。