Kernel-wide Design Approaches
- Entire operating system is working in kernel space
- But hard to maintain
- Can dynamically load executable modules at runtime
- Linux, *BSD, MS-DOS, Windows 9x series
- Address space management, inter-process communication, scheduling
- Mach, QNX, L4
- Monolithic + Micro
- MacOS, Windows NT series, DragonFly BSD
Why Building Custom Kernel
Building a custom kernel is often a rite of passage for advanced FreeBSD users.
The procedure, however, is time consuming, can provide benefites to the FreeBSD
GENERIC kernel provided by the default FreeBSD system aims to
be generic, it must support a very wide range of hardware. A customized kernel
can be stirpped down to fit your needs. The advantages are listed below:
- Faster boot time
- Lower memory usage
- Additional hardware support
Finding The System Hardware
If your FreeBSD is dual boot with Windows, maybe Windows device manager can help you out. Otherwise, use the following methods can list the hardware which are currently in your box.
The Configuration File
/usr/src does not exist or it is empty, download it using Subversion:
$ sudo svn checkout https://svn0.us-west.FreeBSD.org/base/release/9.2.0 /usr/src
The sample kernel configuration file resides in
sub-directory, the file named
GENERIC being the one used to build your
initial installation kernel.
Do not make edits to
GENERIC directly. Also, we will keep the kernel
configuration file elsewhere and create a symbolic link to the file.
$ cd /usr/src/sys/amd64/conf $ sudo mkdir /root/kernels $ sudo cp GENERIC /root/kernels/MYKERNEL $ sudo ln -s /root/kernels/MYKERNEL
References for Configuring Your Own Kernel
The file NOTES contains entries and documentation for all possible devices, not just those commonly used. It is the successor of the ancient LINT file, but in contrast to LINT, it is not buildable as a kernel but a pure reference and documentation file.
To build a file which contains all available options:
$ cd /usr/src/sys/amd64/conf $ sudo make LINT
Reminder: When in doubt, just leave support in the kernel.
Building and Installing a Custom Kernel
First change directory into
/usr/src then compile the custom kernel by
specifying the configuration file:
$ cd /usr/src $ sudo make buildkernel KERNCONF=MYKERNEL
Install the compiled kernel into
/boot/kernel/kernel. The old kernel will be
$ sudo make installkernel KERNCONF=MYKERNEL
By default, all kernel modules are rebuilt when a custom kernel is compiled. To
compile the kernel faster, edit the
/etc/make.conf before starting to build
MODULES_OVERRIDE = linux acpi
Alternately, this lists the modules which are excluded from the build process:
WITHOUT_MODULES = linux acpi sound
Troubleshooting and Failover
config fails, it will show up an error message along with the line of the
error configuration. Try to fix it by comparing your configuration to
config: line 17: syntax error
Sometimes the error is not severe enough to be caught by
make will failed. Send an email to the FreeBSD general questions mailing list
with the kernel configuration file attached, if everything in the configuration
file seems right.
The Kernel Does Not Boot
Make sure to keep a copy of
GENERIC, or some kernel that is known to work.
/boot/kernel/kernel.old will be overwritten with the last
installed kernel, which may not be bootable.
$ sudo mv /boot/kernel /boot/kernel.bad $ sudo mv /boot/kernel.good /boot/kernel
The Kernel Works, But Some Utilities Do Not
After successfully compiled the custom kernel and rebooted the
machine, everything looks well except some utilities do not work. This is
because the kernel version differs from the one that the system utilities have
been built with. For example, a kernel built from -CURRENT source is installed
on a -RELEASE system, many system status command, e.g.,
So the only way to use them as usual is to “recompile and install a world” built with the same version of the source tree as the kernel.
There might still contain old object files that generated in earlier builds. To minimize the potential problem, it is good to remove them.
$ cd /usr/obj $ sudo chflags -R noschg * $ sudo rm -rf *
Compile the new compiler and other tools, then use the new compiler to compile the rest of the new world.
$ cd /usr/src $ sudo make buildworld
Use the new compiler residing in
/usr/obj to build the new kernel.
$ sudo make buildkernel KERNCONF=MYKERNEL
Install new kernel and kernel modules.
$ sudo make installkernel KERNCONF=MYKERNEL
Drop the system into single-user mode to reduce the problems cause by multiple users environment. Also, most of the services will be shut down for the same purpose.
$ sudo shutdown now
Once in single-user mode, run these commands if the system is formatted with UFS.
$ sudo mount -u / $ sudo mount -a -t ufs $ sudo swapon -a
Or instead of UFS, ZFS is used:
$ sudo zfs set readonly=off zRoot $ sudo zfs mount -a
If the keyboard binding is going to be changed, configure it now.
$ sudo kbdmap
If the CMOS clock is set to localtime, run the following command. To check
wether if the clock is set to localtime or not, there is a quick command
date to examine.
$ sudo adjkerntz -i
Rebuilding the world will not update certain directories such as
/usr. The Bourne shell script
mergemaster will determine
the difference between the files in
/usr/src/etc. You will have
four choices for each file that differs:
- Delete the new file
- Install the new file
- Merge the new file with the file that currently installed
- View the result again
$ sudo mergemaster -p
Install the new world and system binaries from
$ cd /usr/src $ sudo make installworld
Update any remaining configuration files.
$ sudo mergemaster -iF
Delete any obsolete files. Otherwise they might cause problems.
$ sudo make delete-old
A reboot is needed to load the new kernel and new world with the new configuration files.
$ sudo reboot
Remove obsolete libraries. Old libraries might have security or stability issues. Make sure that all installed ports are rebuilt.
$ sudo portmaster -af $ sudo make delete-old-libs