1 前达尔文时代:Mac OS Classic
Classic是Mac OS在OS X之前的名称。该版本是创新的全GUI系统,但是,内存管理非常糟糕,多任务系统是协作式的。
协作式的多任务系统中,进程需要资源放弃自己的CPU时间片,如果进程行为良好,则可以很好的工作,然而如果有的进程拒绝协作,即使有一个这样的进程,整个系统都会停止运行。
尽管如此,如今的OS X还是在该系统的基础上发展而来,比如现在的Finder,HFS文件系统等。
2.NeXTSETP
乔布斯创建的NeXT公司,生产专用硬件:NeXT计算机和NeXTstation。这些机器运行中专用的操作系统:NeXTSTEP。
NeXTSTEP的特性:
- Mach微内核
- 使用语言是Objective-C,是C语言的超集,重度面向对象的语言
- 面向对象贯穿整个操作系统,所有的对象都基于NSObject
- 驱动开发环境也是面向对象的框架,称为DriverKit
- 应用程序和库以自包含的bundle形式发布。bundle是一个固定的目录结构,用于封装软件包,带有自己所需要的依赖和相关文件,因此软件安装和删除就像移动一个目录。
- 重度使用PostScript
后来,该公司被苹果收购,乔布斯也回到苹果,NeXTSTEP操作系统的遗产被OS X系统继承了。
3.OS X
实际上,可以把OS X当成是Classic和NeXTSTEP的融合。Mac OS X的第一个版本是Rhapsody,该系统的内核也就是今天所熟知的Darwin(达尔文)。
OS X的核心组件-Cocoa/Mach/IOKit/Xcode的Interface Builder以及很多其他组件,都是直接来自于NeXTSTEP。这也就是OC里面很多类都是以NS开头的原因。
4.iOS----移动平台的OS X
从本质上看,iOS实际上就是Mac OS X,但两者还是有区别的:
- iOS内核和二进制文件编译的目标架构是基于ARM的架构。而不是Intel i386和x86_64。尽管目标处理器不同,但都是采用ARM设计。ARM的优势在于电源管理。
- iOS内核源码是闭源的。
- iOS内核的编译稍有不同,关注的是嵌入式特性和一些新的API。
- iOS的系统GUI是SpringBoard,就是大家熟知的触屏应用加载器;而OS X中是Aqua,是鼠标驱动的,而且特别为窗口系统所设计。
- iOS内核管理要紧凑很多,因为在移动设备上几乎没有无穷的交换空间可以使用。因此,开发者需要适应更严酷的内存限制以及编程模型的变化。
- 系统限制更严,应用程序不允许访问底层,也没有root访问权限。而且只能访问自己目录里的数据,只有苹果的应用才能访问整个系统的权利。
5.OX X架构概述
OS X和iOS的分层:
- 用户体验层:Aqua,Dashboard,Spotlight和辅助功能等
- 应用框架层:Cocoa,Carbon和Java,iOS中只有Cocoa Touch
- 核心框架:图形和媒体层,包括核心框架、Open GL和QuickTime
-
Darwin:操作系统核心--包括内核和UNIX shell环境
只有Darwin是开源的,上面是闭源的,苹果有私有知识产权。
其中,Darwin是需要关心的,具体架构:
这表明,Darwin是由两个技术混合在一起的:Mach和BSD。还添加了一些其他组件。
6.Darwin--UNIX核心
Terminal应用程序会打开一个带有UNIX shell的终端模拟器。默认使用shell是/bin/bash,即GUN的Bourme Again的shell。还提供了其他可选:
- /bin/sh:最基本的UNIX shell
- /bin/bash:默认shell
- /bin/csh:基本shell的替代品,类似C的语法
- /bin/tcsh:类似C-shell
- /bin/ksh:另一个标准shell
- /bin/zsh:与bsh完全兼容
命令行工具都可以通过telnet或SSH远程访问,但默认都是禁止的。不推荐telnet,不安全。
可以方便的启动telnet和SSH,只要编辑/System/Library/LaunchDaemons目录对象的plist文件(telnet.plist和ssh.plist),将Disabled键值设置为false即可。
7.UNIX的系统目录
- /bin:二进制程序,常用UNIX命令所在地方
- /sbin:系统程序。用于管理系统。
- /usr:User目录,不是给用户使用的,用户的第三方软件安装的地方
- /usr:包含bin,sbin和lib。lib存放共享目标文件。include/所有C头文件都存放在此。
- /etc:系统配置文件
- /dev:BSD设备文件,表示系统中存在的设备
- /tmp:临时目录
- /var:杂项文件
OS X特有目录:
- /Applications:所有应用程序默认目录
- /Developer:安装了Xcode,所有开发者工具的默认安装位置。
- /Library:系统应用的数据文件等
- /Network:用于邻居节点发现和访问的虚拟目录
- /System:系统文件目录
- /Users:所有用户的主目录所在的目录
- /Volumes:可移动媒体和网络文件系统的挂载点所在目录
- /Cores:核心转储文件
8.Bundle
bundle:一种标准化的层次结构,保存了可执行代码以及代码所需要的资源。
bundle的结构:
Contents/
CodeResoures/
Info.plist 包中的manifest文件
MacOS/ 包中的二进制文件
PkgInfo 包的8字节标识符
Resources/ .nib文件和.lproj文件
Version.plist 包版本信息
CodeSignature/
CodeResources
Cocoa提供了一中简单的编程方法用于访问和加载bundle,即通过NSBundle对象和CoreFoundation提供的CFBundle系统API可以访问和加载bundle。
9.应用程序
应用程序整洁的包装在bundle中,包含运行该应用程序所需的大部分文件:主二进制文件,私有的库,图标,UI元素以及图形元素。而用户不知情,bundle在Finder中只是显示为一个图标。因此,Mac OS上安装程序只需要将应用程序图标拖到Applications目录即可。
10.lproj文件实现国际化
bundle设计上就支持国际化,每一种语言对应一个子目录,语言目录的后缀为.lproj。在表示语言的目录中包含针对指定语言本地化的字符串文件,nib文件和多媒体。
11.CodeResources
实际上是一个属性列表,包含bundle中所有其他文件的列表,该属性列表只有一项files,是一个字典,键是文件名,值通常是Base64格式的散列值。用于判断应用程序是否完好无损,是否被修改等。
OS X和iOS都没有在系统中为应用程序设置维护一个注册表。因此,程序必须通过其他机制存储用户首选项和各种默认设置。
苹果提供的机制为defaults,每个程序都会得到一个属于自己的名称空间,应用程序可以在这个名称空间中根据需要随意添加,修改和删除设置。这个名称空间称为应用程序的域。
应用程序的默认设置通常保存在属性列表中。
12.框架
OS X中,框架就是bundle,包含一个或多个共享库以及相关的支持文件。
框架不是Darwin的一部分。因为Darwin是开源的,而框架是闭源的。
框架保存位置:
- /system/library/frameworks: 包含苹果提供的框架,iOS和OS X都是如此
- /network/library/frameworks: 用于网络上安装的公共框架
- /library/frameworks: 保存第三方框架
- ~/library/frameworks: 保存用户提供的框架
13.库
框架可以说是一种特殊的库,框架中的二进制文件就是库。
库文件使用.dylib后缀,而不是.so文件。
14.系统调用
用户程序不允许直接访问系统资源,可以操作通用寄存器,执行一些简单的计算,但如果需要执行任何重要功能,比如打开文件或套接字,甚至发送一条简单的消息,都必须使用系统调用。
系统调用值得是由内核导出的预定义函数的入口点,在用户态需要连接/usr/lib/libSystem.B.dylib才能访问这些系统调用。OS X系统调用特殊之处在于实际上导出了两套独特的调用接口----一个是Mach调用,一个是POSIX调用。
POSIX是一套标准的API,定义了如下内容:
- 系统调用原型:所有POSIX系统调用具有相同的原型,具有相同的参数和返回值。
- 系统调用编号:POSIX还完整定义了系统调用的编号,一定程序上允许了二进制层次的可移植性。
OS X是在Mach内核的基础上构建的,BSD是对Mach内核的包装。但Mach系统调用仍然可以在用户态访问。
32位系统上,Mach系统调用编号为负数,POSIX定义了非负的系统调用。
64位上,Mach系统调用是证书,但是以0x2000000开头,而POSIX是以0x1000000开头。
15.XNU概述
XNU是Darwin的核心。也是整个OS X的核心。有如下几个组件构成:
- Mach微内核
- BSD层
- libKern
- I/O Kit
Mach职责:
- 进程和线程抽象
- 虚拟内存管理
- 任务调度
- 进程间通信和消息传递机制
BSD层:建立在Mach之上,提供了:
- UNIX进程模型
- POSIX线程模型及其相关的同步原语
- UNIX用户和组
- 网络协议栈BSD Socket API
- 文件系统访问
- 设备访问,通过/dev目录
libkern:大部分内核都是完全使用C语言和底层汇编语言编写的。而XNU不同,设备驱动程序可以用C++语言编写。为了支持C++运行时并提供所需要的基类,XNU包含了libkern库,这是一个内建的,自包含的C++库。
I/0 Kit:设备驱动程序框架。驱动程序可以通过C++编写,可以在一个面向对象的环境中编写驱动程序。