< Previous PageNext Page > Hide TOC

The Boot Process

From the moment a user turns on a Mac OS X system to beyond the time the login window appears, Mac OS X executes a boot sequence that readies the system for use. If you provide system services to all users, you might need to execute some code during this process. The following sections explain the basic boot sequence and the places where your code can tie into it.

Contents:

BootROM
BootX, boot.efi, and System Initialization
Authenticating Users
Configuring User Sessions
Logout Responsibilities
Identifying the Scope of Processes
The Shutdown Process


BootROM

When the power to a Macintosh computer is turned on, the BootROM firmware is activated. BootROM (which is part of the computer’s hardware) has two primary responsibilities: it initializes system hardware and it selects an operating system to run. BootROM has two components to help it carry out these functions:

If multiple installations of Mac OS X are available, BootROM chooses the one that was last selected by the Startup Disk System Preference. The user can override this choice by holding down the Option key while the computer boots, which causes Open Firmware or EFI to display a screen for choosing the boot volume.

Note: On some legacy hardware, the same version of BootROM can start either Mac OS 9 or Mac OS X. Most current hardware can start only Mac OS X.

BootX, boot.efi, and System Initialization

Once BootROM is finished and a Mac OS X partition has been selected, control passes to the BootX (PowerPC) or boot.efi (Intel) boot loader. The principal job of this boot loader is to load the kernel environment. As it does this, the boot loader draws the “booting” image on the screen.

BootX and boot.efi can be found in the /System/Library/CoreServices directory on the root partition. In addition, a copy of boot.efi can be found at /usr/standalone/i386/boot.efi.

In "exotic” boot situations such as booting from a software RAID volume, a copy of the boot loader is stored on a separate HFS+ “helper” volume to get the system started. In some versions of Mac OS X, a copy of the kernel and mkext cache are also included on the helper volume. In these cases, the booter and other components on the root volume are unused.

Note: Booting from a UFS volume is deprecated as of Mac OS X v10.5.

The boot loader first attempts to load a prelinked version of the kernel that includes all device drivers that are involved in the boot process. This prelinked kernel is located in /System/Library/Caches/com.apple.kernelcaches. By linking these drivers into the kernel ahead of time, boot time is reduced.

If the prelinked kernel is missing, out-of-date, or corrupt, the boot loader attempts to load that same set of device drivers all at once in the form of a single, compressed archive called an mkext cache.

If this cache is also out-of-date, missing, or corrupt, the boot loader searches /System/Library/Extensions for drivers and other kernel extensions whose OSBundleRequired property is set to a value appropriate to the type of boot (for example, local or network boot).

For more information on how drivers are loaded, see I/O Kit Fundamentals.

Once the kernel and all drivers necessary for booting are loaded, the boot loader starts the kernel’s initialization procedure. At this point, enough drivers are loaded for the kernel to find the root device. Also from this point, on PowerPC-based Macintosh computers, Open Firmware is no longer accessible (quiesced).

The kernel initializes the Mach and BSD data structures and then initializes the I/O Kit. The I/O Kit links the loaded drivers into the kernel, using the device tree to determine which drivers to link. Once the kernel finds the root device, it roots(*) BSD off of it.

Note: As a terminology aside, the term “boot” was historically reserved for loading a bootstrap loader and kernel off of a disk or partition. In more recent years, the usage has evolved to allow a second meaning: the entire process from initial bootstrap until the OS is generally usable by an end user. In this case, the term is used according to the former meaning.

As used here, the term “root” refers to mounting a partition as the root, or top-level, filesystem. Thus, while the OS boots off of the root partition, the kernel roots the OS off of the partition before executing startup scripts from it.

Prior to Mac OS X v10.4, the remaining system initialization was handled by the mach_init and init processes. During the course of initialization, these processes would call various system scripts (including /etc/rc), run startup items, and generally prepare the system for the user. While many of the same scripts and daemons are still run, the mach_init and init processes have been replaced by launchd in Mac OS X v10.4 and later. This change means that launchd is now the root system process.

