Smallest possible use case for a FreeBSD kernel

I know that FreeBSD distributes a generic kernel to support as many possible devices as possible. I also know I can compile my own target kernel with only my devices. What I would like to know is how small the kernel can get in theory before you start losing any serious functionality. Could it be used as an RTOS and if so how large would such a machine have to be at a minimum?

Edit: This does appear to be covered in the handbook.

"A FreeBSD installation requires a minimum of 96 MB of RAM and 1.5 GB of free hard drive space. However, such small amounts of memory and disk space are really only suitable for custom applications like embedded appliances."

What is this estimate based on?
 
While I am unable to comment on your actual question, I'd like to jump on this one:
Could it be used as an RTOS and if so how large would such a machine have to be at a minimum?
Whether a kernel "can be used as an RTOS" has little to do with the size or resource requirements overall. While in practice an RTOS tends to come with a smaller footprint, that is usually more of a side effect than a primary goal. The abbreviation RTOS stands for Real-Time Operating System. While FreeBSD is certainly an operating system, as far as I know it is definitely not a real-time OS. Therefore, no matter how much you trim it down, it will not suddenly become an RTOS.
At this part I could mention the characteristics of an RTOS but I want to avoid starting another one of these digressing threads that ignore the OPs original question as they have recently become popular. Furthermore, there is plenty of good information out there on this topic. As often, Wikipedia is a good start: https://en.wikipedia.org/wiki/Real-time_operating_system
An OS needs to be implemented with certain, specific aspects in mind to make it become an RTOS.
That being said - I know that somewhere there are versions of the Linux kernel that are at least marketed as RT (I am being vague here on purpose). While I never specifically looked for it I don't think that FreeBSD does/offers that. If I'm wrong here, please tell me. As an embedded systems engineer I'd be highly interested in this :p

TL;DR: Building a custom FreeBSD kernel, trimming it as much as possible will not make it become an RTOS and is therefore unsuitable for applications that require an RTOS.
 
KERNCONF is relevant. You can make the kernel small. Use dmesg with grep a lot to find what your kernel loads. kldstat helps too. Use man pages to find relevant entries to those modules which are loaded. The more a KERNCONF is trimmed, the more accurate you have to be, or functionality can break so that it won't boot.

It helps to keep backups kernels, by using /boot/loader.conf through the "kernel" and "kernels" arguments. kernel loads the default. kernels has a list of working kernels, so I can pause on bootup and select a known working kernel from that list. I'll have a solid backup that doesn't get replaced every time a kernel install replaces kernel.old. This is convenient so you won't have to rely on a bootcd for every time a kernel install doesn't work.

To start with: I remove all of the sound drivers, except for the ones I use. Then, I remove the network card drivers I don't use. miibus is needed for lots of network drivers, so I'm careful not to remove it if my card depends on it. Removing usb and harddisk/RAID controllers I don't have.

I'll have two KERNCONF's one which is a trimmed down GENERIC, and another with added customizations, which will also use the trimmed KERNCONF. This way, I'll keep updates to the GENERIC organized with another file for added customizations.

Estimates for a kernel size are based on swapspace and RAM during a build. Not enough of total from these, and a build stops. Also based on the size of /boot/kernel/.

Other estimates are based on that base takes up space, and the size of a CD, then updating increases that. My root partition is about 800MB, excluding /usr and /var, bc those are on their own partitions. Use df -m and du -m.



I later realized that you said kernel, not base. Don't worry about src.conf(5) which has to do with base as I previously described about. I found it's better to have the whole base, and to trim the kernel and to use pf to block unneeded services. This is what I wrote about earlier, when thinking about FreeBSD's base, so I'll leave the information:

To try https://www.minibsd.org/ for a smaller BSD base system.

That, or spending a lot of time hands on. That would be a lot of your own exploring with src.conf and KERNCONF. There's some information in the forums from those who've played with different src.conf and KERNCONF options to rebuild base, and have rebuilt base with different options. The Kernel is relevant, because when a needed component is removed from base, that part related to the kernel must be removed too, or the computer won't boot.

In my experience, I lost a lot of functionality in ability to recompile the base, and what worked one time didn't work the same way when components of base were consolidated for the next FreeBSD release. When removing toolchains, each time a recompile was made, more needed components were excluded for 2 more times. The components were there for the compile, but no longer available for the next. On one release, I could replace the base toolchains with one from ports, but for future releases, I could no longer do this, when they kept changing the base or while they were updating Clang/LLVM functionality for each release. I learned this from trial and error.

The easiest thing to remove without breaking functionality were cleartext networking programs from source.
 
What is this estimate based on?
A rough best guess.

I build a NanoBSD image tailored for APU2. Slim kernel to essentials.
With Wifi Networking,hostap, DNSmasq and ytree and NanoBSD weighs in at 140Megabytes.
Code:
/dev/mmcsd0s1a    220M    140M     63M    69%    /
devfs             1.0K    1.0K      0B   100%    /dev
/dev/md0           19M    2.3M     15M    14%    /etc
/dev/md1           19M    808K     16M     5%    /var

