Mac Os引导
“引导”指系统为准备投入使用而执行的一系列动作。引导流程包括许多不同的任务,例如初始化硬件、启动系统守护程序(system daemon)以及显示登录窗口。当用户登录后,系统将完成另一系列动作,用以为用户建立计算环境。
一 引导流程
在从用户打开Mac OS X系统到登录窗口出现的这个时间段内,Mac OS X将执行一个引导流程,使系统处于准备使用状态。
1 BootROM
当打开Macintosh计算机的电源后,BootROM固件是被激活的第一个代码。BootROM(它是计算机硬件的一部分) 有两个主要的职责:初始化系统硬件以及选择引导操作系统。BootROM有两个组件帮助其实现这些功能:
POST(Power-On Self Test,开电自检)对一些硬件接口进行初始化,并检查是否有足够的RAM存储器可供使用以及是否处于良好状态。
Open Firmware对其余硬件进行初始化、创建初始设备树(一个计算机相关设备的分层表示法)以及选择所使用的操作系统。
相同版本的BootROM可启动Mac OS 9以及Mac OS X。
2 BootX
当BootROM(或用户)选择Mac OS X作为引导的操作系统后,控制权就传递给了BootX 引导程序(位于/System/Library/CoreServices目录内)。BootX的主要任务是装载内核环境。当执行此任务时,BootX在屏幕上显示“booting(引导中)”图像。
当装载内核环境时,BootX将首先尝试为涉及引导进程的硬件装入一组预先存储的设备驱动程序(称为mkext缓存)。如果该缓存丢失或遭破坏,BootX将在/System/Library/Extensions目录内搜索驱动程序和其它的内核扩展,这些驱动程序或内核扩展的OSBundleRequired属性被设置为一种合适的引导类型(例如,本地或网络引导)的值。关于OSBundleRequired关键字以及系统引导时装载设备驱动程序的更多信息,请参阅“内核开发人员文档”。
一旦装载了内核以及引导所必需要的所有驱动程序,BootX就开始内核初始化进程。此时,有足够多的驱动程序被装载, 以帮助内核来寻找根设备。另外从此时开始,Open Firmware将不再能被访问。
内核将首先初始化Mach和BSD数据结构,然后初始化I/O Kit。通过使用设备树决定链接的驱动程序,I/O Kit将装入的驱动程序与内核连接。一旦内核找到根设备,它将通知BSD。最后,内核启动mach_init进程。mach_init进程是Mach引导端口服务程序,它启用Mach消息传递。在安装根文件系统后,系统初始化将继续运行系统启动项目并启动所有系统守护程序(参阅“系统初始化”)。
3 系统初始化
mach_init进程将启动BSD init进程。后一进程的进程标识符(PID)为1,它“拥有”系统的所有其它进程。尽管具有中心地位,但init进程是简单的,它执行了四个主要任务:
3.1 确定用户想要进入单用户模式还是通过CD-ROM引导。如果其中任一情况适用,将打印一个询问,并将控制权移交给用户。
3.2 运行完成基本初始化任务的系统初始化外壳脚本,即/etc/rc.boot和/etc/rc。详细内容请参阅“rc.boot 和rc脚本”。
/etc/rc脚本运行SystemStarter程序,它处理更多被指定为“启动项目”的特定初始化任务。详细内容请参阅“启动项目”。
3.3 通过getty命令,init将启动loginwindow应用程序,它将显示登录窗口并管理用户登录过程。详细内容请参阅“管理用户会话”。
3.4 作为所有进程的父进程, init在这些系统进程终止时,将对它们进行所有必要的清理。尽管init进程拥有系统的所有其它进程,但仍然可区分用户进程和系统进程。启动项目以及所有在loginwindow应用程序以前运行的应用程序构成了系统进程组。这些应用程序为系统的所有用户提供服务,它们通常是init进程的子进程。在启动loginwindow后被创建的进程构成了用户进程组。用户进程总是与一个特定的用户会话相关联,它们通常是用户会话的窗口管理器(Window Manager)进程的子进程。
注意:并非所有的用户进程都是窗口管理器(Window Manager)进程的子进程。用户可以是由root启动的进程和某些特殊系统进程的拥有者,这些进程是init进程的子进程。您可使用进程显示程序(Process Viewer)应用程序来确定系统任何进程的拥有者和父进程。当用户注销会话时,loginwindow应用程序将终止在该用户会话期间内运行的所有进程,这是完全结束会话的必要条件。而系统进程将不受用户注销的影响,只有当系统本身关闭或重启动时系统进程才被终止。关于注销、重启动或关机流程的更多信息,请参阅“注销”。
4 rc.boot和rc脚本
/etc中的rc.boot和rc Bourne外壳脚本执行了基本的初始化任务。rc.boot脚本首先执行一次文件系统一致性检验(file-system consistency check ,fsck),并使存储器与文件系统同步(sync)。然后,rc脚本将完成下列动作:
启动设备驱动程序的装载程序(kextd)。
启动ATS服务程序。
启动窗口服务程序。
运行更新后台进程,它周期性地刷新文件系统缓存。
为虚拟存储系统创建交换文件并启动动态页面调度程序。
最后,rc脚本启动SystemStarter程序,处理本地与系统启动项目(请参阅“启动项目”)。由于rc脚本是简单的Bourne外壳脚本,您可以直接阅读其源代码,以确切地了解所发生的事情。关于在系统安装期间所启动的守护程序的更多信息,请参阅“系统守护程序”。
5 启动项目
启动项目是为Mac OS X系统正常运转而在引导的最后阶段运行的过程。它们由程序(包括外壳脚本)组成,这些程序执行诸如清除临时文件和启动系统守护程序等任务。
Apple提供的系统启动项目位于/System/Library/StartupItems中。您不可修改在此目录中的项目。然而,您可定义自己的启动项目并将它们存放在/Library/StartupItems中。关于如何创建自己的启动项目的说明,请参阅“创建定制启动项目”。SystemStarter程序是由rc脚本运行的最后程序,它协调所有启动项目的执行。了解SystemStarter的功能对理解什么是启动项目是有帮助的。启动项目是一个包含至少两个文件的文件夹:
一个程序(一般为一个外壳脚本),其名称与文件夹名称一致。
一个配置属性列表文件
每一个启动项目的配置属性列表都被命名为StartupParameters.plist。此属性列表指定了启动项目的名称,更重要的是,多层次地指定了启动项目间的相互依赖关系。属性列表中的值指明该启动项目可以提供何种服务,在启动该项目前应首先运行何种服务,以及该启动项目本身需要使用何种服务(如果需要)。SystemStarter使用这些相互依赖关系的信息来决定所有启动项目的启动次序。
SystemStarter程序并行地启动尽可能多的启动项目。将启动项目根据它们的相关性组织成不同的组。只有当同一组的项目都被启动后,下一组的项目才开始被启动。关于StartupParameters.plist中键值对的更多信息,请参阅“创建定制启动项目”。关于属性列表的一般信息,请参阅“属性列表”。
6 系统守护程序
当用户登录到Mac OS X系统时,许多进程已处于运行状态。这些进程的大多数是由系统创建并运行于后台的守护程序或服务程序。少数是由loginwindow应用程序和窗口管理守护程序为用户创建的。在登录后立即启动进程显示程序(Process Viewer)(位于/Applications/Utilities),将引出一个类似图1中显示的窗口。
图1
7 创建定制启动项目
通过创建新的启动项目,您可把专用的功能加入引导流程。在“启动项目”中描述的启动项目是一个程序或外壳脚本,它们在首次登录会话以前执行各种服务,例如启动系统守护程序、删除旧文件或任何其它维护任务。启动项目在引导流程的最后阶段运行(通过SystemStarter程序)。此时,SystemStarter
在/System/Library/StartupItems和/Library/StartupItems目录中搜寻启动项目。它从每个启动项目的属性列表中收集信息,并且使用那些信息决定项目的执行次序。然后以基于项目的相关性形成的组来执行启动项目。
/System/Library/StartupItems目录是为Mac OS X装载的启动项目而保留的。所有其它的启动项目应被放置在/Library/StartupItems目录中。注意这个目录并非默认存在,可能需要在安装启动项目时创建。为了创建一个新的启动项目,您必须创建一个程序或脚本来执行您的代码,并且必须创建一个包含启动项目信息的属性列表文件。以下几节将更详尽地描述这些技术。
注意:尽管单个启动项目能执行多个任务并启动多个守护程序,但建议您最好将一个启动项目限制于一个任务。每个项目执行一个任务可使相关性的分离更为容易,并可加快启动项目的装入。
8 创建启动项目可执行文件
启动项目可执行文件包含了您的启动项目的代码,它可作为命令行程序或外壳脚本来被执行。通常,仅在系统启动时才调用这些可执行文件。但实际上,SystemStarter具有在此以后调用这些可执行文件的能力(请参阅“启动和停止启动项目”)。创建启动项目的步骤如下:
8.1 为启动项目创建一个目录。目录名称应与您提供的功能相符。
例如:MyDBServer
8.2 将可执行文件加入目录中。可执行文件的名称应与目录名称完全相同。
例如:MyDBServer/MyDBServer
8.3 创建名为StartupParameters.plist的属性列表并将其加入目录。请参阅“指定启动项目功能”。
例如:MyDBServer/StartupParameters.plist
8.4 创建安装程序,将启动项目放置在/Library/StartupItems目标系统的目录中。(安装程序可能需要首先创建此目录。)
Mac OS X提供一些外壳脚本代码,以简化创建启动项目的过程。文件/etc/rc.common定义了一些例程,对于处理命令行变量和收集系统设置是有用的。为使用这些例程,如下例所示,在一个外壳脚本中引用rc.common文件,并调用RunService例程,将第一个命令行参数传递给它:
#!/bin/sh
. /etc/rc.common
#
# Your startup item code
#
RunService "$1"
RunService例程在外壳脚本中搜寻StartService、StopService以及RestartService例程,根据需要来调用它们以启动、停止或重新启动您的服务。而您必须为所有三个例程提供具体实现(当然您的服务也可以不支持其中的某个例程)。如果启动项目可执行文件包含可能需要一点时间完成的代码,那么您应该考虑将该代码作为守护程序或后台进程来运行。直接从脚本执行冗长的启动任务将推迟系统启动。启动项目脚本应尽可能快地执行,然后退出。
<!--EndFragment-->