sword in the stone   Hayne of Tintagel
Mac OS X  /  Programming  /  Notes on Boot Sequence

References on the OS X boot sequence

Notes on the OS X boot sequence

Here is the sequence of operations at Mac OS X startup: (extracted from the above references)
 0) Press power button
 1) The BootROM firmware is run. It does the following:
 1.1) POST (Power-On Self Test) initializes some hardware interfaces
      and tests the RAM. If all is well, plays the startup chime.
      If some problem is found, gives an indication via beeps:
      see http://docs.info.apple.com/article.html?artnum=58442
 1.2) Open Firmware initializes the rest of the hardware,
      builds the initial device tree (a hierarchical representation
      of devices associated with the computer), and selects the
      operating system to use.
 2) When BootROM (or the user) selects Mac OS X as the operating system
    to boot, control passes to the BootX booter
    (located in /System/Library/CoreServices).
    Here are the main functions called by BootX, with a short explanation
    for the parts where I have some understanding
    (from looking at the source code):
    The entry point is defined in the variable StartTVector to be the function
    Start() which calls the function Main() which calls the following sequence
    of functions. (StartTVector is defined to be the entry point via the -e
    option to 'ld' in the Makefile.)
 2.1) InitEverything()
 2.2) GetBootPaths()
        - find the kernel on the hard disk
 2.3) DrawSplashScreen(0)
        - draws the grey Apple
        - initializes the indicator (that spins to show activity)
 2.4) LoadFile(BootFile)
        - reads the kernel from disk
        - each read operation makes the indicator spin
          (this is true of the following two steps as well
           - the indicator is made to spin every time the function
           'Read()' is called)
 2.5) DecodeKernel()
 2.6) LoadDrivers(RootDir)
 2.7) DrawSplashScreen(1)
        - erases the grey apple by drawing a grey rectangle over top of it
 2.8) SetUpBootArgs()
        - sets up the command-line arguments that will be passed
          to the /etc/rc script
 2.9) CallKernel()
        - starts the kernel running
        - verbose mode messages start arriving

 3) CallKernel() invokes machine_startup() (xnu/osfmk/ppc/model_dep.c)
    which calls setup_main()               (xnu/osfmk/kern/startup.c)
    which calls start_kernel_threads()     (xnu/osfmk/kern/startup.c)
    which calls bsd_init()                 (xnu/bsd/kern/bsd_init.c)
    which hand-crafts process #0, naming it 'kernel_task'
    and then calls bsd_utaskbootstrap()    (xnu/bsd/kern/bsd_init.c)
    which creates process #1 (via a call to cloneproc()) 
    and then calls act_set_astbsd() for process #1.
    This results in a call to bsd_ast()    (xnu/bsd/kern/kern_sig.c)
    which calls bsdinit_task()             (xnu/bsd/kern/bsd_init.c)
    which assigns the name 'init' to process #1
    and then calls load_init_program()     (xnu/bsd/kern/kern_exec.c)
    which does an exec of /sbin/mach_init (without doing a fork).

    The code for 'mach_init' is in system_cmds/mach_init.tproj/bootstrap.c

    mach_init forks and then the parent process (#1) does an exec
    of /sbin/init.
    The child process from the fork is process #2 and continues running
    as mach_init.

    So, process #1 is called 'init' for a short time while it is executing
    kernel code, then it is '/sbin/mach_init', then it is '/sbin/init'
    after the fork & exec.


Thanks to "JavaOSX" on the MacOSXHints forums for useful discussions.