5.1. Arranging for the Kernel to ExecuteThe Mac OS X kernel is a Mach-O executable that resides as /mach_kernel by default on a boot volume. Recall that in Chapter 4, we examined the kernel executable using the otool program to determine the kernel's entry point. When the kernel is compiled, the final linking stage arranges several aspects of the executable, such as the following:
5.1.1. Exceptions and Exception VectorsThe __VECTORS segment contains the kernel's exception vectors. As we saw in Chapter 4, BootX copies these to their designated locationsstarting at address 0x0before calling the kernel. These vectors are implemented in osfmk/ppc/lowmem_vectors.s. Table 51 contains an overview of PowerPC exceptions, most of which are subject to one or more conditions. For example, exceptions caused by failed effective-to-virtual address translations occur only if address translation is enabled. Moreover, most exceptions can occur only when no higher-priority exception exists.
Most hardware exceptions in the Mac OS X kernel are channeled through a common exception-handling routine: exception_entry() [osfmk/ppc/lowmem_vectors.s]. The designated exception handler saves GPR13 and GPR11, sets a "rupt" code in GPR11, and jumps to exception_entry. For example, the following is the exception handler for T_INSTRUCTION_ACCESS: . = 0x400 .L_handler400: mtsprg 2,r13 ; Save R13 mtsprg 3,r11 ; Save R11 li r11,T_INSTRUCTION_ACCESS ; Set rupt code b .L_exception_entry ; Join common Note that several exceptions in Table 51 may do "nothing," depending on the hardware being used, whether the kernel is being debugged, and other factors. 5.1.2. Kernel SymbolsTwo other related files are usually present on the root volume: /mach.sym and /mach. The /mach.sym file contains symbols from the currently running kernel. It is meant for use by programs that need to access kernel data structures. In some cases, the on-disk kernel executable may not correspond to the running kernelfor example, in the case of a network boot. In fact, there may not even be a kernel executable present on the root file system. To address this issue, the kernel can generate a dump of its own symbols and write it to a designated file. This file's pathname can be retrieved using the KERN_SYMFILE sysctl, which provides read access to the kern.symfile sysctl variable. $ sysctl kern.symfile kern.symfile = \mach.sym The kernel implementation of the KERNEL_SYMFILE sysctl checks whether /mach.sym is open by looking at a global Boolean variable. If it is not open, the kernel outputs kernel symbols to /mach.sym and marks it as open. The kernel does not dump symbols to /mach.sym if the root device is being accessed over the network, if /mach.sym exists as a nonregular file, or if it exists as a file with a link count of more than one. This symbol-file creation is triggered during user-level system startup from /etc/rc, which uses the sysctl command to retrieve the value of the kern.symfile variable. # /etc/rc ... # Create mach symbol file sysctl -n kern.symfile if [ -f /mach.sym ]; then ln -sf /mach.sym /mach else ln -sf /mach_kernel /mach fi We see that if /mach.sym exists, /mach is created as a symbolic link to it, otherwise /mach is a symbolic link to /mach_kernel. Moreover, since /mach.sym is useful only if it corresponds to the running kernel, it is deleted and recreated during every boot. $ ls -l /mach* lrwxr-xr-x 1 root admin 9 Mar 10 16:07 /mach -> /mach.sym -r--r--r-- 1 root admin 598865 Mar 10 16:07 /mach.sym -rw-r--r-- 1 root wheel 4330320 Feb 3 20:51 /mach_kernel Note that the kernel supports dumping symbols only once per bootif you delete /mach.sym, running the sysctl command will not regenerate it unless you reboot. The symbols in /mach.sym are the same as in the running kernel's executable, although section references in the symbol table are converted to absolute references. In fact, /mach.sym is a Mach-O executable containing a load command for the __TEXT segment, a load command for the __DATA segment, and an LC_SYMTAB load command for the symbol table. Only the __const section of the __TEXT segment is nonempty, containing the kernel vtables. $ otool -hv /mach.sym /mach.sym: Mach header magic cputype cpusubtype filetype ncmds sizeofcmds flags MH_MAGIC PPC ALL EXECUTE 3 816 NOUNDEFS $ otool -l /mach.sym ... Load command 2 cmd LC_SYMTAB cmdsize 24 symoff 184320 nsyms 11778 stroff 325656 strsize 273208 $ nm -j /mach_kernel > /tmp/mach_kernel.sym $ nm -j /mach.sym > /tmp/mach.sym.sym $ ls -l /tmp/mach_kernel.sym /tmp/mach.sym.sym -rw-r--r-- 1 amit wheel 273204 Mar 10 19:22 /tmp/mach.sym.sym -rw-r--r-- 1 amit wheel 273204 Mar 10 19:22 /tmp/mach_kernel.sym $ diff /tmp/mach_kernel.sym /tmp/mach.sym.sym # no output produced by diff $ nm /mach_kernel | grep __start_cpu 00092380 T __start_cpu $ nm /mach.sym | grep __start_cpu 00092380 A __start_cpu 5.1.3. Run Kernel RunFigure 51 shows a very high level overview of Mac OS X system startup. In the rest of this chapter, we will look at details of the steps listed in the "Kernel" and "User" boxes. Figure 51. A high-level view of Mac OS X system startup
The qualifications low-level and high-level are subjective and approximate. For example, the I/O Kitspecifically the platform driver, such as AppleMacRISC4PEhandles certain low-level aspects of processor initialization, but the I/O Kit is not active during very early kernel startup. |