Building kernel without devices

To build a kernel without some devices I do something like,
in order to remove the lines from GENERIC KERNCONF kernel configuation file.
Maybe there is a nicer solution ?

Code:
#!/usr/local/bin/zsh -x
#Call with KERNNAME parameter
WORK=$1
gawk -i inplace '{gsub(/GENERIC/,"'"$1"'"); print}' $WORK
gawk -i inplace '! ( $1 == "makeoptions" && $2 == "DEBUG=-g"   )' $WORK
gawk -i inplace '! ( $1 == "makeoptions" && $2 == "WITH_CTF=1" )' $WORK

gawk -i inplace '! ( $1 == "options"     && $2 == "NFSCL" )' $WORK
gawk -i inplace '! ( $1 == "options"     && $2 == "NFSD" )' $WORK
gawk -i inplace '! ( $1 == "options"     && $2 == "NFSLOCKD" )' $WORK
gawk -i inplace '! ( $1 == "options"     && $2 == "NFS_ROOT" )' $WORK

gawk -i inplace '! ( $1 == "device"      && $2 == "fdc" )' $WORK

gawk -i inplace '! ( $1 == "device"      && $2 == "ahc" )' $WORK
gawk -i inplace '! ( $1 == "options"     && $2 == "AHC_REG_PRETTY_PRINT" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "ahd" )' $WORK
gawk -i inplace '! ( $1 == "options"     && $2 == "AHD_REG_PRETTY_PRINT" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "esp" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "hptiop" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "isp" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "ispfw" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "mpt" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "mps" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "mpr" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "sym" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "trm" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "adv" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "adw" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "aic" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "bt" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "isci" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "ocs_fc" )' $WORK

gawk -i inplace '! ( $1 == "device"      && $2 == "amr" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "arcmsr" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "ciss" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "dpt" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "hptmv" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "hptnr" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "hptrr" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "hpt27xx" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "iir" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "ips" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "mly" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "twa" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "smartpqi" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "tws" )' $WORK

gawk -i inplace '! ( $1 == "device"      && $2 == "aac" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "aacp" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "aacraid" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "ida" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "mfi" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "mlx" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "mrsas" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "pmspcv" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "twe" )' $WORK

gawk -i inplace '! ( $1 == "device"      && $2 == "ppc" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "ppbus" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "lpt" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "ppi" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "puc" )' $WORK

gawk -i inplace '! ( $1 == "device"      && $2 == "bxe" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "de" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "em" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "igb" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "ix" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "ixv" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "ixl" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "ixlv" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "le" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "ti" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "txp" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "vx" )' $WORK

gawk -i inplace '! ( $1 == "device"      && $2 == "ae" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "age" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "alc" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "ale" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "bce" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "bfe" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "bge" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "cas" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "dc" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "et" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "fxp" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "gem" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "hme" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "jme" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "lge" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "msk" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "nfe" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "nge" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "pcn" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "rl" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "sf" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "sge" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "sis" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "sk" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "ste" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "stge" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "tl" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "tx" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "vge" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "vr" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "wb" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "xl" )' $WORK

gawk -i inplace '! ( $1 == "device"      && $2 == "snd_cmi" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "snd_csa" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "snd_emu10kx" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "snd_es137x" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "snd_via8233" )' $WORK

gawk -i inplace '! ( $1 == "options"     && $2 == "XENHVM" )' $WORK

gawk -i inplace '! ( $1 == "options"     && $2 == "KDB" )' $WORK
gawk -i inplace '! ( $1 == "options"     && $2 == "KDB_TRACE" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "pvscsi" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "nvme" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "nvd" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "vmd" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "vmd_bus" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "iflib" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "iavf" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "ice" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "vmx" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "axp" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "xenpci" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "mlx5" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "mlxfw" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "mlx5en" )' $WORK
gawk -i inplace '! ( $1 == "device"      && $2 == "hyperv" )' $WORK
 
A few remarks:
  • Don't write scripts using a shell other than /bin/sh and try to avoid "third-party" tools like gawk as well, this will make your scripts much more robust (and portable).
  • For the specific usecase, Crivens is right: the recommended way to have a custom kernel configuration is to include an existing one (most likely GENERIC) and only add your modifications with [no]device|options.
  • Removing things that are enabled in GENERIC is unlikely to improve security (as many seem to assume) *), and the savings in terms of disk space and RAM usage are relatively small, so it only makes sense for "special" target environments – otherwise it's not worth the effort.

