Chapter 28. Compiling the kernel

Table of Contents

28.1. Installing the kernel sources
28.2. Requirements and procedure
28.3. Creating the kernel configuration file
28.4. Configuring the kernel manually
28.5. Generating dependencies and recompiling manually
28.6. Using build.sh
28.7. If something went wrong

Most NetBSD users will sooner or later want to compile a customized kernel. This gives you several benefits:

28.1. Installing the kernel sources

# cd /
# tar zxf /path/to/syssrc.tgz

If you chose to use AnonCVS, be patient, the operation can last many minutes, because the repository contains hundreds of files.

Once you have the sources available, you can create a custom kernel: this is not as difficult as you might think. In fact, a new kernel can be created in a few steps which will be described in the following sections.

28.2. Requirements and procedure

To recompile the kernel you must have installed the compiler set (comp.tgz).

The basic steps for kernel compilation then are:

  1. Create/modify the kernel configuration file

  2. Configure the kernel

  3. Generate dependencies

  4. Compile the kernel

  5. Install the kernel

These steps can either be performed manually, or using the new build.sh command that was introduced in section Chapter 27, Crosscompiling NetBSD with build.sh. This section will first give instructions on how to build a native kernel using manual steps, and then describe how to use build.sh to do the same.

28.3. Creating the kernel configuration file

The directories described in this section are i386 specific. Users of other architectures must substitute the appropriate directories, see the subdirectories of src/sys/arch for a list.

The kernel configuration file defines the type, the number and the characteristics of the devices supported by the kernel as well as several kernel configuration options. For the i386 port, kernel configuration files are located in the /usr/src/sys/arch/i386/conf directory.

Please note that the names of the kernel configuration files are historically in all uppercase, so they are easy to distinguish from other files in that directory:

$ cd /usr/src/sys/arch/i386/conf/
$ ls
CARDBUS                 GENERIC_PS2TINY         NET4501
CVS                     GENERIC_TINY            SWINGER
DELPHI                  GENERIC_VERIEXEC        SWINGER.MP
DISKLESS                INSTALL                 VIRTUALPC
GENERIC                 INSTALL.MP              files.i386
GENERIC.FAST_IPSEC      INSTALL_LAPTOP          kern.ldscript
GENERIC.MP              INSTALL_PS2             kern.ldscript.4MB
GENERIC.MPDEBUG         INSTALL_SMALL           largepages.inc
GENERIC.local           INSTALL_TINY            majors.i386
GENERIC_DIAGNOSTIC      IOPENER                 std.i386
GENERIC_ISDN            LAMB
GENERIC_LAPTOP          Makefile.i386

The easiest way to create a new file is to copy an existing one and modify it. Usually the best choice on most platforms is the GENERIC configuration, as it contains most drivers and options. In the configuration file there are comments describing the options; a more detailed description is found in the options(4) man page. So, the usual procedure is:

$ cp GENERIC MYKERNEL
$ vi MYKERNEL

The modification of a kernel configuration file basically involves three operations:

  1. support for hardware devices is included/excluded in the kernel (for example, SCSI support can be removed if it is not needed.)

  2. support for kernel features is enabled/disabled (for example, enable NFS client support, enable Linux compatibility, ...)

  3. tuning kernel parameters.

Lines beginning with “#” are comments; lines are disabled by commenting them and enabled by removing the comment character. It is better to comment lines instead of deleting them; it is always possible uncomment them later.

The output of the dmesg(8) command can be used to determine which lines can be disabled. For each line of the type:

XXX at YYY

both XXX and YYY must be active in the kernel configuration file. You'll probably have to experiment a bit before achieving a minimal configuration but on a desktop system without SCSI and PCMCIA you can halve the kernel size.

You should also examine the options in the configuration file and disable the ones that you don't need. Each option has a short comment describing it, which is normally sufficient to understand what the option does. Many options have a longer and more detailed description in the options(4) man page. While you are at it you should set correctly the options for local time on the CMOS clock. For example:

options RTC_OFFSET=-60

The adjustkernel Perl script, which is available through pkgsrc, analyzes the output of dmesg(8) and automatically generates a minimal configuration file. The installation of packages is described extensively in in the Chapter 30, The package collection, but installing adjustkernel basically boils down to:

$ cd /usr/pkgsrc/sysutils/adjustkernel
$ make install

You can now run the script with:

$ cd /usr/src/sys/arch/i386/conf
$ adjustkernel GENERIC > MYKERNEL

This script usually works very well, saving a lot of manual editing. But be aware that the script only configures the available devices: you must still configure the other options manually.

28.4. Configuring the kernel manually

When you've finished modifying the kernel configuration file (which we'll call MYKERNEL), you should issue the following command:

$ config MYKERNEL

If MYKERNEL contains no errors, the config(8) program will create the necessary files for the compilation of the kernel, otherwise it will be necessary to correct the errors before running config(8) again.

28.5. Generating dependencies and recompiling manually

Dependencies generation and kernel compilation is performed by the following commands:

$ cd ../compile/MYKERNEL
$ make depend
$ make

It can happen that the compilation stops with errors; there can be a variety of reasons but the most common cause is an error in the configuration file which didn't get caught by config(8). Sometimes the failure is caused by a hardware problem (often faulty RAM chips): the compilation puts a higher stress on the system than most applications do. Another typical error is the following: option B, active, requires option A which is not active. A full compilation of the kernel can last from some minutes to several hours, depending on the hardware.

The output of the make command is the netbsd file in the compile directory: this file should be copied in the root directory, after saving the previous version.

# mv /netbsd /netbsd.old
# mv netbsd /

Customization can considerably reduce the kernel's size. In the following example netbsd.old is the install kernel and netbsd is the new kernel.

-rwxr-xr-x  3 root  wheel  3523098 Dec 10 00:13 /netbsd
-rwxr-xr-x  3 root  wheel  7566271 Dec 10 00:13 /netbsd.old

The new kernel is activated after rebooting:

# shutdown -r now

28.6. Using build.sh

After creating and possibly editing the kernel config file, the manual steps of configuring the kernel, generating dependencies and recompiling can also be done using the src/build.sh script, all in one go:

$ cd /usr/src
$ ./build.sh kernel=MYKERNEL 

This will perform the same steps as above, with one small difference: before compiling, all old object files will be removed, to start with a fresh build. This is usually overkill, and it's fine to keep the old file and only rebuild the ones whose dependencies have changed. To do this, add the -u option to build.sh:

$ cd /usr/src
$ ./build.sh -u kernel=MYKERNEL 

At the end of its job, build.sh will print out the location where the new compiled kernel can be found. It can then be installed with the steps given above in Section 28.5, “Generating dependencies and recompiling manually”.

28.7. If something went wrong

When the computer is restarted it can happen that the new kernel doesn't work as expected or even doesn't boot at all. Don't worry: if this happens, just reboot with the previously saved kernel and remove the new one (it is better to reboot “single user”):

  • Reboot the machine

  • Press the space bar at the boot prompt during the 5 seconds countdown

    boot:
  • Type

    > boot netbsd.old -s
  • Now issue the following commands to restore the previous version of the kernel:

    # fsck /
    # mount /
    # mv netbsd.old netbsd
    # reboot

This will give you back the working system you started with, and you can change the kernel config file next to make it really going. In general, it's wise to start with a GENERIC kernel first, and then make gradual changes.