FreeBSD Host Serial Console: Boot Output, Login, and Recovery
Configure and troubleshoot a FreeBSD host serial console across boot blocks, loader, kernel, and getty, with baud-rate and recovery checks.
A serial console is an operational path to a FreeBSD host when its monitor, keyboard, or primary network is unavailable. It is useful on headless servers, remote appliances, and machines that must be observed before userland networking starts. The configuration is not one switch: boot-block output, loader output, kernel console selection, and a login prompt from getty are separate stages. A host can successfully boot while only some of those stages use the serial line.
This guide is about a physical FreeBSD host and its serial port. It does not configure a bhyve guest’s virtual UART, a USB-to-serial adapter inside another operating system, or a network console server’s access policy. Confirm that the hardware exposes a UART and that the cable or out-of-band controller is wired for the expected transmit, receive, and ground signals before changing boot files.
Confirm the port and terminal settings
FreeBSD commonly names UART devices uartN and terminal devices ttyuN or cuauN, but hardware and device hints determine which number maps to the physical connector. Inspect dmesg and /var/run/dmesg.boot for uart attachment messages, then check the uart(4) manual and device hints for the controller. Multiport cards and platform-specific UARTs may require different kernel support.
Start with the actual host and terminal settings. A common serial framing is 115200 bits per second, eight data bits, no parity, and one stop bit, but both ends must agree. A wrong baud rate often produces garbled characters rather than a clean timeout. Hardware flow control can also block input if the cable or terminal server does not provide the expected control signals.
For a local test after the operating system has booted, first determine the terminal device and whether a getty is configured. Do not assume ttyu0 is always the physical first port:
grep -E '^(uart|ttyu)' /var/run/dmesg.boot
grep -E '^[[:space:]]*ttyu' /etc/ttys
ps axww | grep '[g]etty.*ttyu'
The grep filters are only aids; read the surrounding boot messages and exact /etc/ttys rows. A UART can exist without a login prompt, and an enabled getty does not prove that the port was selected as the kernel console.
Separate early output from a login prompt
The earliest boot block, loader, and kernel messages are controlled by the boot console path. A user login prompt is provided later by init and getty through an entry in /etc/ttys. These functions can be configured independently. If boot text appears but no prompt follows, inspect the terminal’s ttys row and getty process. If a prompt appears but boot output is absent, inspect boot.config, loader console variables, and the boot-stage wiring.
On boot paths whose boot blocks support them, the FreeBSD Handbook describes /boot.config flags for console selection. The -h option selects or toggles the serial console according to the existing console choice. The -D option configures simultaneous output during the boot-block stage; the Handbook cautions that this dual-console behavior does not continue after the loader takes control. The -P option probes for a keyboard, but its detection has limitations. Do not combine flags by guesswork; follow the exact boot path and hardware documented for the installed release.
The loader can be directed to the serial console with the loader setting console=“comconsole”. The Handbook says this line should appear first in /boot/loader.conf so that loader output is redirected as early as possible. The current loader.conf manual defines console as a loader setting; kernel console selection is a separate stage and must be checked against the boot-block options, loader(8), kernel configuration, and UART hardware for the installed release. If using both video and serial consoles, loader.conf supports a multi-console value, but verify the result at the actual boot prompt rather than assuming firmware, loader, and kernel behave identically.
A representative loader configuration for serial output is:
console="comconsole"
comconsole_speed="115200"
This is a minimal loader example, not a complete recipe for every boot stage. The loader(8) manual documents boot_serial for forcing serial-console use even when an internal console is present. Only include settings supported by the target release and hardware. A platform may need a different UART hint or console name, and custom kernel builds can have their own console-speed setting. Do not add duplicate or contradictory console declarations; preserve the current file, place the intended early console setting correctly, and test with a recovery path available.
Enable a serial terminal deliberately
For interactive login, init reads /etc/ttys and starts getty on terminal entries marked enabled. The Handbook shows default ttyu0 through ttyu3 entries that are commonly disabled until an administrator connects a terminal. A simplified row’s shape is:
ttyu0 "/usr/libexec/getty std.115200" dialup off secure
This is shown as a structural example, not a complete login recommendation. Select the correct ttyu device, gettytab speed profile, terminal type, enabled flag, and final login policy for the site. The terminal type affects control sequences and line handling. The final field influences whether root login is allowed directly on that terminal; use the current Handbook and ttys(5) manual to choose deliberately.
After editing /etc/ttys, tell init to reread it using the documented signal procedure, then verify that a getty process is running on the intended device. A running getty is not a completed end-to-end test: confirm that the terminal receives a prompt, sends input, handles backspace and control characters, and renders command output correctly.
If the console should be the only login path on a headless machine, test the alternative recovery mechanisms before disabling the ordinary video console or other access paths. A serial console that is configured correctly but unreachable through the remote management controller does not help during an outage. Keep a known-good local or out-of-band recovery option while deploying changes.
Match boot and terminal speeds
The boot blocks, loader, kernel, getty, and terminal server each have speed configuration. If these disagree, one stage may show readable text and the next may show garbage or appear to stop. Set a consistent rate on both ends and verify the line’s data bits, parity, stop bits, and flow control. The Handbook documents 115200 as the usual default and describes changing boot speed through /boot.config, loader.conf, or a custom boot/kernel build, depending on the stage.
Do not treat a getty speed change as a boot-console speed change. Editing the second field of /etc/ttys affects the login terminal initialized by getty; it does not rewrite the speed used by boot blocks. Similarly, setting comconsole_speed in loader.conf cannot fix a hardware UART that the kernel does not enumerate. Change one layer at a time and observe every reboot stage.
For a baud-rate migration, schedule a maintenance window, keep the previous configuration, and prepare a terminal session at both the old and new speed if the remote equipment supports it. Change one stage, reboot under console observation, and record the last readable message. If output becomes unreadable before loader starts, the problem is earlier than getty and should not be debugged by changing /etc/ttys.
Validate a controlled reboot
Before rebooting, record the current /boot.config, /boot/loader.conf, kernel release, /etc/ttys entry, UART device, terminal server settings, and the current console route. Confirm syntax by reviewing the installed release’s loader.conf(5), boot.config(5), ttys(5), gettytab(5), and uart(4) manuals. Do not assume that a configuration copied from an older i386 installation applies to a modern UEFI or non-x86 system.
During the test, observe power-on output, boot-block messages, loader menu and prompt, kernel device probe, root mount, init startup, and the final getty login prompt. Mark the exact stage where output changes. If only the boot block is visible, investigate loader handoff and console variables. If kernel output is visible but no prompt appears, inspect getty and /etc/ttys. If nothing is visible, check cable wiring, controller port selection, baud rate, and whether the firmware itself directs output to serial.
After login, verify the terminal behaves in both directions. Send a command with predictable output, check line wrapping and control keys, and ensure logging does not depend on a local screen. If the system uses a console concentrator, test disconnect and reconnect and confirm that a detached terminal does not leave a stale login process that blocks the port.
Troubleshoot by stage
Garbled characters usually point first to a baud or framing mismatch. No response at all suggests wrong port, cable type, missing UART attachment, or incorrect transmit/receive wiring. A one-way connection often indicates crossed signal expectations, flow control, or a terminal server configuration issue. Verify the hardware path before repeatedly editing FreeBSD files.
Readable boot output followed by silence often indicates a change in the selected console as boot progresses. The boot blocks have their own flags, loader has console variables, and kernel console selection depends on the loader environment and compiled-in support. A getty prompt is another later stage. Keep notes of the last visible message so each failure is assigned to the right boundary.
If a getty does not appear, confirm the /etc/ttys line names the real terminal device, is enabled, and uses a valid gettytab entry. After changing the file, follow the Handbook procedure to signal init for a reread. Check ps output for the expected ttyu process. If it runs but the prompt is unreadable, compare the getty profile and terminal settings rather than changing boot.config.
Acceptance and rollback
The serial-console change is complete only when the entire boot sequence is visible at the intended speed and a normal login prompt appears on the selected port. Keep a record of which stage is visible on which console, the UART identity, all baud and flow-control parameters, and the exact configuration files changed. Test a reboot after a package or kernel update if console behavior depends on custom drivers.
Preserve the original files and maintain a known recovery route until the new path has survived a full reboot and operator login. If the configuration prevents boot, use the boot menu, alternate console, or rescue media to restore the saved files. Avoid making a remote-only host depend on an untested serial path. A staged, observable test turns the serial connection into dependable out-of-band access rather than a last-minute cable experiment.
Related:
- Inside the FreeBSD Boot Process: BIOS/UEFI, the Loader, and init
- Diagnosing a FreeBSD Kernel Panic from a Crash Dump
Sources: