Skip to content
FreeBSDDeep Dive Published Updated 7 min readViews unavailable

FreeBSD kenv Operations: Inspect Kernel Environment and Probe Hints

Distinguish FreeBSD's live kernel environment from loader settings, inspect device hints, test changes safely, and persist only supported tunables.

kenv(1) reads and modifies the environment associated with the running FreeBSD kernel. It is not the same as a user’s shell environment, and it is not a general-purpose replacement for sysctl(8) or persistent configuration. That boundary matters during boot and device diagnosis: the kernel environment can show values passed from the loader, while a sysctl usually represents current kernel state exposed through a separate interface.

Use kenv to answer a specific question: which environment variables or device probe hints are visible to this kernel now, and what was inherited from an earlier boot stage? A value present in kenv does not establish that a driver consumed it, that the device attached successfully, or that changing the value at runtime will reconfigure existing hardware.

Capture a bounded inventory

Start with a small query rather than dumping every value into a ticket. Kernel environments can include hardware details, boot paths, and site-specific information:

kenv -v currdev
kenv -h -N | sort | head -80
kenv -h | grep -E '^(hint\.|.*uart)'

The -h option limits output to kernel probe hints. -N prints names only in current versions; check the installed manual before using it on older systems. The example is diagnostic, not a complete device inventory. It also intentionally limits output so a large or sensitive environment is not indiscriminately copied into logs.

For a particular hint, query it directly and keep the value, device name, kernel version, and boot timestamp together:

kenv hint.uart.0.at
kenv -v hint.uart.0.irq
kenv -v hint.uart.0.port

The correct hint names and values depend on the bus, driver, kernel configuration, and hardware. A hint that worked on one machine may point a driver at the wrong I/O port or interrupt on another. Do not copy a kernel hint from an unrelated model without matching it to the device’s documented resource assignment.

Understand the environment layers

The loader can pass an environment to the kernel during startup. Some kernels also support querying preserved static environments with kenv -l or kenv -s; these modes depend on kernel configuration and the default kernel does not necessarily preserve those early environments. Treat failure or empty output from these options as a kernel-configuration limitation, not proof that the loader never supplied a value.

The default kenv view is the live kernel environment. With a named variable, it prints that value; with name=value, it attempts to set it; with -u name, it attempts to remove it. Permissions and variable-specific behavior apply. A successful assignment only proves the environment value changed; it does not mean that an already attached device was detached and reprobed or that a subsystem re-read the setting.

Use sysctl for tunables that the kernel exposes through the sysctl tree, and use the owning driver’s manual for whether a particular setting is runtime-adjustable. Use a loader setting only when the variable is documented as a loader tunable and the value must exist before the relevant kernel initialization stage. These mechanisms overlap in some configuration workflows but have distinct interfaces, timing, and persistence rules.

Inspect related state together:

kenv -h -N | grep '^hint\.uart'
sysctl -a | grep '^hw\.uart'
dmesg | grep -iE 'uart|serial|probe|attach'
devinfo -rv

The exact sysctl subtree is driver-specific. Do not infer that every device exposes a corresponding hw.* variable. dmesg shows the kernel’s reported attach path, devinfo shows the current device hierarchy, and kenv shows variables. Correlating all three narrows the question without turning a hint change into blind experimentation.

Treat runtime changes as experiments, not repairs

If a documented variable is safe to change at runtime, capture the before state, make one controlled change, and read it back:

kenv verbose_loading
kenv verbose_loading="YES"
kenv verbose_loading

This example uses a diagnostic variable whose behavior is tied to kernel loader output; it illustrates the interface, not a general recommendation to set boot variables after startup. Some variables can be immutable, ignored after boot, or consumed only once. Never guess a kernel tunable name or value in production. Consult the variable’s manual, tunable description, driver documentation, or source before writing it.

The kenv -u form removes a runtime environment key where permitted. It does not undo side effects already caused by code that read the value earlier. It also does not erase the persistent source from /boot/loader.conf, a kernel configuration, or a configuration-management template. If a value returns after reboot, locate the source of persistence instead of repeatedly deleting the live copy.

For hardware changes, avoid detaching a production device simply to force a new probe. A driver may own storage, network connectivity, console output, or children in the device tree. Use devinfo, driver documentation, and a maintenance plan to determine whether the device can be safely reprobed and whether you have alternate access. On a remote host, test from an out-of-band console and prepare rollback before touching the interface carrying the session.

Persist only documented settings

When a tunable must persist, the location is determined by its documented initialization stage. /boot/loader.conf is read by the loader; /etc/sysctl.conf is read by the sysctl startup mechanism; /etc/rc.conf configures rc-managed services and variables. Do not put a kernel environment value in a convenient file merely because it appears to work on one boot.

Before adding a line, record the exact variable, accepted syntax, whether the setting is a loader tunable or runtime sysctl, supported kernel versions, and any device-specific constraints. Avoid putting secrets in loader environment files: early boot settings can be exposed to operators or diagnostic output and are not a secret-management facility.

If the existing host has a known-good loader configuration, preserve its permissions and make a minimal diff. kenv cannot validate the syntax of the loader file before reboot. Check the file, compare against the installed manual, and ensure console access before applying a setting that could prevent boot or disable the only network interface.

After reboot, query the value again with kenv and inspect the actual outcome in kernel messages and device state. A persistent string is not proof of a successful driver attach. If the device remains absent, compare the device tree, driver availability, bus resource assignment, firmware state, and kernel configuration. Remove or revert the experimental setting through the source file if it caused an unexpected boot or attach behavior.

Preserve useful but minimal evidence

For an incident report, capture the FreeBSD release and architecture, kernel version, selected kenv keys, relevant sysctl values, devinfo path, and matching dmesg lines. Redact site-specific identifiers when sharing outside the operations team. Do not treat the output of kenv as a complete inventory of every boot argument or a canonical system configuration export.

An acceptance check is not merely “the string is present.” It should establish that the intended value is visible in the correct layer, the driver or subsystem documents that value, the expected device attached with the intended resources, and the service using that device passed a real test. If those conditions are not met, revert the change and investigate the actual layer that failed.

For a reproducible incident, keep a before-and-after pair rather than a single copied kenv dump. Include only the keys that support the hypothesis, and note whether each value came from the live environment, loader-preserved state, a kernel configuration, or another persistent file. This makes it possible to distinguish a newly supplied loader hint from a runtime modification and reduces the chance that a reviewer mistakes a transient experiment for intended policy. If a key could reveal hardware topology or local boot configuration, share the minimal excerpt with the team that needs it instead of attaching the entire environment to a public bug report.

Related:

Sources:

Comments