In addition to initializing the system, the launchd process coordinates the launching of system daemons in an orderly manner. Like the inetd process, launchd launches daemons on-demand. Daemons launched in this manner can shut down during periods of inactivity and be relaunched as needed. (When a subsequent service request comes in, launchd automatically relaunches the daemon to process the request.)

This technique frees up memory and other resources associated with the daemon, which is worthwhile if the daemon is likely to be idle for extended periods of time. More importantly, however, this guarantees that runtime dependencies between daemons are satisfied without the need for manual lists of dependencies.

Next, launchd starts SystemStarter, which starts any non-launch-on-demand daemons.

Note: While launchd does support non-launch-on-demand daemons, this use is not recommended. The launchd daemon was designed to remove the need for dependency ordering among daemons. If you do not make your daemon be launch-on-demand, you will have to handle these dependencies in another way, such as by using the legacy startup item mechanism.

For more information about launch-on-demand and SystemStarter daemons and how to launch them, see “Daemons.”

As the final part of system initialization, launchd launches loginwindow. The loginwindow program controls several aspects of user sessions and coordinates the display of the login window and the authentication of users.

Note: By default, Mac OS X boots with a graphical boot screen. For debugging the boot process, it is often useful to disable this, revealing the text console underneath. This mode is known as verbose boot mode. To enable verbose boot mode, simply hold down command-v after the boot chime.

Authenticating Users

Mac OS X requires users to authenticate themselves prior to accessing the system. The loginwindow program coordinates the visual portion of the login process (as manifested by the window where users enter name and password information) and the security portion (which handles the user authentication). Once a user is authenticated by the security systems, loginwindow begins setting up the user environment.

In two key situations, loginwindow bypasses the usual login prompt and begins the user session immediately. The first situation occurs when the system administrator has configured the computer to automatically log in as a specified user. The second occurs during software installation when the installer program is to be launched immediately after a reboot.

Configuring User Sessions

Immediately after the user is successfully authenticated, loginwindow sets up the user environment and records information about the login. As part of this process, it performs the following tasks:

Once the user session is up and running, loginwindow monitors the session and user applications in the following ways:

If the Finder, Dock, or SystemUIServer processes die for some reason, loginwindow automatically restarts them. In the same manner, if the loginwindow process dies, the launchd process automatically restarts it.

Logout Responsibilities

The procedures for logging out, restarting the system, or shutting down the system have similar semantics. The foreground process usually initiates these procedures in response to the user choosing an item from the Apple menu; however, a process can also initiate the procedure programmatically by sending an appropriate Apple event to loginwindow. The loginwindow program carries out the procedure, posting alerts and notifying applications to give them a chance to clean up before closing.

A typical logout/restart/shutdown procedure is as follows:

  1. The user selects Log Out, Restart, or Shut Down from the Apple menu.

  2. The foreground application initiates the user request by sending an Apple event to loginwindow. (See “Application Responsibilities” for a list of events.)

  3. The loginwindow program displays an alert to the user asking for confirmation of the action.

  4. If the user confirms the action, loginwindow sends a Quit Application Apple event (kAEQuitApplication) to every foreground and background user process.

  5. Once all processes have quit, loginwindow closes out the user session and continues with the action.

    • For a logout action, loginwindow dequeues all events in the event queue, starts the logout-hook program (if one is defined), records the logout, resets device permissions and user preferences to their defaults, and quits. It is subsequently relaunched by launchd to handle a new login. (See “Customizing Login and Logout” for more on loginwindow hooks.)

    • For a restart action, loginwindow sets the device permissions and user preferences to their defaults and then restarts the system.

    • For a shutdown action, loginwindow powers off the system.

Foreground processes can choose not to terminate when they receive the Quit Application event. See “Terminating Processes” for more information.

Application Responsibilities

To initiate a logout, restart, or shutdown sequence programmatically, the foreground application must send an appropriate Apple event to loginwindow. Upon receipt of the event, loginwindow begins the process of shutting down the user session. Depending on the Apple event sent by the process, loginwindow may or may not post an alert dialog and give the user a chance to abort the sequence.

The following list shows the preferred Apple events for logout, restart, and shutdown procedures. These events have no required parameters.

Upon receipt of one of these events, loginwindow displays an alert notifying the user of the impending action. At this point, the user may continue with the action or abort it. If the user continues with the action, loginwindow sends an Apple event to each application asking it to quit. See “Terminating Processes.”

