Managing the NetBSD kernel: loading and unloading modules with modload, modunload, and modstat, as well as assembling and building a custom kernel from the GENERIC config with build.sh.

In episode 8 we connected NetBSD to the network. Now it's time to go into the deepest machine room: the kernel. In this episode we'll dissect the NetBSD kernel from two sides — the dynamic side with kernel modules (modload, modunload, modstat), and the static side with kernel configuration (assembling a custom config and building it with build.sh).
NetBSD separates many subsystems into modules that can be loaded and unloaded while the system is running. This is the fastest way to add hardware support or features without rebuilding the kernel.
modstatNAME CLASS SOURCE REFS SIZE
acpi misc - 0 101
npf network - 0 82
wm netdev - 0 55Each line is a module with its metadata: name, class (network, misc, netdev, etc.), source, reference count, and size.
Loading a module manually:
modload /modules/mbuf_32k.omodstat | grep mbufUnloading a module:
modunload -n mbuf_32kWarning
Don't unload a module that's in use — modstat will show a REFS count greater than zero. If REFS is non-zero, a subsystem still depends on it; unload it only once nothing is using it.
Modules that must always be present at boot are registered in /etc/modules.conf — one name per line without the extension:
if_wm
npfNetBSD also loads modules automatically when new hardware is detected — so this file is only for special needs.
Modules are built from the kernel source tree. Once you have the source (in /usr/src/sys), enter the module directory and run make:
cd /usr/src/sys/modules/npf
makecc -O2 -std=gnu99 -ffreestanding ... -c npf.c
ld -T kernel.ldscript ... -o npf.kmodThe build result is placed as npf.kmod, which can be loaded with modload.
Every NetBSD kernel is built from a config file — a list of device declarations, filesystems, and options that determine the kernel's contents. The default config is in the source tree:
ls /usr/src/sys/arch/amd64/confGENERIC GENERIC.local INSTALL ...Never edit GENERIC directly. Create a new config that includes GENERIC and overrides what you want to change:
include "arch/amd64/conf/GENERIC"
# Disable devices that aren't used
no wd* at ata0 disk
no fd* at fdc0 drive ?With the include + no pattern, you get a trimmed GENERIC kernel tailored to your needs — a good foundation for embedded or specialized servers.
The kernel is built from /usr/src using build.sh. The most common flow:
cd /usr/src
./build.sh -u kernel=MYCUSTOM...
copying netbsd to .../obj/release/kernels/MYCUSTOM/netbsdSome common variants:
| Command | Function |
|---|---|
./build.sh kernel=GENERIC | Builds the default kernel |
./build.sh -u kernel=MYCUSTOM | Builds a custom kernel, -u updates obj |
./build.sh -j 4 kernel=GENERIC | Parallel build with 4 jobs |
./build.sh -m mips64el kernel=GENERIC | Cross-compiles for another arch |
After the build finishes, the kernel is in the build object directory. Install it by copying to /:
cp obj/sys/arch/amd64/compile/MYCUSTOM/netbsd /# cp obj/.../netbsd /
# (at reboot, the boot loader will offer to use the new kernel)Save the old kernel as a backup before overwriting:
cp /netbsd /netbsd.old
cp obj/sys/arch/amd64/compile/MYCUSTOM/netbsd /The NetBSD boot loader offers a kernel choice at boot. You can type the kernel name at the > prompt:
NetBSD/x86 BIOS Boot, Revision 3.5
> boot netbsd.oldThis is useful when a new kernel has problems — you can fall back to netbsd.old or netbsd (the old GENERIC kernel) without hassle.
Danger
Make sure you hold a proven working kernel before trying a new one. Keep a backup (/netbsd.old), and always test in a VM or non-production machine before deploying to production.
| Scenario | Custom Kernel Needed? |
|---|---|
| General server with GENERIC | No — GENERIC is sufficient |
| Embedded with small storage | Yes — trim unused drivers |
| Special/new hardware | Yes — add specific drivers |
| Additional security features | Yes — enable certain options |
NetBSD's GENERIC is efficient enough for most cases. A custom kernel is a precision tool — use it when there's a real need, not just for pride.
In this episode 9, you've managed the NetBSD kernel from two sides: the dynamic side with modload, modunload, and modstat, registering modules in /etc/modules.conf, and the static side by assembling a custom config and building the kernel with build.sh kernel=MYCUSTOM.
Key takeaways:
modload (load), modunload (unload), modstat (view)./etc/modules.conf./usr/src/sys/arch/<arch>/conf — don't edit GENERIC directly; create a new config with include + no../build.sh kernel=NAME, install with cp to /, and keep the old kernel as /netbsd.old.In the next episode, episode 10, we'll go up a level: source builds with build.sh — building the toolchain, kernel, and the entire userland/world from source, running parallel builds, and cross-compiling for other architectures. See you in episode 10!