Compile and Build a small Custom Kernel tailored to a specific AMD64 PC System

After seeing this thread today Thread 14-2-release-p.97162, I decided to do a small guide about how to compile, and build a custom kernel for FreeBSD-X.Y-RELEASE.
Since FreeBSD already works very well, I decided to reduce the amount of devices, and options available in the GENERIC kernel.
This has the following benefits:
-> faster boot times
-> reduced RAM usage
Another benefits, which possibly could also be achieved by compiling and building a GENERIC kernel from source, would be the security patches.

Make sure to have devel/git installed or build, before proceeding.
Now, let us get started.

1.1) If you have a /usr/src directory already available, and populated, delete its contents by issuing as root:
Code:
rm -rf /usr/src/*

Make sure to delete the /sys symlink as well by issuing as root:
Code:
rm -rf /sys

1.2) If you do not have a /usr/src directory create it by issuing as root:
Code:
mkdir /usr/src

2) Populate the /usr/src directory by issuing as root:
Code:
git clone -o freebsd https://git.FreeBSD.org/src.git /usr/src

Be a little patient, as it could take a little while until git finishes.
The speed of completion may vary due to I/O speeds of the drive, and internet speed.

Create a new sys symlink in / by issuing as root:
Code:
doas -- ln -s usr/src/sys /sys

3) Move to the /usr/src directory by issuing the following command as root:
Code:
cd /usr/src

In that directory issue the following command as root:
Code:
git checkout releng/14.2
Now you should be on the release branch.

4) Create a file called MYKERNEL, CUSTOMKERNEL, SMALLKERNEL, whatever you thing would describe your kernel name config best.
Create the file in the /usr/src/sys/amd64/conf directory by issuing as root:
Code:
touch /usr/src/sys/amd64/conf/your-kernel-config-name

5) Now, I suggest that you open the file as root, and put the following in, first:
Code:
your-editor-of-choice /usr/src/sys/amd64/conf/your-kernel-config-name
--- Start of Content ---
#
# your-kernel-config-name -- Custom kernel configuration file for FreeBSD/amd64
#

include GENERIC
ident your-kernel-config-name
--- End of Content ---

This will include the content of the GENERIC kernel, but use your kernel config name while building.

6) After the kernel config file is now created, append the content of the GENERIC file to your kernel config file issuing as root:
Code:
cat /usr/src/sys/amd64/conf/GENERIC >> /usr/src/sys/amd64/conf/your-kernel-config
Decide for yourself which comments you want to delete, or not.

7.1) Issue as root in one terminal emulator process:
Code:
dmesg | less

7.2) Issue as root in another terminal emulator process:
Code:
your-editor-of-choice /usr/src/sys/amd64/your-kernel-config

7.3) Compare the devices, and drivers loaded up, and the devices, and drivers in your-kernel-config file.
Delete every device which matches the device in dmesgs output, and add a no to the device which does not match the device or driver in the dmesg log.
Example: nodevice device-name.
Devices which you have deleted in your-kernel-config file will be loaded anyway, because you have included GENERIC in your-kernel-config-file.
nodevice device-name parameter will overwrite the ones in GENERIC.

8) Assuming you still are in the /usr/src directory, issue as root:
Code:
make buildkernel KERNCONF=your-kernel-config-file

followed by a
Code:
make installkernel KERNCONF=your-kernel-config-file

Be patient, as compiling, and building the kernel can take some time.
On some systems the process finishes faster, on some not.
In my case it took around 12 minutes to build, and install the kernel.
After the kernel is installed, reboot.
If something goes wrong during the boot process, it is ok.
In that case restart the system, press space in the boot menu followed by a 6, and then by a 1.
This ensures that your working kernel will be loaded.
Edit your-config-file again, and try again the build, and install procedure as long as the kernel works as intended.
It took me around 40 minutes to get everything right so, you need to be patient.

9) If everything is working, make somewhere outside the /usr/src/ a backup of your-kernel-config-file by issuing as root
Code:
mv /usr/src/sys/amd64/conf/your-kernel-config-file ~/your-path-of-choice

Now issue
Code:
freebsd -kru

You should get this output:
Code:
14.2-RELEASE-p2 (kernel installed)
14.2-RELEASE-p2 (kernel currently running)
14.2-RELEASE-p2 (userland)

Hopefully this guide can help people upgrade/update their system to the most current RELEASE branch/patch level version.
 
Hello!
Just one question about steps 5 and 6:

after those steps your-kernel-config-name will be like

include GENERIC
ident your-kernel-config-name
GENERIC FILE


is line "include GENERIC" is really needed if full GENERIC file is included in step 6?
 
Hello!
Just one question about steps 5 and 6:

after those steps your-kernel-config-name will be like

include GENERIC
ident your-kernel-config-name
GENERIC FILE


is line "include GENERIC" is really needed if full GENERIC file is included in step 6?
Yes, include GENERIC is neccessary, because it will have all options, and devices enabled by default.
The purpose of your own file is to override enabled options, devices with nooption, and nodevice.
Your kernel config file should only have options, devices which you do not want to have enabled through GENERIC by default.
 
Yes, include GENERIC is neccessary, because it will have all options, and devices enabled by default.
The purpose of your own file is to override enabled options, devices with nooption, and nodevice.
dark.initr0 is right. You're appending the entire GENERIC config to your-kernel-config-name. Which defeats the purpose of doing the include in the first place.

Decide for yourself which comments you want to delete, or not.
Removing them will still have them included because you include GENERIC on line 1.
 
It works like this:
You include GENERIC, now you have the default config shipped with the kernel.
Give it a new name using "indent"
Now you remove the drivers you don't want statically linked in using "nodevice", or by "nooption".

You will need to remove "sound" when you want to play with the ports OSS version, for example.
 
But if I don't include GENERIC the kernel won't compile, right ?
No, none of my custom configs include GENERIC. I copy GENERIC then remove everything I don't need (and change the ident).

The handbook at least statet that I should include Generic, or is that method outdated by now ?
Maybe a language barrier, but I think you're misunderstanding the explanation in the handbook.
 
I see ...
Well, I really misunderstood something ...
Thank you for clarifying things !

An include directive is available for use in configuration files.This allows another configuration file to be included in the current one, making it easy to maintain small changes relative to an existing file.If only a small number of additional options or drivers are required, this allows a delta to be maintained with respect to GENERIC, as seen in this example:
I misunderstood this part.
I thought including GENERIC, and then overriding part of it in my ident file would be the solution...
Oh, well, I am going to recompile/build the kernel now.
 
Back
Top