Default UART Configuration and Override Guide for EDF BSPs
This page documents the default UART (serial console) selection used by each AMD BSP shipped with the EDF Yocto layers, and how to override it for a custom board. For the per-board USB-UART bridge and connector designators, see the per-board UART subsections in Board Specific Specifications and Information.
Overview
For adaptive-SoC families (Zynq-7000, ZynqMP, Versal, Versal Gen 2), each
AMD BSP selects a default PS UART instance that is
used by all boot stages (BootROM, PLM / FSBL, TF-A
(also known as ATF), U-Boot) and by the Linux console. MicroBlaze BSPs
instead default to a PL UART (typically AXI UART Lite or the
MDM UART), because they have no PS UART available. The PMC /
PSM trace UARTs are separate, dedicated firmware-trace ports and are
not affected by the variables on this page; changing stdout-path does
not move the PLM trace output. The selected console instance is
driven from the System Device Tree (SDT) chosen { stdout-path }
property and is reflected in three Yocto variables:
SERIAL_CONSOLES– Linuxgettyconsole (ttyPS<n>/ttyAMA<n>).TFA_CONSOLE– TF-A (Arm Trusted Firmware, also referred to as ATF) console driver (cadencefor ZynqMP,pl011for Versal / Versal Gen 2). The variableATF_CONSOLEis the legacy alias;arm-trusted-firmware.incsetsTFA_CONSOLE ?= "${ATF_CONSOLE}", and the per-machine BSPs inmeta-amd-adaptive-socsandmeta-kriaall useTFA_CONSOLE.KERNEL_BOOTARGS–earlycon/console=kernel command line.
All AMD evaluation boards use the same line settings: 115200 8N1 (115200 baud, 8 data bits, no parity, 1 stop bit, no flow control).
Default UART per SoC Family
SoC family |
SOC_FAMILY |
Default PS UART IP |
Linux console device |
Default TFA_CONSOLE |
Default KERNEL_BOOTARGS console |
|---|---|---|---|---|---|
Zynq-7000 |
zynq |
Cadence UART (xuartps) – UART1 |
ttyPS0 |
n/a (no TF-A) |
|
Zynq UltraScale+ MPSoC / RFSoC |
zynqmp |
Cadence UART (xuartps); UART instance is board-dependent.
The authoritative value lives in the per-machine
|
ttyPS0 |
cadence (board dependent; Kria K26 BSPs use cadence1) |
earlycon 1 |
Versal (Gen 1) |
versal |
Arm PL011 – UART0 or UART1 (board dependent) |
ttyAMA0 |
pl011 |
earlycon 1 |
Versal Gen 2 |
versal-net |
Arm PL011 – UART0 or UART1 (board dependent) |
ttyAMA0 or ttyAMA1 (board dependent) |
pl011 or pl011_1 (board dependent) |
earlycon 1 |
MicroBlaze (PMC, PSM, RPU bare-metal) |
microblaze |
AXI UART Lite (xps-uartlite) or MDM UART |
ttyUL0 |
n/a |
|
(1) For ZynqMP and Versal the Linux console is not hard-coded by
SERIAL_CONSOLES. The kernel uses earlycon and resolves the final
/dev/ttyPSx or /dev/ttyAMAx from the chosen { stdout-path }
property of the active system device tree. To change the console,
modify the SDT (or the device-tree overlay) rather than only
setting SERIAL_CONSOLES.
Default UART per Evaluation Board (BSP)
The sections that follow list the default UART selection for
each AMD evaluation-board BSP packaged with EDF, organised by
device family. Every value comes directly from the per-machine
conf/machine/<machine>.conf file shipped in
meta-amd-adaptive-socs, meta-kria, or meta-xilinx-core.
Each subsection’s preamble names the family-wide defaults
(TFA_CONSOLE, Linux device) so the per-board table only carries
what differs board to board. For the per-board USB-UART bridge part
numbers, connector designators, and physical pinout, see the per-board
UART subsections in
Board Specific Specifications and Information.
Zynq-7000
Zynq-7000 boots BootROM -> FSBL -> U-Boot -> Linux without a
TF-A stage, so neither ZC702 nor ZC706 sets TFA_CONSOLE.
Board |
Machine |
Default PS UART |
Linux device |
TFA_CONSOLE |
|---|---|---|---|---|
ZC702 |
zynq-zc702-sdt-full |
xuartps UART1 |
ttyPS0 |
n/a |
ZC706 |
zynq-zc706-sdt-full |
xuartps UART1 |
ttyPS0 |
n/a |
Zynq UltraScale+ MPSoC / RFSoC
The non-Kria ZynqMP and RFSoC BSPs ship in meta-amd-adaptive-socs.
Board |
Machine |
Default PS UART |
Linux device |
TFA_CONSOLE |
|---|---|---|---|---|
ZCU102 |
zynqmp-zcu102-sdt-full |
xuartps UART0 |
ttyPS0 |
cadence |
ZCU104 |
zynqmp-zcu104-sdt-full |
xuartps UART0 |
ttyPS0 |
cadence |
ZCU106 |
zynqmp-zcu106-sdt-full |
xuartps UART0 |
ttyPS0 |
cadence |
ZCU111 |
zynqmp-zcu111-sdt-full |
xuartps UART0 |
ttyPS0 |
cadence |
ZCU208 |
zynqmp-zcu208-sdt-full |
xuartps UART0 |
ttyPS0 |
cadence |
Kria SoM (K26)
The Kria K26 SOMs (KV260, KR260) ship in meta-kria. They route
TF-A to the second Cadence instance (cadence1), but the
kernel renumbers xuartps UART1 to ttyPS0 through the
chosen { stdout-path } property in the SDT, so the
user-visible Linux device is still ttyPS0.
Board |
Machine |
Default PS UART |
Linux device |
TFA_CONSOLE |
|---|---|---|---|---|
KV260 |
k26-smk-kv-sdt |
xuartps UART1 |
ttyPS0 |
cadence1 |
KR260 |
k26-smk-kr-sdt |
xuartps UART1 |
ttyPS0 |
cadence1 |
Versal (Gen 1)
All Versal Gen 1 BSPs ship in meta-amd-adaptive-socs and use the
same default PS UART.
Board |
Machine |
Default PS UART |
Linux device |
TFA_CONSOLE |
|---|---|---|---|---|
VCK190 |
versal-vck190-sdt-seg |
PL011 UART0 |
ttyAMA0 |
pl011 |
VMK180 |
versal-vmk180-sdt-seg |
PL011 UART0 |
ttyAMA0 |
pl011 |
VEK280 |
versal-vek280-sdt-seg |
PL011 UART0 |
ttyAMA0 |
pl011 |
VPK120 |
versal-vpk120-sdt-seg |
PL011 UART0 |
ttyAMA0 |
pl011 |
VPK180 |
versal-vpk180-sdt-seg |
PL011 UART0 |
ttyAMA0 |
pl011 |
VPK360 |
versal-vpk360-sdt-seg |
PL011 UART0 |
ttyAMA0 |
pl011 |
VRK160 |
versal-vrk160-sdt-seg |
PL011 UART0 |
ttyAMA0 |
pl011 |
VRK165 |
versal-vrk165-sdt-seg |
PL011 UART0 |
ttyAMA0 |
pl011 |
Versal Gen 2
The Versal Gen 2 BSPs ship in meta-amd-adaptive-socs under the
versal-2ve-2vm- machine prefix. The VEK385 family defaults to
UART1, while VMK365 defaults to UART0.
Board |
Machine |
Default PS UART |
Linux device |
TFA_CONSOLE |
|---|---|---|---|---|
VEK385 revA |
versal-2ve-2vm-vek385-sdt-seg |
PL011 UART1 |
ttyAMA1 |
pl011_1 |
VEK385 revB |
versal-2ve-2vm-vek385-revb-sdt-seg |
PL011 UART1 |
ttyAMA1 |
pl011_1 |
VEK386 |
versal-2ve-2vm-vek386-sdt-seg |
PL011 UART1 |
ttyAMA1 |
pl011_1 |
VMK365 |
versal-2ve-2vm-vmk365-sdt-seg |
PL011 UART0 |
ttyAMA0 |
pl011 |
MicroBlaze
The generic MicroBlaze machine ships in meta-xilinx-core and runs
entirely from the PL, with no TF-A stage.
Board |
Machine |
Default PS UART |
Linux device |
TFA_CONSOLE |
|---|---|---|---|---|
generic |
microblaze-generic |
AXI UART Lite (xps-uartlite) |
ttyUL0 |
n/a |
Where EDF Sources the Default in the BSP
For an EDF BSP, the default UART flows from the hardware design (XSA / SDT) into the Yocto build through the following chain:
Vivado / system design sets the
stdout-pathin the generated System Device Tree.gen-machineconf (
gen-machine-conflib) reads the SDT and writesSERIAL_CONSOLESandYAML_SERIAL_CONSOLE_BAUDRATEinto the generatedconf/machine/<machine>.conffile (seemeta-xilinx-core/gen-machine-conf/lib/yocto_machine.py).meta-xilinx-coresets the SoC-family defaults througharm-trusted-firmware.incinmeta-xilinx-core/recipes-bsp/arm-trusted-firmware/:ATF_CONSOLE_DEFAULT:zynqmp = "cadence" ATF_CONSOLE_DEFAULT:versal = "pl011" ATF_CONSOLE_DEFAULT:versal-net = "pl011" ATF_CONSOLE ?= "${ATF_CONSOLE_DEFAULT}" TFA_CONSOLE ?= "${ATF_CONSOLE}"
TFA_CONSOLEdrives the TF-A build directly;ATF_CONSOLEsurvives only as the legacy spelling.meta-xilinx-coresets the Linux kernel boot arguments throughmeta-xilinx-core/recipes-bsp/u-boot/u-boot-xlnx-uenv.bb:KERNEL_BOOTARGS:zynq = "earlyprintk console=ttyPS0,115200 root=/dev/mmcblk0p2 rw rootwait" KERNEL_BOOTARGS:zynqmp = "earlycon root=/dev/mmcblk${devnum}p2 rw rootwait"
The
device-tree.bbappendshipped undermeta-xilinx/meta-xilinx-standalone-sdt/recipes-bsp/device-tree/wires per-machine*-system-conf.dtsifiles into the device-tree build.meta-amd-adaptive-socs-bsp/recipes-bsp/device-tree/files/ships those*-system-conf.dtsifiles for each EDF-supported board (for exampleversal-2ve-2vm-vek385-sdt-seg-system-conf.dtsi,zynq-cortexa9-system-conf.dtsi); this is where a board overrides thestdout-pathif the hardware design did not.
Overriding the Default UART
There are three supported override points, in increasing order of specificity:
Per-build override – in
conf/local.conf. Pick the line that matches your SoC family; do not set both in the same configuration:# ZynqMP only (valid: 'cadence', 'cadence0', 'cadence1', 'dcc'; # bare 'cadence' is the default and resolves to 'cadence0' in # arm-trusted-firmware.inc). TFA_CONSOLE = "cadence1"
# Versal / Versal Gen 2 only (valid: 'pl011', 'pl011_0', 'pl011_1', # 'dcc'; bare 'pl011' is the default and resolves to 'pl011_0'). TFA_CONSOLE = "pl011_1"
# Linux getty + login (sysvinit) SERIAL_CONSOLES = "115200;ttyPS1" # Override the Linux command line KERNEL_BOOTARGS = "earlycon console=ttyPS1,115200 root=/dev/mmcblk1p2 rw rootwait"
arm-trusted-firmware.incaccepts the legacy spellingATF_CONSOLE, but every per-machine BSP inmeta-amd-adaptive-socsandmeta-kriausesTFA_CONSOLE. Match that spelling to stay forward-compatible.Per-machine override – in
conf/machine/<machine>.conf(the file generated bygen-machineconf). Set the same variables there to make the change a property of the machine recipe.Per-hardware-design override – update
chosen { stdout-path = ... };in the System Device Tree (or in a*.dtsioverlay added throughEXTRA_DT_INCLUDE_FILES). The change is to the SDT, not the silicon, but it reaches the PLM, FSBL, and U-Boot in addition to Linux – making it the only override that affects every boot stage.
Step-by-Step: Switching the Serial Port on a Hardware Board
Use this procedure to permanently move the console of an EDF BSP
from the default UART instance (for example UART0) to a
different one (for example UART1) on a real evaluation board.
Identify the target UART in the System Device Tree. Open the SDT produced by
sdtgen(or thesystem-top.dtsshipped with the BSP) and locate the secondserial@...node. Note itsregbase address - for example ZynqMPUART1is at0xFF010000and VersalPL011_1is at0xFF010000. Make sure the node hasstatus = "okay";.Point ``stdout-path`` at the new UART. Edit the
chosennode in the SDT (or in an overlay file referenced throughEXTRA_DT_INCLUDE_FILES):/ { chosen { stdout-path = "serial1:115200n8"; }; };
This single change reaches BootROM, PLM / FSBL, U-Boot and the Linux
earlycondriver, because they all resolve the console fromstdout-path.Re-align the firmware console. In
conf/local.conf(or inconf/machine/<machine>.conf):# ZynqMP - second Cadence UART TFA_CONSOLE = "cadence1" # Versal / Versal Gen 2 - second PL011 TFA_CONSOLE = "pl011_1"
Re-align the Linux user-space console. Still in
conf/local.conf:SERIAL_CONSOLES = "115200;ttyPS1" # ZynqMP SERIAL_CONSOLES = "115200;ttyAMA1" # Versal / Versal Gen 2 KERNEL_BOOTARGS = "earlycon console=ttyPS1,115200 root=/dev/mmcblk0p2 rw rootwait"
SERIAL_CONSOLEScontrols thegetty/ login prompt, whileKERNEL_BOOTARGScontrols theconsole=argument passed to the kernel by U-Boot.Rebuild the affected components. Force the device tree, firmware and boot-image recipes to pick up the new console:
$ bitbake -c cleansstate device-tree arm-trusted-firmware u-boot-xlnx $ bitbake virtual/bootloader virtual/kernel $ bitbake <your-image> # for example core-image-minimal
Re-flash and verify. Program the new
BOOT.BIN(or boot.scr + image.ub) to the boot media, move the host serial cable to the USB-UART channel that maps to the new instance (see the “Default UART per Evaluation Board” table for the connector / channel mapping on each board), and confirm at 115200 8N1 that BootROM, PLM/FSBL, TF-A, U-Boot and Linux all print on the new port.
Note
On boards whose USB serial bridge exposes a quad of channels (CP2108 /
FT4232HL), the secondary PS UART typically maps to channel 1
(/dev/ttyUSB1 on a Linux host). Usually you only change the
host terminal’s tty selection – no extra wiring needed.
The arm-trusted-firmware.inc recipe enforces a fixed set of valid
TFA_CONSOLE values. Any other value causes bitbake to skip the
recipe with a message of the form TFA_CONSOLE (...) is not
configured properly for ZynqMP, only cadence, cadence0, cadence1, and
dcc are valid options. (and the corresponding Versal and
Versal-Net variants).
Note
ZynqMP :
cadence(default; resolves tocadence0),cadence0,cadence1,dccVersal :
pl011(default; resolves topl011_0),pl011_0,pl011_1,dccVersal Gen 2 :
pl011(default; resolves topl011_0),pl011_0,pl011_1,dcc
Xen and QEMU Console Notes
Xen : the hypervisor uses
serial0by default. To move it to the secondary UART, setXEN_SERIAL_CONSOLES = "serial1"inlocal.conf. See https://github.com/AMD-AECG-SSW-PUBLIC/meta-xilinx/blob/2026.1/meta-xilinx-virtualization/README.build.xen.md for the Xen build details.
Default runqemu Serial Port
When you launch a guest with runqemu, the qemuboot-xilinx class
(meta-xilinx-core/classes-recipe/qemuboot-xilinx.bbclass) wires the
QEMU -serial ports as follows:
The first entry of
SERIAL_CONSOLESbecomes the primary QEMU serial port and connects to the terminal that startedrunqemu(stdio/mon:stdio).For ZynqMP, the kernel command line uses
earlyconand resolves the console device from thechosen { stdout-path }of the DTB selected byQEMU_HW_DTB_PS(see the per-machine config inmeta-amd-adaptive-socsandmeta-kria, for examplezynqmp-zcu102-sdt-full.confsetsQEMU_HW_DTB_PS = "${QEMU_HW_DTB_PATH}/board-zynqmp-zcu102.dtb").For Versal and Versal Gen 2,
QEMU_HW_DTB_PSselects the active PL011 instance (for exampleboard-versal-ps-vek280.dtb) together withQEMU_HW_DTB_PMC = "${QEMU_HW_DTB_PATH}/board-versal-pmc-virt.dtb".Extra ports – the PMC / PMU console or the secondary PS UART – reach QEMU through
QB_OPT_APPEND(or directly throughqemuparams="-serial ..."on therunqemucommand line). They default to-serial nullso only the primary console reaches the host terminal.
The resulting per-family default runqemu console is:
SoC family |
QEMU_HW_DTB_PS (per-board) |
Primary console (host terminal) |
Secondary serial ports |
|---|---|---|---|
ZynqMP |
board-zynqmp-zcu102.dtb, board-zynqmp-zcu104.dtb, board-zynqmp-kv260.dtb, etc. |
PS UART0 -> ttyPS0 (stdio) |
PS UART1, PMU UART -> null |
Versal |
board-versal-ps-vck190.dtb, board-versal-ps-vek280.dtb, board-versal-ps-vpk180.dtb, etc. |
PL011 UART0 -> ttyAMA0 (stdio) |
PL011 UART1, PMC UART -> null |
Versal Gen 2 |
|
PL011 UART0 -> ttyAMA0 (stdio) |
PL011 UART1, PMC UART -> null |
Zynq-7000 |
n/a ( |
PS UART1 -> ttyPS0 (stdio) |
– |
MicroBlaze |
n/a ( |
xps-uartlite -> ttyUL0 (stdio) |
– |
For every Arm target in the preceding table, qemuboot-xilinx.bbclass invokes
qemu-system-amd-fpga-multiarch -machine arm-generic-fdt and selects
the actual board through QEMU_HW_DTB_PS (and QEMU_HW_DTB_PMC for
Versal). MicroBlaze targets use qemu-system-microblazeel with
-M microblaze-fdt-plnx.
Switching the runqemu Serial Port
EDF supports four methods to change which serial port runqemu
connects to the host terminal; pick the one that matches the scope of the
change you need.
Swap which port reaches the host terminal – runtime only. Use the
serialstdio/serialtcpoptions on therunqemucommand line.serialstdiokeeps stdio connected to the first-serialdevice; to redirect a different one, append your own-serialarguments throughQB_OPT_APPEND:# Default - primary console on the host terminal $ runqemu qemuparams="-serial mon:stdio -serial null" nographic # Move the host terminal to the *secondary* PS / PL011 instance instead $ runqemu qemuparams="-serial null -serial mon:stdio" nographic # Capture both UARTs to log files $ runqemu qemuparams="-serial file:uart0.log -serial file:uart1.log" nographic
Change the kernel console for the QEMU boot only. Override
KERNEL_BOOTARGS(or passbootparams=on therunqemucommand line) so Linux prints to the desired UART:$ runqemu bootparams="earlycon console=ttyPS1,115200 root=/dev/mmcblk0p2 rw rootwait" $ runqemu bootparams="earlycon console=ttyAMA1,115200 root=/dev/mmcblk0p2 rw rootwait"
Change the build-time default for ``runqemu``. Set the variables in
conf/local.confso every subsequentrunqemuuses the new port:# Linux getty + login (sysvinit) SERIAL_CONSOLES = "115200;ttyPS1" # Update the kernel command line accordingly KERNEL_BOOTARGS = "earlycon console=ttyPS1,115200 root=/dev/mmcblk0p2 rw rootwait" # Re-route the QEMU -serial wiring (poky qemuboot variable) QB_OPT_APPEND:append = " -serial null -serial mon:stdio" # Optional - point the firmware/early stages at the same instance TFA_CONSOLE = "cadence1" # or "pl011_1" for Versal / Versal Gen 2
Change the QEMU PS DTB so it exposes a different :term:`UART`.
QEMU_HW_DTB_PSselects which PL011 (Versal / Versal Gen 2) or Cadence (ZynqMP) instance reaches the QEMU console. Point it at a DTB that wires up the UART you want as primary. The ZynqMPmeta-amd-adaptive-socsandmeta-kriamachine configs setQEMU_HW_DTB_PS(for exampleboard-zynqmp-zcu102.dtb,board-zynqmp-kv260.dtb); the Versal / Versal Gen 2 configs set bothQEMU_HW_DTB_PSandQEMU_HW_DTB_PMC.# Versal example - use a custom PS DTB that maps PL011_1 to serial0 QEMU_HW_DTB_PS = "${QEMU_HW_DTB_PATH}/board-versal-ps-custom.dtb" QEMU_HW_DTB_PMC = "${QEMU_HW_DTB_PATH}/board-versal-pmc-virt.dtb" # ZynqMP example - select a different PS DTB for the same machine QEMU_HW_DTB_PS = "${QEMU_HW_DTB_PATH}/board-zynqmp-custom.dtb"
See
README.building.md(QEMU Configurations table) andhttps://github.com/Xilinx/qemu-devicetreesfor the available PS / PMC DTBs and how to author a new one.
Using a PL Serial Console Instead of the PS Default
On Zynq-7000, ZynqMP and Versal boards the default console is a PS
UART. A PL UART can serve as the console instead,
when the hardware design exposes one. Typical PL options are the
xps-uartlite or xps-uart16550 IP instantiated in the programmable
logic. PL UART ports enumerate in Linux as /dev/ttyULx (the
xps-uartlite driver). The xps-uart16550 driver registers as
/dev/ttyS<n>. The kernel allocates the exact index at probe time and
the value depends on the design. Confirm the assigned index from
dmesg after boot rather than assuming ttyS0 (refer to the
upstream 8250/16550 driver in drivers/tty/serial/8250/ for the
registration logic).
Switching the console to a PL UART requires changes in three places:
Hardware design – instantiate the
xps-uartlite/xps-uart16550IP in Vivado, route it to a board pin or PL-side USB-UART bridge, and export the updated XSA / SDT.Device tree – the regenerated SDT will already contain a
serial@...node for thePLUART (compatiblexlnx,xps-uartlite-1.00.aorxlnx,xps-uart16550-2.00.a). Pointchosen / stdout-pathat it:/ { chosen { stdout-path = "&axi_uartlite_0:115200n8"; }; };
Yocto configuration – in
conf/local.confalign the Linux user-space console and kernel command line:SERIAL_CONSOLES = "115200;ttyUL0" KERNEL_BOOTARGS = "earlycon console=ttyUL0,115200 root=/dev/mmcblk0p2 rw rootwait"
Summary
Topic |
Behavior |
|---|---|
Default UART |
Defined per BSP through the System Device Tree |
|
Automatically mapped to the BSP-default UART. The
|
Change UART (build-time) |
Update |
Change UART (hardware-wide) |
Edit |
|
Available to U-Boot and Linux only after the boot flow programs
the PL (so TF-A and PLM / FSBL cannot use
it and must stay on a PS UART). Requires that the
|
References
meta-amd-adaptive-socsmachine config files (per-board UART instance): https://github.com/AMD-AECG-SSW-PUBLIC/meta-amd-adaptive-socs/tree/2026.1/meta-amd-adaptive-socs-bsp/conf/machinemeta-kriamachine config files (Kria K26 SOM BSPs): https://github.com/AMD-AECG-SSW-PUBLIC/meta-kria/tree/2026.1/conf/machinemeta-xilinx-coreArm Trusted Firmware (ATF) console defaults: https://github.com/AMD-AECG-SSW-PUBLIC/meta-xilinx/blob/2026.1/meta-xilinx-core/recipes-bsp/arm-trusted-firmware/arm-trusted-firmware.incmeta-xilinx-coreU-BootKERNEL_BOOTARGSdefaults: https://github.com/AMD-AECG-SSW-PUBLIC/meta-xilinx/blob/2026.1/meta-xilinx-core/recipes-bsp/u-boot/u-boot-xlnx-uenv.bbmeta-xilinx-coreqemuboot-xilinxclass: https://github.com/AMD-AECG-SSW-PUBLIC/meta-xilinx/blob/2026.1/meta-xilinx-core/classes-recipe/qemuboot-xilinx.bbclassBooting guides (per family) : https://github.com/AMD-AECG-SSW-PUBLIC/meta-xilinx/tree/2026.1/docs
See Also
Board Specific Specifications and Information – per-board USB-UART bridge, connector designators, and physical UART pinout.
EDF Common Specifications – PL UART context and shared platform conventions.
Discovery and Evaluation – discovery walkthrough that includes the host-side serial setup.