C1 & C2 简介和系统结构
这里仅简单列出在简介和 C1 中的内容, 主要是整体结构和系统历史.
简介
OSX 和 iOS 有非常复杂的结构, 因为它们都是由若干技术构成的混合体:
- UI 和 API 是从 NextSETP 的 Cocoa 来的.
- 系统调用和内核层是 BSD
系统结构简介
OSX 和 iOS 都是在非常简单的原则和基础上构造起来的. 首先来看基础内容, 然后自底向上介绍用户模式下的系统组件.
在介绍过程中, 会对比两个结构: iOS 和 OSX. 之后可以发现, iOS 是完整 OSX 的简化版本, 且 iOS 是基于 ARM 的, 系统中有些组 件直接被移除, 或被简化了.
OSX 的架构总览
OSX 架构可以按如下简化描述:
- 用户体验层: 包含 Aqua/Aqua Dark, Dashboard, Spotlight, Accessibility 功能. 而在 iOS 上, UX 完全依赖于 SpringBoard, 而且也支持 Spotlight.
- Application Framework 层: 包含 Cocoa/AppKit 等. 而在 iOS 上仅有 UIKit(Cocoa Touch).
- Core Service Framework 层: 这层中包含若干核心服务框架, 比如 OpenGL, Quick Time 等.
- Darwin: 是系统的核心, 即内核以及内核提供的 Shell 环境.
上面的只是系统架构的总体描述, 在 Darwin 层中, 实际有许多组成部分, 如下是 Darwin 的完整架构:
这个总体架构是贴近目前 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 的索引(最初设计为对移动设备提供支持, 避免不必要的索引).