In addition to the preferred Apple events, there are two additional events that tell loginwindow to proceed immediately with a restart or shutdown sequence:

These events proceed with the corresponding sequence without posting an alert dialog to the user. Thus, if you send one of these events to loginwindow, the user does not have an opportunity to abort the sequence. These events should be used sparingly, if at all.

Important: Note that if a logout, restart, or shutdown event originates from an application in the Classic environment, the event affects only the Classic environment and its applications. The rest of the user session continues running.

Terminating Processes

As part of a log out, restart, or shutdown sequence, loginwindow attempts to terminate all foreground and background user processes. It sends each process a Quit Application Apple event (kAEQuitApplication), as a courtesy, to give each process a chance to shut itself down gracefully. For foreground processes, loginwindow sends the event and waits for a reply. For background processes, loginwindow sends the event but does not wait for a reply. It terminates any lingering background processes by sending a kill command.

When a foreground process receives the Quit Application Apple event from loginwindow, it should terminate itself immediately or post an alert dialog if a user decision is required first (such as when there is an unsaved document); when that condition is resolved the application should then terminate. If the user decides to abort the termination sequence (by clicking Cancel in a Save dialog, for example) the application should respond to the event by returning a userCancelledErr error.

Note: Cocoa applications do not see the kAEQuitApplication event directly. The Application Kit notifies your application by calling its applicationShouldTerminate: delegate method. To abort the termination sequence, implement this method and return NSTerminateCancel; otherwise, termination of your application continues normally.

If a foreground application fails to reply or terminate itself after 45 seconds, loginwindow automatically aborts the termination sequence. This safeguard is to protect data in various situations, such as when an application is saving a large file to disk and is unable to terminate in the allotted time. If a foreground application is unresponsive and not doing anything, the user must use the Force Quit window to kill it before proceeding.

For user background processes that link with Carbon, Cocoa, or Java, the procedure is a little different. The loginwindow program notifies the process that it is about to be terminated by sending it a Quit Application Apple event (kAEQuitApplication) as before. Unlike foreground processes, however, loginwindow does not wait for a reply. It proceeds to terminate any open background processes, regardless of any returned errors.

During a user logout, loginwindow does not terminate processes residing in the root context. These processes reside outside the context of the user session and are terminated only during a restart or shutdown sequence. The loginwindow program also does not kill background processes that are independent of Carbon, Cocoa, or Java, even if they are launched from the user context. (Though launched from a user context, these processes are taken over by the system when the user logs out.) Mac OS X does not send any notifications to system processes before terminating them.

Identifying the Scope of Processes

Although the launchd process owns every other process on the system, a distinction can still be made between user and system processes. Startup items, daemonized processes, and any processes run prior to loginwindow typically run in the root context. Processes in this context provide services to all users of the system.

Processes that run within the context of an authenticated user session are user processes. User processes are always associated with a particular user session and are usually children of the WindowServer or loginwindow processes associated with the user login.

Note: Not all user processes are children of the WindowServer process. Processes launched as root, and some special system processes, are owned by the user but are children of the launchd process. You can use the ActivityMonitor application to determine the owner and parent of any process on the system.

The Shutdown Process

At shutdown, Mac OS X first executes the service stop routines in any SystemStarter startup items such as those described in “Creating a Startup Item.”

Next, as with most UNIX-based and UNIX-like operating systems, Mac OS X sends a SIGTERM signal to all running processes prior to shutdown. Upon receiving this signal, your daemon should quickly make an orderly shutdown.

Every reasonable attempt will be made to wait for it to exit, but it is ultimately the responsibility of your daemon to keep the amount of unsaved state information to a level that can be reasonably written to disk in the time allotted.

A few seconds later, your daemon will receive a SIGKILL signal and will be terminated.



< Previous PageNext Page > Hide TOC


© 2003, 2008 Apple Inc. All Rights Reserved. (Last updated: 2008-11-19)


Did this document help you?
Yes: Tell us what works for you.
It’s good, but: Report typos, inaccuracies, and so forth.
It wasn’t helpful: Tell us what would have helped.