# # CDDL HEADER START # # The contents of this file are subject to the terms of the # Common Development and Distribution License (the "License"). # You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. # See the License for the specific language governing permissions # and limitations under the License. # # When distributing Covered Code, include this CDDL HEADER in each # file and include the License file at usr/src/OPENSOLARIS.LICENSE. # If applicable, add the following below this CDDL HEADER, with the # fields enclosed by brackets "[]" replaced with your own identifying # information: Portions Copyright [yyyy] [name of copyright owner] # # CDDL HEADER END # # # Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" KERNEL MAKEFILE STRUCTURE ------------------------- The advent of dynamic loading of kernel modules has obsoleted the 4.x kernel configuration scheme which was centered around a derived Makefile and a collection of derived header files generated by the config(8) program. This file describes the structure of the replacement "static" set of Makefiles. Some additional secondary goals were associated with the generation of these Makefiles. It should be noted that the ability to properly deal with derived Makefiles is an explicit non-goal of the ongoing NSE enhancements, so this project is a necessary consequence of that decision. All project goals are enumerated below: 1] To provide a set of static Makefiles to support kernel build and installation. 2] To provide a set of static Makefiles which conform to the "Makefiles Guidelines". (This document is currently available on-line as "terminator:/usr/integration/doc/make.std") 3] To completely eliminate the config(8) program. 4] To provide a framework for linting the kernel (so that "lint free" can be made an integration criterion, in addition to being general good hygiene). 5] To eliminate the need for the small headers generated by config(8). In the ddi/dki world this need is completely eliminated as drivers will be expected to dynamically configure themselves. Interim support for existing drivers will be provided. 6] To be able to "acquire" only the files needed to build a specific module, if that is all that is needed. 7] To provide a framework suitable for the production of "implementation architecture" independent modules. 8] To restructure the assembly language files to support the generation of "lint-libraries" from them. 9] To provide support for the incidental Makefile targets many developers are accustomed to (such as cscope and tags). These can be added to the Makefiles asd required. (cscope is currently supported.) GENERAL STRUCTURE ----------------- The source code layout is not generally effected by the Makefiles. However, the location of the generated files has changed dramatically. "Implementation architecture" independent modules are produced in individual directories (one per module) under the "instruction-set architecture" directory (i.e.: sparc). Similarly, "implementation architecture" dependent modules are produced in individual directories under the "implementation architecture" directory (i.e.: sun4, sun4c). It should be noted that currently (4/14/91) no implementation architecture modules exist. This situation is expected to change shortly. The driving Makefile for any module is located in the leaf directory where the module (and associated objects) are built. After a 'make clobber' operation, the Makefile is the only file remaining in that directory. Common definitions and rules are contained in suffixed Makefiles in non-leaf directories which are included in the leaf Makefiles. Non-suffixed Makefiles in non-leaf directories generally invoke lower level Makefiles to perform the actual tasks. uts/Makefile uts/sparc/Makefile uts/sun4c/Makefile uts/sun4c/svvs/Makefile These Makefiles generally are cognizant of the components made in subdirectories and invoke Makefiles in those sub- directories to perform the actual build. Some targets (or pseudo-targets) may be directly built at this level (such as the cscope databases). uts/Makefile.uts Contains common definitions for all possible architectures. uts/Makefile.targ Contains common targets for all possible architectures. uts/common/Makefile.files uts/sun/Makefile.files uts/sparc/Makefile.files uts/sun4c/Makefile.files uts/sun4/Makefile.files These Makefiles are divided into two sections. The first section can be viewed as the equivalent of the "files" (sparc and sun4c) and "files.cmn" (common and sun) files. These define the object lists which define each module. The second section defines the appropriate header search paths and other machine specific global build parameters. uts/common/Makefile.rules uts/sun/Makefile.rules uts/sparc/Makefile.rules uts/sun4c/Makefile.rules uts/sun4/Makefile.rules The files provide build rules (targets) which allow make to function in a multiple directory environment. Each source tree below the directory containing the Makefile has a build rule in the file. uts/sun4c/Makefile.sun4c uts/sun4/Makefile.sun4 These Makefile contains the definitions specific (defaults) to the obvious "implementation architecture". These rules can be overridden in specific leaf node Makefiles if necessary. uts/sun4c/unix/Makefile Main driving Makefile for building /unix. uts/sun4c/MODULE/Makefile (for MODULE in arp, aoutexec, ...) Main driving Makefile for building MODULE.kmod. uts/sun4c/unix.static/Makefile Main driving Makefile for building a static unix (for development work only). This Makefile is known to NSE, but its targets are not. This makefile may be copied to additional parallel directories to build multiple configurations. This configuration is roughly equivalent to the GENERIC kernel of SunOS 4.x. uts/*/Makefile.?.shared These denote Makefile contents which are shared between open and closed builds. The Makefiles are verbosely commented. It is desired that they should stay this way. USE --- Issuing the command 'make' in the uts directory will cause all supported, modularized kernels and modules to be built. Issuing the command 'make' in a uts/ARCHITECTURE directory (i.e.: uts/sparc) will cause all supported, "implementation architecture" independent modules for ARCHITECTURE to be built. Issuing the command 'make' in a uts/MACHINE directory (i.e.: uts/sun4c) will cause that kernel and all supported, "implementation architecture" dependent modules for MACHINE to be built. Issuing the command 'make' in the uts/MACHINE/unix directory will cause the kernel for MACHINE to be built (and unix.o). Issuing the command 'make' in a uts/MACHINE/MODULE or a uts/ARCHITECTURE/MODULE directory will cause MODULE.kmod to be built. LINT ---- Linting is fairly similar to the builds, but it has an additional complication. In order to get meaningful output from lint pass2, all the modules must be linted together. This is accomplished by each module being responsible to produce its own pass1 output (file.ln, one per .c/.s file). It is also responsible for placing the a lint-library (llib-lMODULE) in the uts/MACHINE/lint-libs directory. The final full lint is accomplished by the Makefile in the uts/MACHINE directory by linting all the lint-libraries against each other. Note that there is no equivalent to Locore.c in the current source base. The C prototypes are in the .s files. As example: #if defined(lint) int blort(int, int) { return 0 } #else /* lint */ ENTRY(blort) ld [%i0],.... .... SET_SIZE(blort) #endif /* lint */ COMPONENT HIERARCHY ------------------ The component hierarchy has been restructured to allow the acquisition of more finely grained objects; specificly a kernel module. The basic component structure is: :src:uts.all --+--> :sparc --+--> :MODULES... (none currently) | +--> :sun4c --+--> :unix | | | +--> :MODULES... | | | +--> :unix.static | +--> :sun4 ---+--> :unix | | | +--> :MODULES... | | | +--> :unix.static ... The above diagram does not reflect the full component tree. The full component tree may be displayed with the "nsecomp list -r :src:uts.all" command. COMMON OPERATIONS ----------------- Adding a New Kernel Module -------------------------- 0] Create the source files (and directories) as usual. 1] Edit uts/*/Makefile.files to define the set of objects. By convention the symbolic name of this set is of the form MODULE_OBJS, where MODULE is the module name (i.e.: namefs). The files in each subtree should be defined in the Makefile.files in the root directory of that subtree. Note that they are defined using the += operator, so that the set can be built across multiple files. As example: NAMEFS_OBJS += namevfs.o namevno.o Each source file needs a build rule in the corresponding Makefile.rules file (compilation and lint). A typical pair of entries would be: $(OBJS_DIR)/mem.o: $(UTSBASE)/sun4c/io/mem.c $(COMPILE.c) -o $@ $(UTSBASE)/sun4c/io/mem.c $(LINTS_DIR)/mem.ln: $(UTSBASE)/sun4c/io/mem.c @($(LHEAD) $(LINT.c) $(UTSBASE)/sun4c/io/mem.c $(LTAIL)) 2] Create build directories in the appropriate places. If the module can be built in a machine independent way, this would be in the "instruction set architecture" directory (i.e.: sparc). If not, these directories would be created for all appropriate "implementation architecture" dependent directories (i.e.: sun4, sun4c). 3] In each build directory, create a Makefile. This can usually be accomplished by copying a Makefile from a parallel directory and editing the following lines (in addition to comments). MODULE = namefs - replace with module name OBJECTS = $(NAMEFS_OBJS:%=$(OBJS_DIR)/%) LINTS = $(NAMEFS_OBJS:%.o=$(LINTS_DIR)/%.ln) - replace with MODULE_OBJS ROOTMODULE = $(ROOT_FS_DIR)/$(MODULE).kmod - replace directory part with the appropriate installation directory name (see Makefile.uts) If a custom version of modstubs.o is needed to check the undefines for this routine, the following lines need to appear in the Makefile (after the inclusion of Makefile.mach (i.e.: Makefile.sun4c)). MODSTUBS_DIR = $(OBJS_DIR) $(MODSTUBS_O) := AS_CPPFLAGS += -DNAMEFS_MODULE - replace "-DNAMEFS_MODULE" with the appropriate flag for the modstubs.o assembly. CLEANFILES += $(MODSTUBS_O) 4] Edit the parent Makefile.mach (i.e.: Makefile.sun4c) to know about the new module: FS_KMODS += fd fifo namefs nfs proc spec ufs ------ Any additional questions can be easily answered by looking at the many existing examples. Moving a Module to the "Implementation Architecture" Independent Build ---------------------------------------------------------------------- 1] Create the build directory under the appropriate "instruction set architecture" build directory (i.e.: sparc/MODULE). 2] Move the Makefile from the "implementation architecture" build directory (i.e.: sun4c/MODULE) to the directory created above. Edit this Makefile to reflect the change of parent (trivial: comments, paths and includes). 3] Edit the "implementation architecture" directory Makefile (i.e.: Makefile.sun4c) to *not* know about this module and edit the "instruction set architecture" directory Makefile (i.e.: Makefile.sparc) to know about it.