Table of Contents
Most NetBSD users will sooner or later want to recompile their kernel, or compile a customized kernel. This might be for several reasons:
you can install bug-fixes, security updates, or new functionality by rebuilding the kernel from updated sources.
by removing unused device drivers and kernel sub-systems from your configuration, you can dramatically reduce kernel size and, therefore, memory usage.
by enabling optimisations more specific to your hardware, or tuning the system to match your specific sizing and workload, you can improve performance.
you can access additional features by enabling kernel options or sub-systems, some of which are experimental or disabled by default.
you can solve problems of detection/conflicts of peripherals.
you can customize some options (for example keyboard layout, BIOS clock offset, ...)
you can get a deeper knowledge of the system.
To recompile the kernel you must have installed the compiler set
(comp.tgz
).
The basic steps to an updated or customised kernel then are:
Install or update the kernel sources
Create or modify the kernel configuration file
Building the kernel from the configuration file, either manually or using build.sh
Install the kernel
If you chose to use AnonCVS to fetch the entire source tree, be patient, the operation can last many minutes, because the repository contains thousands of files.
If you have a source tarball, you can extract it as root:
#
cd /
#
tar zxf /path/to/syssrc.tgz
Even if you used the tarball from the release, you may wish to use AnonCVS to update the sources with changes that have been applied since the release. This might be especially relevant if you are updating the kernel to include the fix for a specific bug, including a vulnerability described in a NetBSD Security Advisory. You might want to get the latest sources on the relevant release or critical updates branch for your version, or Security Advisories will usually contain information on the dates or revisions of the files containing the specific fixes concerned. See Section 29.4, “Fetching by CVS” for more details on the CVS commands used to update sources from these branches.
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.
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:
support for hardware devices is included/excluded in the kernel (for example, SCSI support can be removed if it is not needed.)
support for kernel features is enabled/disabled (for example, enable NFS client support, enable Linux compatibility, ...)
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
atYYY
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. 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.
Based on your kernel configuration file, either one of the standard configurations or your customised configuration, a new kernel must be built.
These steps can either be performed manually, or using the
build.sh command that was introduced
in section Chapter 30, Crosscompiling NetBSD with build.sh
.
This section will give instructions on how to build a native
kernel using manual steps, the following section Section 31.5, “Building the kernel using build.sh
” describes how to use
build.sh to do the same.
Configure the kernel
Generate dependencies
Compile the kernel
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.
As the config(8) program used to create header files and Makefile for a kernel build is platform specific, it is necessary to use the nbconfig program that's part of a newly created toolchain (created for example with
/usr/src/build.sh -m sparc64 tools/
). That aside, the procedure is just as like compiling a "native" NetBSD kernel. The command is for example:
%
/usr/src/tooldir.NetBSD-4.0-i386/bin/nbconfig
MYKERNEL
This command has created a directory
../compile/
with a number of header files defining information about devices
to compile into the kernel, a Makefile that is setup to build
all the needed files for the kernel, and link them together.MYKERNEL
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 result of a successful make command is the
netbsd
file in the compile directory, ready
to be installed.
For crosscompiling a sparc64 kernel, it is necessary to use the
crosscompiler toolchain's nbmake-sparc64
shell
wrapper, which calls make(1) with all the necessary settings for
crosscompiling for a sparc64 platform:
%
cd ../compile/MYKERNEL/
%
/usr/src/tooldir.NetBSD-4.0-i386/bin/nbmake-sparc64 depend
%
/usr/src/tooldir.NetBSD-4.0-i386/bin/nbmake-sparc64
This will churn away a bit, then spit out a kernel:
... text data bss dec hex filename 5016899 163728 628752 5809379 58a4e3 netbsd%
ls -l netbsd
-rwxr-xr-x 1 feyrer 666 5874663 Dec 2 23:17 netbsd%
file netbsd
netbsd: ELF 64-bit MSB executable, SPARC V9, version 1 (SYSV), statically linked, not stripped
Now the kernel in the file netbsd
can
either be transferred to an UltraSPARC machine (via NFS, FTP,
scp, etc.) and booted from a possible harddisk, or directly from
the cross-development machine using NFS.
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.
Whichever method was used to produce the new kernel file, it must now be installed. The new kernel file should be copied to 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
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 revise your custom kernel config file to resolve the problem. In general, it's wise to start with a GENERIC kernel first, and then make gradual changes.