Code:
root@APU2:~ # mount
/dev/mmcsd0s1a on / (ufs, local, read-only)
devfs on /dev (devfs, local)
/dev/md0 on /etc (ufs, local, soft-updates)
/dev/md1 on /var (ufs, local, soft-updates)

NanoBSD with a dual slice arrangment.
You can update a single slice and still keep old slice incase of update failure.
Code:
root@APU2:~ # gpart show
=>     63  7774145  mmcsd0  MBR  (3.7G)
       63   467649       1  freebsd  [active]  (228M)
   467712       63          - free -  (32K)
   467775   467649       2  freebsd  (228M)
   935424    40320       3  freebsd  (20M)
   975744  6798464          - free -  (3.2G)

=>     0  467649  mmcsd0s1  BSD  (228M)
       0      16            - free -  (8.0K)
      16  467633         1  !0  (228M)

=>     0  467649  mmcsd0s2  BSD  (228M)
       0      16            - free -  (8.0K)
      16  467633         1  !0  (228M)
 
KERNCONF is relevant. You can make the kernel small. Use dmesg with grep a lot to find what your kernel loads. kldstat helps too. Use man pages to find relevant entries to those modules which are loaded. The more a KERNCONF is trimmed, the more accurate you have to be, or functionality can break so that it won't boot.

It helps to keep backups kernels, by using /boot/loader.conf through the "kernel" and "kernels" arguments. kernel loads the default. kernels has a list of working kernels, so I can pause on bootup and select a known working kernel from that list. I'll have a solid backup that doesn't get replaced every time a kernel install replaces kernel.old. This is convenient so you won't have to rely on a bootcd for every time a kernel install doesn't work.

To start with: I remove all of the sound drivers, except for the ones I use. Then, I remove the network card drivers I don't use. miibus is needed for lots of network drivers, so I'm careful not to remove it if my card depends on it. Removing usb and harddisk/RAID controllers I don't have.

I'll have two KERNCONF's one which is a trimmed down GENERIC, and another with added customizations, which will also use the trimmed KERNCONF. This way, I'll keep updates to the GENERIC organized with another file for added customizations.

Estimates for a kernel size are based on swapspace and RAM during a build. Not enough of total from these, and a build stops. Also based on the size of /boot/kernel/.

Other estimates are based on that base takes up space, and the size of a CD, then updating increases that. My root partition is about 800MB, excluding /usr and /var, bc those are on their own partitions. Use df -m and du -m.



I later realized that you said kernel, not base. Don't worry about src.conf(5) which has to do with base as I previously described about. I found it's better to have the whole base, and to trim the kernel and to use pf to block unneeded services. This is what I wrote about earlier, when thinking about FreeBSD's base, so I'll leave the information:

To try https://www.minibsd.org/ for a smaller BSD base system.

That, or spending a lot of time hands on. That would be a lot of your own exploring with src.conf and KERNCONF. There's some information in the forums from those who've played with different src.conf and KERNCONF options to rebuild base, and have rebuilt base with different options. The Kernel is relevant, because when a needed component is removed from base, that part related to the kernel must be removed too, or the computer won't boot.

In my experience, I lost a lot of functionality in ability to recompile the base, and what worked one time didn't work the same way when components of base were consolidated for the next FreeBSD release. When removing toolchains, each time a recompile was made, more needed components were excluded for 2 more times. The components were there for the compile, but no longer available for the next. On one release, I could replace the base toolchains with one from ports, but for future releases, I could no longer do this, when they kept changing the base or while they were updating Clang/LLVM functionality for each release. I learned this from trial and error.

The easiest thing to remove without breaking functionality were cleartext networking programs from source.
This brings back memories - remember when the interrupts needed to be determined so it would bootstrap and kernel customizing was a right of passage.

If there’s a bare metal machine or something you can be fairly certain won’t be switching adapters or more specifically switching to a different make model - I have had several that had what was required nothing else - the additions I wanted into the kernel go till they died naturally.. great post!
 
I think the title is misleading as we all know FreeBSD is a kernel plus userland.
If you could boot off kernel alone image would only be 25 megabytes.
In reality you need userland tools.
Which leads me to this. Notice that I used gpart on NanoBSD.
In reality why would I need gpart on an embedded appliance.
So you could go lower than 140MB.
 
I was always curious to see how 'essential' tools like gpart would be handled with pkgbase.
Are the central tools all broken down into individual packages or core tools lumped together like busybox.
 
What I would like to know is how small the kernel can get in theory before you start losing any serious functionality. Could it be used as an RTOS and if so how large would such a machine have to be at a minimum?
Not clear to me if you want this for an embedded application or you want full development environment. If the former, you can use only the drivers and subsystems you need. Remove zfs if you don't need it and so on. We did use FreeBSD in this way and back in FreeBSD 2.2.2 days an unstripped kernel was about 2M for our use case. These days kernel.debug is about 3 times the size of kernel but I don't think back then the ratio was this large. I can't recall the size of the stripped kernel.
 
Back
Top