RT-Thread RTOS
An open source embedded real-time operating system
UART early console

Early console (before full UART driver)

Early output runs before the normal **rt_serial_device** / **rt_hw_serial_register** path: a minimal putc hook is installed from FDT **/chosen** **stdout-path** and/or **earlycon=** in **bootargs**.

Sources:

  • 8250 / NS16550 / DW APB: components/drivers/serial/device/8250/early.c
  • Hypervisor console: components/drivers/serial/device/serial-early-hvc.c

Baud/format/base parsing: **serial_cfg_from_args**, **serial_base_from_args** in **serial_dm.c** — see UART device model (DM).


8250 earlycon (<tt>early.c</tt>)

Registration

**RT_FDT_EARLYCON_EXPORT** entries (examples):

Symbol earlycon name Example compatible
ns16550 uart8250 ns16550, ns16550a
dw8250 uart8250 snps,dw-apb-uart
tegra20 uart8250 nvidia,tegra20-uart
bcm2835aux uart8250 brcm,bcm2835-aux-uart

Bootargs example:

earlycon=uart8250,mmio32,0x10009000,115200n8

The FDT earlycon core passes **options** into **serial8250_early_fdt_setup**, which calls **serial8250_config** then maps MMIO with **rt_ioremap_early**.

<tt>serial8250_early_putc</tt>

Polls UART LSR (TEMT | THRE) after writing UART_TX**—safe with interrupts masked. Installed as **con->console_putc.

Lifecycle: <tt>serial8250_early_kick</tt>

why Action
FDT_EARLYCON_KICK_UPDATE **rt_ioremap** full mapping when switching from early to runtime map
FDT_EARLYCON_KICK_COMPLETED **rt_iounmap** early mapping after the platform driver owns the port

If **config.baud_rate** is zero at setup, firmware already programmed the UART; the code only clears IER.

Divisor

When **serial->freq** is set, **init_serial** programs DLL/DLM from **freq / (16 * baud_rate)**.


HVC earlycon (<tt>serial-early-hvc.c</tt>)

RT_FDT_EARLYCON_EXPORT(hvc, "hvc", "vmrt-thread,hvc-console", hvc_early_setup);
  • **hvc_early_setup** calls **rt_hv_version**; on success **console_putc** → **rt_hv_console(c)**.
  • No MMIO **reg**—hypervisor console path.

Handoff to full driver

  1. Earlycon prints via **rt_kprintf** / **console_putc**.
  2. Platform probe (e.g. **8250-ofw**) maps the same UART, **serial_dev_set_name**, **rt_hw_serial_register** → **uartN** for apps.
  3. Early mapping is released on **FDT_EARLYCON_KICK_COMPLETED** when the serial core finishes transition.

Do not leave early putc and the full driver writing the same UART without the kick handshake.


Pitfalls

  • **reg-shift**: early defaults may differ from DT **reg-shift** in probe—keep them consistent for your IP.
  • Options buffer: **serial_cfg_from_args** may modify the string ( **OFW** suffix).
  • RX: early path is TX-only; input needs the full UART driver or another console backend.

See also