Skip to main content

C1 & C2 简介和系统结构

这里仅简单列出在简介和 C1 中的内容, 主要是整体结构和系统历史.

简介​

OSX 和 iOS 有非常复杂的结构, 因为它们都是由若干技术构成的混合体:

  • UI 和 API 是从 NextSETP 的 Cocoa 来的.
  • 系统调用和内核层是 BSD

OSX system Architecture

系统结构简介​

OSX 和 iOS 都是在非常简单的原则和基础上构造起来的. 首先来看基础内容, 然后自底向上介绍用户模式下的系统组件.

在介绍过程中, 会对比两个结构: iOS 和 OSX. 之后可以发现, iOS 是完整 OSX 的简化版本, 且 iOS 是基于 ARM 的, 系统中有些组件直接被移除, 或被简化了.

OSX 的架构总览​

OSX 架构可以按如下简化描述:

  1. 用户体验层: 包含 Aqua/Aqua Dark, Dashboard, Spotlight, Accessibility 功能. 而在 iOS 上, UX 完全依赖于 SpringBoard, 而且也支持 Spotlight.
  2. Application Framework 层: 包含 Cocoa/AppKit 等. 而在 iOS 上仅有 UIKit(Cocoa Touch).
  3. Core Service Framework 层: 这层中包含若干核心服务框架, 比如 OpenGL, Quick Time 等.
  4. Darwin: 是系统的核心, 即内核以及内核提供的 Shell 环境.

ar

上面的只是系统架构的总体描述, 在 Darwin 层中, 实际有许多组成部分, 如下是 Darwin 的完整架构:

ar2

这个总体架构是贴近目前 Darwin 的, Darwin 的核心又被称为 XNU. XNU 由两大部分组成: BSD 和 Mach, 另外还有若干小的其他组件(主要是 IOKit 中的).

为研究系统架构, 更好的办法是由不同抽象层级进行, 每个抽象层级都可以简化理解过程. 比如用户体验层中的 APP, 绝大部分都只是基于 Application Framework 层, 只有少量还依赖了 Core Service 层. 因此 app 开发者才不用关注更底层的 Darwin 或系统内核.

系统内核中, 有不少组件是可以被设备驱动开发者直接访问的. 因此, 书后面的部分才会从 Shell 环境开始讲, 然后再转到内核.

用户体验层​

在 OSX 中看 UI 即 UX. 苹果列出来它的 UX 层中若干组件:

  • Aqua/Aqua Dark
  • Quick Look
  • Spotlight
  • Accessibility options

而在 iOS 结构中, 底层的结构和 OSX 类似, 但 UX 层却完全不同. SpringBoard(触控驱动的 UI)负责所有的 UI 任务.

Aqua​

在 OSX 的第一个进程 launchd 启动后, 它会负责启动 GUI. GUI 的主进程是 WindowServer, 这个进程是 Core Graphics framework 的一个组成部分, 而 CG Framework 又是 Application Framework 中众多 Framework 的一个, WindowServer 的存储位置在 /System/Library/Frame- works/ApplicationServices.framework/Frameworks/CoreGraphics.framework/Resources/ WindowServer.

window server 启动时候带 -daemon 参数, 意味着它将以守护进程方式运行. WindowServer 实际上没有做实际的工作, 而是将所有任务交给 CGXServer(Core Graphics X Server)做, 它也是 CG framework 的一部分. CGXServer 首先检查自己是否以守护进程还是(或是)以 main console getty 的方式运行, 然后 fork 自己到后台运行, 当准备好后, LoginWindow 会被 launchd 启动, 然后开始交互式登录的过程.

Quick Look​

Quick Look 的作用是让用户在 finder 内快速预览文件内容(而不用双击打开文件, 直接按空格即可预览).

Quick Look 支持插件, 可用将 Quick Look 的任务交给插件进行. Quick Look 插件打包为 qlgenerator 格式, 安装时直接放到 /System/Library/QuickLook(系统范围内可用)或 ~/Library/QuickLook(当前用户可用).

插件本质上是一个编译好的程序, 但它没有 main 入口. 插件只是实现 QuickLookGeneratorPluginFactory 协议, 并且单独提供一个配置文件表示自己关联的文件类型, 文件类型使用 UTI(Uniform Type Identifier, 表现为逆序的 DNS 记号字符串).

quicklookd 作为系统的 Quick Look 服务器, 它也是一个守护进程, 通过 /System/Library/LaunchAgents/com.apple.quicklook.plist 配置文件配置启动. 这个进程存放在 QuickLook framework 中, 它没有 GUI 界面.

用户可用 qlmanage 命令管理 quicklookd 守护进程和 Quick Look 插件. 比如下面的命令可以列出当前 Quick Look 的具体信息:

$ qlmanage -m

# 会打印出守护进程以及插件的信息, 略.

Spotlight​

Spotlight 是苹果在 10.4 系统后引入的快速搜索技术, 并且集成到了 finder 中. 在 iOS 3.0 之后, Spotlight 也被集成到了 iOS.

Spotlight 的后端是一个索引服务器: mds.

mds 是一个没有 GUI 的守护进程, 存放在 MetaData Framework 中(/System/Library/Frameworks/CoreServices.framework/Frameworks/Metadata.framework/Support/mds), MeataData Framework 是系统的 Core Service 的一部分.

当任意文件操作发生后(增删改), 内核会通知 mds 进程, 而 "通知" 的实现就是 fsevents. 当接到通知后, mds 会利用它自己的工作进程(mdworker)导入对应的元数据信息到数据库. mdworker 可以启动特殊的 "Spotlight Importer" 将改变的文件对应的元数据抽取出来. 系统范围可用的 importer 都存放在 /System/Library/Spotlight, 用户的则是在 /Library/Spotlight 中. 并且 Spotlight 也支持插件(通过 Xcode 的 MetaData Importer 模板即可创建).

Spotlight 可以通过下面的命令访问:

  • mdutil: 管理 MetaData 数据库.
  • mdfind: 发起 spotlight 查询.
  • mdimport: 配置并测试 spotlight 插件.
  • mdls: 列出对应文件的元数据信息.
  • mdcheckschema: 验证元数据结构
  • Mddiagnose: Lion 后可用, 这个实用工具可以提供 spotlight 子系统(mds 和 mdworker)的完整诊断信息, 并提供系统上的额外数据信息.

还有一个控制 Spotlight 的技巧: 如果在任意目录创建 .metadata_never_index 文件, 则可以将它排除出 Spotlight 的索引(最初设计为对移动设备提供支持, 避免不必要的索引).