Mac OS X Internals: A Systems Approach
6.10. Compiling the Kernel
In this section, we will briefly discuss the kernel compilation procedure in Mac OS X. Depending on the Darwin release, you might need the following Darwin packages to compile the xnu kernel:
Mac OS X does not have a publicly well-defined kernel compilation procedure. Compiling the kernel requires certain tools and libraries that are part of Darwin but are not installed by default. These prerequisites must be compiled from source. However, they are few in number, and it is straightforward to compile them. Moreover, depending on the specific Darwin release you use, you may require more or fewer steps than the ones described in this section.
6.10.1. Retrieving Prerequisite Packages
We begin by retrieving and unpacking the required package archives.[20] Let us assume all package archives have been expanded within the /work/darwin/ directory. Each package will expand into a directory whose name includes the package's name and version. We will omit the version number in the examples in this section. [20] On some Mac OS X versions, the header file ar.h may be missing from the Kernel framework's Headers/ subdirectory. If this is the case, copy /usr/include/ar.h to /System/Library/Frameworks/Kernel.framework/Headers/.
6.10.2. Compiling Prerequisite Packages
Change directory to bootstrap_cmds/relpath.tproj/, and run make to compile and install the relpath tool, which calculates the relative path from a given directory to a given path. $ cd /work/darwin/bootstrap_cmds/relpath.tproj $ sudo make install ... $ relpath /usr/local/ /usr/local/bin/relpath bin/relpath
relpath is used in various "doconf" shell scripts in the kernel source tree to set up build paths during the precompilation ("config") stage of the kernel build process.
The tools and libraries that you compile and install from these support packages are installed by default in the /usr/local/ directory hierarchy. You must ensure that /usr/local/ is in your shell's path. A benefit of confining this software to /usr/local/ is that you will not accidentally overwrite any standard files belonging to the operating system.
The rest of the packages are needed to satisfy the following requirements:
Figure 654 shows dependencies between the packages. libsa links against a static kernel link editor library (libkld.a), which comes from the cctools package. libkld.a in turn depends on the Libstreams package, the libmacho library, and the libstuff library. libmacho and libstuff come from the cctools package. libsa also requires a tool called seg_hack, which can change all segment names in a Mach-O file to the one specified on the command line. The kernel compilation process uses seg_hack to change segment names to __KLD while compiling libsa. We can satisfy these dependencies by appropriately traversing the graph shown in Figure 654. Figure 654. Software dependencies in the kernel build process
Change directory to the Libstreams package, and run make to compile and copy the required headers and libraries to the /usr/local/ hierarchy. $ cd /work/darwin/Libstreams/ $ sudo make install ...
The components within the cctools package must be compiled in a particular sequence since they have internal dependencies. Change directory to cctools/libstuff/, and run make. No installation is required since we need the result of this build only to compile other components in this package. Change directory to cctools/misc/, and run the following commands, which compile and install seg_hack in /usr/local/bin/ with the appropriate ownership and permissions. $ make seg_hack.NEW $ sudo install -o root -g wheel -m 0755 seg_hack.NEW /usr/local/bin/seg_hack
Change directory to cctools/libmacho/, and run make. Again, no installation is required. Change directory to cctools/ld/, and run the following commands. $ make kld_build $ sudo install -o root -g wheel -m 0755 static_kld/libkld.a /usr/local/lib/ $ sudo ranlib /usr/local/lib/libkld.a Finally, we need to compile kextsymboltool, which the build process uses for generating symbol sets from compiled kernel components. BSDKernel.symbolset, IOKit.symbolset, Libkern.symbolset, and Mach.symbolset are examples of the resultant files that exist in the BUILD directory hierarchy of a compiled kernel source tree. These Mach-O relocatable object files contain nothing besides a symbol table, for example: $ cd /work/darwin/xnu/BUILD/obj/DEBUG_PPC/ $ file Mach.symbolset Mach.symbolset: Mach-O object ppc $ otool -l Mach.symbolset Mach.symbolset: Load command 0 cmd LC_SYMTAB cmdsize 24 symoff 52 nsyms 2652 stroff 31876 strsize 49748 $ cd /work/darwin/xnu/BUILD/obj/RELEASE_PPC/ $ otool -l Mach.symbolset Mach.symbolset: Load command 0 cmd LC_SYMTAB cmdsize 24 symoff 52 nsyms 52 stroff 676 strsize 1128 The source for kextsymboltool is in the kext_tools package. However, its compilation depends on header files from the IOKitUser and cctools packages. Change directory to kext_tools/, and run the following commands. $ mkdir IOKit $ ln -s /work/darwin/IOKitUser/kext.subproj IOKit/kext $ gcc -I /work/darwin/cctools/include -I . -o kextsymboltool kextsymbool.c $ sudo install -o root -g wheel -m 0755 kextsymboltool /usr/local/bin/ 6.10.3. Compiling the xnu Package
At this point, we are ready to compile the kernel. Change directory to xnu/, and run the following command to initiate kernel compilation. $ make exporthdrs && make all
This will create a standard (RELEASE configuration) kernel, which will be available as xnu/BUILD/obj/RELEASE_PPC/mach_kernel at the end of the compilation. Alternative build configurations include DEBUG and PROFILE, which yield debugging and profiling versions, respectively, of the kernel. The following command will compile a debug version, which will be available as xnu/BUILD/obj/DEBUG_PPC/mach_kernel at the end of the compilation: $ make exporthdrs && make KERNEL_CONFIGS=DEBUG all
Regardless of which kernel configuration you build, a kernel object file with full symbolic information is generated as mach_kernel.sys in the same directory as mach_kernel. A typical mach_kernel.sys is several times larger than the corresponding mach_kernel and contains more symbols. Table 618 compares some aspects of release, profile, and debug builds for a particular kernel version.
6.10.4. DarwinBuild
A convenient way to compile the xnu kernel (in fact, any Darwin package in general) is through DarwinBuilda specialized open source tool that provides a build environment similar to Apple's internal build environment. DarwinBuild's usefulness is evident when building complex packages with a large number of dependencies, for example, the system library. Specifically, DarwinBuild consists of two primary harness programs: darwinbuild, which builds software, and darwinxref, which parses property list files containing project information and performs a variety of operations such as resolving dependencies, finding files, and loading indexes. |
Категории