*) what does improve security is preventing random kernel modules from being able to load at runtime; for that, see the sysctl kern.securelevel described in rc.conf(5) and security(7).
 
and the savings in terms of disk space and RAM usage are relatively small,
That's a matter of perspective.
GENERIC kernel from FreeBSD 13 memstick image:
Code:
% du -hs /media/SanDisk_Cruzer_Blade_4C531001480801101250_s2_s2a/boot/kernel/kernel
 28M    /media/SanDisk_Cruzer_Blade_4C531001480801101250_s2_s2a/boot/kernel/kernel
Custom built kernel from my desktop machine, containing only necessary bits and pieces:
Code:
% du -hs /boot/kernel/kernel
 10M    /boot/kernel/kernel
That's actually less than half the size, YMMV.
 
Yes, and on a normal-sized server or desktop machine, 18MiB is "nothing". To put it into perspective, an ESP wastes hundreds of MiB, just to host a bootloader.

As I said, for "special" targets (anything embedded and similar), building a "minimal" kernel might make sense.
 
A waste of resources cannot be justified, no matter how you put it, it stays what it is: a waste. If having around a gazillion of scsi, hardware raid, network and other drivers that your machine is never gonna use gives you that warm cosy feeling, fine. I still don't like seeing resources wasted that could be put to good use elsewhere.
 
The key is to believe what you're doing makes any sense (so far for "warm cozy feelings"). Better don't worry about UEFI then :cool: (oh, the horrors)
 
A very very basic question I have , is /etc/src.conf read when you build the kernel or world or both ?

I rebuilded world and was able to remove many things I don't use,

Code:
WITHOUT_BIND=yes
WITHOUT_BLUETOOTH=yes
WITHOUT_CROSS_COMPILER=yes
WITHOUT_DEBUG_FILES=yes
WITHOUT_FLOPPY=yes
WITHOUT_HYPERV=YES
WITHOUT_INETD=yes
WITHOUT_IPX=yes
WITHOUT_KDUMP=yes
WITHOUT_KVM=yes
WITHOUT_KVM_SUPPORT=yes
WITHOUT_KERNEL_SYMBOLS=yes
WITHOUT_LLVM_TARGET_ALL=yes
WITHOUT_LLVM_TARGET_AARCH64=yes
WITHOUT_LLVM_TARGET_BPF=yes
WITHOUT_LLVM_TARGET_ARM=yes
WITHOUT_LLVM_TARGET_MIPS=yes
WITHOUT_LLVM_TARGET_POWERPC=yes
WITHOUT_LLVM_TARGET_RISCV=yes
WITHOUT_LLVM_TARGET_SPARC=yes
WITHOUT_LOCATE=yes
WITHOUT_LPR=yes
WITHOUT_MAIL=yes
WITHOUT_MAILWRAPPER=yes
WITHOUT_NDIS=yes
WITHOUT_NVME=yes
WITHOUT_OPENSSH=yes
WITHOUT_RPCBIND_WARMSTART_SUPPORT=yes
WITHOUT_SENDMAIL=yes
WITHOUT_TCP_WRAPPERS=yes
WITHOUT_WIRELESS_SUPPORT=yes
WITHOUT_WIRELESS=yes
WITHOUT_WPA_SUPPLICANT_EAPOL=yes

I think without IPX make sense in our modern world.
 
A very very basic question I have , is /etc/src.conf read when you build the kernel or world or both ?
/etc/src.conf is included for anything built from /usr/src. So, yes, it's included for building the kernel as well, but I don't know right now if there are any knobs influencing the kernel – I suspect the answer is no.

Anyways, leaving things you don't use out of building "world" will probably save a lot more space than any customization of kernel config can ever do. You could even build a "world" that doesn't include a compiler (which might make sense if your target system doesn't compile anything).
 
A very very basic question I have , is /etc/src.conf read when you build the kernel or world or both ?
Answered in the first few lines of src.conf(5):
Code:
DESCRIPTION
     The src.conf file contains variables that control what components will be
     generated during the build process of the FreeBSD source tree; see
     build(7).
 
Back
Top