Advanced: project structure and customization
This section is intended for users who want to modify the reference design — adding IP to the block design, changing constraints, adding packages or drivers to the PetaLinux project, and so on. It describes how the repository is laid out, how the Make-driven build flow works, how the block design assembles the MRMAC subsystem, how the PetaLinux BSP is composed from layered fragments, and what modifications have been added on top of the stock AMD BSP.
The actual build instructions are in build_instructions; this section is about understanding the project well enough to modify it.
Repository layout
.
├── Makefile <- Top-level build entry point
├── README.md
├── config/ <- Source-of-truth design metadata and auto-generation
│ ├── data.json
│ └── update.py
├── docs/ <- This documentation (Sphinx + Read the Docs)
├── PetaLinux/
│ ├── Makefile <- PetaLinux build orchestration
│ └── bsp/ <- Board and port-config BSP fragments
│ ├── vck190/ <- board-specific overlay
│ ├── ports-versal-0123/ <- port-config overlay: 10G targets
│ └── ports-versal-0123-25g/ <- port-config overlay: 25G targets
├── Vitis/
│ ├── Makefile <- Vitis workspace build orchestration
│ ├── build-vitis.bat <- Windows workspace-creation helper
│ ├── py/ <- Vitis Python build driver (args.json config)
│ └── common/src/ <- Echo server sources (main.c, mrmac.c, si5328.c, vadj.c)
└── Vivado/
├── Makefile <- Vivado build orchestration
├── build-vivado.bat <- Windows project-creation helper
├── scripts/
│ ├── build.tcl <- Project creation + block design assembly
│ └── xsa.tcl <- Synthesis, implementation, XSA export
└── src/
├── bd/
│ └── bd_versal.tcl <- Block design for all (Versal) targets
├── constraints/
│ └── <target>.xdc <- One XDC per target (pin assignments)
└── hdl/
├── mrmac_gt_ctrl_passthru.v <- GT-control feed-through (SDT generator workaround)
└── mrmac_port_axis_adapter.v <- MRMAC port client ↔ AXI4-Stream adapters
Per-target build outputs are written to Vivado/<target>/,
Vitis/<target>_workspace/ and PetaLinux/<target>/; packaged
boot-image zips are written to bootimages/. None of these are
committed.
Target naming
A TARGET is the canonical handle for a single design and is the only
parameter passed through the build flow. It encodes the board, the FMC
connector and (for the 25G variants) the line rate:
<board>_<connector>[_25g]
For this repo the targets are vck190_fmcp1 (4x 10GbE) and
vck190_fmcp1_25g (4x 25GbE). The first underscore-delimited token
(vck190) is taken as the target board and is what
PetaLinux/Makefile uses to select the BSP under
PetaLinux/bsp/<board>/.
The complete list of valid targets is in the UPDATER START block of
each Makefile and is generated from config/data.json (see below).
config/data.json and config/update.py
config/data.json is the canonical source of truth for the set of
supported designs and their per-target metadata (board name, board URL,
line rate, FMC connector, etc.). config/update.py reads data.json
and regenerates the auto-managed sections of the Makefiles, the Vivado
build.tcl target dictionary, the top-level README.md, and
.gitignore — the sections delimited by UPDATER START / UPDATER END
(or <!-- updater start --> / <!-- updater end -->) comment markers.
The Sphinx documentation also reads data.json directly to render the
supported-board and target-design tables.
Note
The lanes field of each design holds the list of SFP28 ports the
design instantiates (["0","1","2","3"] for all four). Each port is one
MAC client of the single MRMAC hard block and uses one GTY lane (FMC
DP0–3). The linkspeed field ("10" or "25") selects the MRMAC
configuration preset and the active client data width.
When adding or modifying a target, edit data.json and re-run
update.py (from the config/ directory). Do not hand-edit content
between the updater markers; it will be overwritten on the next
regeneration. Note that update.py derives the PetaLinux port-config
overlay name from the populated ports and the line rate:
lanes=["0","1","2","3"] with linkspeed="10" selects
bsp/ports-versal-0123/; linkspeed="25" selects
bsp/ports-versal-0123-25g/.
Make-driven build flow
There are four Makefiles in the repository, each scoped to a stage of the build:
Makefile |
Scope |
|---|---|
|
Top-level orchestration; assembles boot-image zips for one or all targets. |
|
Creates the Vivado project, runs synthesis and implementation, exports the XSA. |
|
Creates the Vitis workspace from the XSA, builds the echo server, packages BOOT.BIN. |
|
Creates the PetaLinux project from the XSA, applies BSP overlays, builds, packages. |
A make bootimage TARGET=<t> invocation at the top level cascades:
make bootimage TARGET=t
-> ensures PetaLinux build output exists
PetaLinux/Makefile petalinux TARGET=t
-> ensures Vivado XSA exists
Vivado/Makefile xsa TARGET=t
-> vivado -mode batch -source scripts/build.tcl (creates project + block design)
-> vivado -mode batch -source scripts/xsa.tcl (synth, impl, device image, XSA export)
-> petalinux-create --template versal --name t
-> petalinux-config --get-hw-description <XSA>
-> copy bsp/<board>/project-spec/* into the project
-> copy bsp/<port-config>/project-spec/* into the project (overlay)
-> petalinux-config --silentconfig
-> petalinux-build
-> petalinux-package boot --plm --psmfw --u-boot --dtb
-> ensures Vitis boot file exists (standalone echo server)
Vitis/Makefile bootfile TARGET=t
-> zip the resulting boot files into bootimages/
The dependency chain means a clean make bootimage TARGET=t from
scratch will perform every step in order. Re-running after an
intermediate step has succeeded picks up where the previous run left
off. Per-target lock files (.<target>.lock) prevent two concurrent
builds of the same target from clobbering each other.
Tip
make project TARGET=<t> (in Vivado/) creates the block design and
runs validate_bd_design without synthesis — use it to catch
block-design wiring errors fast before committing to the long XSA build.
Vivado side
Block design
There is one block-design TCL, Vivado/src/bd/bd_versal.tcl. It is
parameterised by the ports list and the line_rate (passed in from
build.tcl’s target_dict), and builds the design as follows:
CIPS + NoC + DDR. The Versal CIPS is added and configured by the
xilinx.com:bd_rule:cipsautomation (DDR branch, one DDR memory controller), then extended with a per-boardPS_PMC_CONFIG(M_AXI_LPD enabled, 16 PL→PS interrupts, two PL clocks).Clocking. A clock wizard generates the 100 MHz system clock (all AXI-Lite control and the MCDMA/NoC datapath), and a second clock wizard generates the 390.625 MHz MRMAC AXIS client clock — a single client clock domain shared by all four ports, the same client clock the AMD VCK190 Ethernet TRD uses for its 4-port MRMAC.
GT quad. One
gt_quad_base(GTY) serves all four ports: FMC DP0–3 = SFP28 slots 0–3. Its reference clock is GBTCLK0 from the FMC Si5328, and an APB3 bridge drives its DRP.MRMAC. A single MRMAC hard block is configured with the
4x10GE Wideor4x25GE Widepreset and pinned toMRMAC_X0Y0, then connected to the GT quad’s four per-lane serdes interfaces and to the per-lane user-clock buffers (see below).Per-port subsystem. The
create_sfp_portproc (called once per port) builds ansfp_port<N>hierarchy containing the MRMAC client AXIS adapters, the width-converter/CDC-FIFO datapath, the AXI MCDMA, an AXI-Lite SmartConnect, the GT-control GPIO, and the SFP sideband and LED logic.Shared peripherals. One AXI IIC reaches every I2C device on the card through the PCA9548 mux, and a 4-bit input GPIO reads the four MOD_ABS (module presence) lines. Structural counts (NoC slave ports, control SmartConnect masters, interrupts) are derived from the number of ports.
After sourcing the BD script, build.tcl runs validate_bd_design,
which triggers parameter propagation and connection automation. To see
the netlist as actually built, inspect the saved .bd under
Vivado/<target>/<target>.srcs/sources_1/bd/mrmac/ or use
write_bd_tcl.
build.tcl checks XILINX_VIVADO against the version_required constant
(2025.2) and refuses to build with a different Vivado version — the BD
TCL APIs are not stable across major releases.
The MRMAC datapath, in detail
These are the design choices that are specific to driving the four SFP28 ports as independent 10G/25G clients of one MRMAC. If you modify the block design, these are the parts most likely to need care.
MRMAC configuration — order matters
The MRMAC is configured by three set_property calls whose order is
load-bearing:
MRMAC_IS_GT_WIZ_OLD = 1first — the “old” GT wizard model exposes thegt_*_serdes_interface_*pins that connect directly to thegt_quad_baseTXn/RXn_GT_IP_Interfaceports. Setting this parameter after the preset resets the whole MRMAC configuration back to its 1x100GE default.The configuration preset (
4x10GE Wide/4x25GE Wide) — cascadesMRMAC_SPEED,MRMAC_CLIENTS=4, allMAC_PORTn_RATEand the per-port 64-bit Wide client data path selections.Location (
MRMAC_X0Y0) and the GT reference-clock frequency overrides (322.265625 MHz on every channel, so the MRMAC andgt_quad_baseagree).
The script guards this by re-reading the preset afterwards and failing fast if it was reset.
GT Quad configuration — derived, not set
Unlike the 2x QSFP28 (100G CAUI-4) design, the GT quad here is not
configured manually. With MRMAC_IS_GT_WIZ_OLD=1, IP integrator’s
parameter propagation derives the complete per-lane GT configuration
from the connected MRMAC serdes interfaces: four independent
single-lane Ethernet RAW protocols (10G or 25G line rate, LCPLL,
322.265625 MHz reference clock, TX/RXPROGDIV output clocks at
644.531 MHz) — identical to the 2025.2 MRMAC example design GT settings.
Setting the same values manually (USER strength) fights the propagation
and breaks the quad’s refclk grouping across lanes
(QUAD_PACK_SUCCESS FAIL).
One wrinkle: the derived configuration groups lanes 0/1 (HSCLK0) on
GT_REFCLK0 and lanes 2/3 (HSCLK1) on GT_REFCLK1 — and the quad’s
GT_REFCLK1 pin only exists after propagation has run. The BD script
therefore runs a first validate_bd_design pass (caught), wires
GT_REFCLK1 to the same Si5328 refclk buffer, and re-validates.
Per-lane user clocking
Each GT channel’s txoutclk and rxoutclk is buffered by a pair of
free-running BUFG_GT primitives — one full-rate, one half-rate
(BUFG_GT divides by gt_bufgtdiv+1, so the constant 1 gives /2), with
the buffer clears left at their inactive defaults. This matches the
hardware-validated MRMAC references for the Linux xilinx_axienet
driver (the 2x QSFP28 FMC design and the AMD VCK190 Ethernet TRD). In
this 4-port independent configuration every port is clocked by its
own lane in both directions (unlike 100G CAUI-4, where all four TX
lanes share the ch0 clock):
tx_core_clk[n]= chn TX full-rate;tx_alt_serdes_clk[n]= chn TX half-raterx_core_clk[n],rx_serdes_clk[n]= chn RX full-rate;rx_alt_serdes_clk[n]= chn RX half-rateGT
ch<n>_txusrclk/ch<n>_rxusrclk= chn half-rate
The AXIS client clocks tx_axi_clk/rx_axi_clk are a separate,
single 390.625 MHz domain shared by all four ports — do not confuse the
two clock buses. 390.625 MHz exceeds the minimum client frequency of
the 64-bit Wide interface at both line rates (10G needs ≥161.133 MHz,
25G needs ≥390.625 MHz).
Warning
The user-clock buffers must free-run under the Linux xilinx_axienet
driver. Two other topologies were tried and rejected during hardware
bring-up:
MBUFG_GT with
CLR/CLRB_LEAFdriven from the MRMAC’sclr/clrb_leafoutputs (the 2025.2 MRMAC example design topology): under the driver’s software reset sequence the MRMAC holds the clears asserted, stopping every GT user clock. RX then never achieves block lock, and the frozen TX serial stream makes the SFP28 module’s TX CDR squelch its laser — the link partner sees no light even though the module’s DOM diagnostics still report nominal TX power. GT reset-done still asserts, so the failure masquerades as a link or optics problem.MBUFG_GT with the clears tied off: rejected by DRC REQP-2090 at device-image generation — free-running clears are only legal on plain BUFG_GT.
MRMAC port client AXIS adapters
The MRMAC per-port “Independent Non-Segmented” client is not a
standard AXI4-Stream bus. In the block design its axis_rx_portN /
axis_tx_portN interfaces are handshake-only (they map only
TVALID/TLAST/TREADY, so IP integrator reports TDATA_NUM_BYTES=0). The
data actually rides on loose 64-bit lane pins (port N uses
rx/tx_axis_tdata<2N>) plus an 11-bit tkeep_user<2N> control word.
Feeding that handshake-only interface straight into a stock
axis_dwidth_converter mis-delineates frames.
Vivado/src/hdl/mrmac_port_axis_adapter.v provides two adapters
(mrmac_port_tx_axis_adapter, mrmac_port_rx_axis_adapter) that map
one port’s client lane onto a single standard AXIS stream at the port’s
active width: a 10GE port only drives/samples tdata[31:0]
(“Independent 32b Non-Segmented”), a 25GE port uses the full 64 bits.
The adapters and the dwidth converters are sized to the active width by
the DATA_W parameter, set from the target’s line rate.
Width conversion, CDC and MCDMA
The MRMAC client runs at 390.625 MHz at the port’s active width; the
MCDMA and NoC run at the 100 MHz system clock / 256-bit. Each direction
has an axis_dwidth_converter (active width ↔ 256 bit) and an
asynchronous axis_data_fifo for the clock-domain crossing. The
per-port AXI MCDMA (c_num_mm2s_channels/c_num_s2mm_channels = 1,
256-bit, 64-bit addressing) moves packet data to/from DDR over three NoC
AXI slave ports (scatter-gather, MM2S, S2MM). 256 bits at 100 MHz =
25.6 Gb/s, covering the line rate of a single port at both 10G and 25G.
GT-control GPIO
Each port has a dual-channel AXI GPIO (sfp_port<N>/axi_gpio_gt) that
lets software reset that port’s GT lane and read reset-done:
Channel 1 (5 outputs): bit 0 =
gt_reset_all, bit 1 =gt_reset_tx_datapath, bit 2 =gt_reset_rx_datapath, bits 3–4 = spare (gt-ctrl-rate).Channel 2 (2 inputs): bit 0 =
gt_tx_reset_done, bit 1 =gt_rx_reset_done.
Each port’s reset request bits drive only that port’s bit of the
MRMAC’s 4-bit gt_reset_*_in buses — its own GT lane — unlike the 100G
design where one GPIO bit fans out to four bonded lanes. The MRMAC’s
4-bit gt_tx/rx_reset_done_out buses are sliced per port back into the
GPIO inputs, and (inverted) release the MRMAC core/serdes resets.
The concatenated reset buses reach the MRMAC through
mrmac_gt_ctrl_passthru (Vivado/src/hdl/), a combinational
feed-through whose only purpose is to be opaque to the SDT generator:
with four different GPIOs visible behind plain slice/concat primitives,
sdtgen auto-emits a gt-ctrl-gpios property with syntactically
invalid phandles (<& 32 0>) on the MRMAC nodes, breaking every
downstream device-tree compile (Vitis platform and PetaLinux). The real
per-port gt-*-gpios bindings live in port-config.dtsi.
SFP sideband and LEDs
The SFP sideband signals are handled in fabric, with no software in the loop:
TX_DISABLE is tied low — the module transmitter is enabled from configuration.
RS0/RS1 (SFP28 rate select) are tied low on the 10G targets (reduced bandwidth) and high on the 25G targets (full 25G bandwidth).
User LEDs are driven from the MRMAC’s per-port
stat_rx_statusand the slot’s MOD_ABS: green = module present and link up, red = module present and link down, both off when no module is present.MOD_ABS (active-high absence) additionally feeds the shared 4-bit input GPIO read by the Linux SFP framework, and RX_LOS / TX_FAULT are routed into each port hierarchy.
Address and interrupt maps
The control peripherals are mapped from M_AXI_LPD (addresses as
assigned in the released projects):
Peripheral |
Port 0 |
Port 1 |
Port 2 |
Port 3 |
|---|---|---|---|---|
GT-control GPIO |
|
|
|
|
AXI MCDMA |
|
|
|
|
Shared peripheral |
Address |
|---|---|
GT quad APB3 bridge |
|
MRMAC |
|
MOD_ABS GPIO |
|
AXI IIC (PCA9548 mux) |
|
Each MAC port owns a 4 KB register page inside the MRMAC s_axi
window (port N at 0x80010000 + N*0x1000).
Interrupts are connected to pl_ps_irq0..8 (GIC SPI = 84 + index):
|
SPI |
Source |
|---|---|---|
0 |
84 |
Port 0 MCDMA |
1 |
85 |
Port 0 MCDMA |
2 |
86 |
Port 1 MCDMA |
3 |
87 |
Port 1 MCDMA |
4 |
88 |
Port 2 MCDMA |
5 |
89 |
Port 2 MCDMA |
6 |
90 |
Port 3 MCDMA |
7 |
91 |
Port 3 MCDMA |
8 |
92 |
AXI IIC (PCA9548) |
Constraints
Vivado/src/constraints/<target>.xdc contains the pin assignments. For
the VCK190 targets it covers the four GTY lanes (DP0–3 = SFP28 slots
0–3), the GT reference clock (GBTCLK0), the I2C bus to the PCA9548 mux
(LA11), and the per-slot SFP sideband I/O and user LEDs on LA pins (all
LVCMOS15 — the FMC VADJ rail runs at 1.5V on these boards). The 10G and
25G XDCs are identical apart from the file header.
Modifying the block design
Edit Vivado/src/bd/bd_versal.tcl. Most per-port logic lives in the
create_sfp_port proc, which is called once per entry in ports;
structural counts (NoC slave ports, control SmartConnect masters,
interrupts) are derived from the number of ports, so adding or removing
a port is largely a matter of changing the lanes list in data.json.
The line rate is selected by the linkspeed field, which switches the
MRMAC preset, the adapter/dwidth widths and the rate-select pin levels.
After editing, delete the existing project directory and rebuild:
rm -rf Vivado/<target>
cd Vivado
make xsa TARGET=<target>
Vitis side
The bare-metal echo server is built by the universal Vitis Python build
driver (Vitis/py/build-vitis.py, configured by Vitis/py/args.json).
It creates a platform from the target’s XSA and an application
(echo_server) from the sources in Vitis/common/src/ — there is no
lwIP or BSP-library dependency, since the app drives the MRMAC, MCDMA,
I2C (Si5328) and VADJ directly through the standalone driver layer. See
echo_server for what the application does and how to run
it.
PetaLinux side
BSP composition
The PetaLinux project is composed at build time from two BSP fragments copied into the target’s project directory:
A board BSP at
PetaLinux/bsp/vck190/. Provides the board kernel and U-Boot configuration,system-user.dtsi(which includesport-config.dtsi), the kernel patches, and the rootfs configuration.A port-config overlay at
PetaLinux/bsp/ports-versal-0123/(10G) orPetaLinux/bsp/ports-versal-0123-25g/(25G). Providesport-config.dtsi— the device-tree fragment that wires up the four MRMAC ports, their MCDMAs, the GT-control GPIOs, the I2C mux, the Si5328 and the SFP cages. The two overlays differ only in themax-speedvalues (10000 vs 25000).
The mapping from target to (board BSP, port-config overlay) is encoded
in PetaLinux/Makefile’s UPDATER block, for example:
vck190_fmcp1_target := versal 0 0 ports-versal-0123
The first column is the PetaLinux template (versal); the last is the
port-config overlay name. The board BSP is derived from the first token
of the target name (vck190). At build time both project-spec/ trees
are copied in, with the port-config overlay copied after the board BSP.
The port-config.dtsi overlay
This is the device-tree fragment that makes the MRMAC ports work. The
SDT generator emits one DT node per MAC port from the single MRMAC
instance, in port order: mrmac (port 0), mrmac_1, mrmac_2,
mrmac_3. Per port the overlay sets, on that node:
axistream-connected→ the port’s MCDMA node (sfp_port<N>_axi_mcdma), plus the MCDMA channel interrupts (mm2s_ch1_introut/s2mm_ch1_introut) and their GICinterrupts. Thexilinx_axienetMCDMA probe looks the interrupts up by name on the MRMAC node, so bothinterrupt-namesand the matchinginterrupt-parent/interruptsmust be present here.local-mac-address(00:0a:35:00:00:0N),xlnx,channel-ids,xlnx,num-queues,xlnx,addrwidth.max-speed = <10000>(or<25000>on the 25G overlay) — the line rate the driver programs into the port.gt-ctrl-gpios,gt-tx-dpath-gpios,gt-rx-dpath-gpios,gt-ctrl-rate-gpios,gt-tx-rst-done-gpios,gt-rx-rst-done-gpios(all on the port’s GT-control AXI GPIO, lines 0–6) andxlnx,gtlane = <N>. These let the driver reset the port’s GT lane and poll reset-done (see below).
It also overrides each MCDMA node’s compatible to "xlnx,eth-dma",
instantiates the PCA9548 mux and the Si5328 on the shared I2C bus, and
adds the four SFP cage nodes (see below).
Modifications layered on the stock BSP
The board BSP started as the stock AMD VCK190 reference BSP. This list is the answer to “what would I lose if I overwrote the BSP with the stock one?”
AXI Ethernet + MCDMA driver. Kernel configs enable the
xilinx_axienetdriver with MCDMA support (CONFIG_XILINX_AXI_EMAC,CONFIG_AXIENET_HAS_MCDMA,CONFIG_GPIO_XILINX,CONFIG_I2C_XILINX). The four MRMAC ports bind toxilinx_axienetand appear aseth0–eth3.MCDMA
compatibleoverride (device tree).xilinx_axienetioremaps the MCDMA registers itself, but the standalonexilinx_dmadmaengine driver also matches the MCDMA node and claims the region first, so axienet’s probe fails with-EBUSY. BecauseCONFIG_XILINX_AXI_EMACdepends onXILINX_DMA, the dmaengine driver cannot simply be disabled. The fix is thecompatible = "xlnx,eth-dma"override inport-config.dtsi:xilinx_dma’s of-match table does not bindeth-dma, and axienet finds the MCDMA via theaxistream-connectedphandle (not by compatible), so the region is left for axienet.GT-control GPIO binding. The
xilinx_axienetMRMAC driver needs to reset the GT lane and read reset-done/PLL status from the PS. The block design exposes a dual-channel AXI GPIO per port (sfp_port<N>/axi_gpio_gt): five outputs (gt_reset_all, gt_reset_tx_datapath, gt_reset_rx_datapath, plus two spare gt-ctrl-rate lines) and two inputs (gt_tx/rx_reset_done). Thegt-*-gpiosproperties inport-config.dtsipoint the driver at these GPIO lines. Without this, the driver fails withunable to get GT PLL resource.Si5328 clock generator (device tree).
port-config.dtsiinstantiates asilabs,si5328clock-generator@68node on channel 4 of the PCA9548 mux, with a fixed-clock 114.285 MHz crystal input and aclk0@0output programmed to 322.265625 MHz (the GT reference clock on GBTCLK0). The Linuxclk-si5324driver programs the device from this node on probe.SFP cages through the kernel SFP framework. Kernel configs (
CONFIG_SFP,CONFIG_MDIO_I2C,CONFIG_I2C_MUX,CONFIG_I2C_MUX_PCA954x) plus the foursff,sfpcage nodes inport-config.dtsi(module presence via the MOD_ABS GPIO’smod-def0-gpios, module I2C via mux channels 0–3) give module presence detection, EEPROM access and diagnostics (hwmon). The axienet/MRMAC driver has no phylink, so the cages are standalone management devices — they are not linked to the MACs.MRMAC link carrier-monitor kernel patch. The MRMAC has no PHY/phylink and gives no link-change interrupt, and the stock
xilinx_axienetdriver checks RX block lock only once inaxienet_open()(a 1 ms poll), failing the open with-ENODEVif the link is not already up. On a cold bring-up the GT/PCS take longer than that to lock, so the open loses the race and the port needs a manualip linkbounce; a link partner that powers on later never brings the port up; and the driver never sets the netdev carrier (ip linkshowsstate UNKNOWN). The patchrecipes-kernel/linux/linux-xlnx/0002-net-axienet-mrmac-carrier-link-monitor.patchadds a delayed-work monitor that drives the netdev carrier from RX block-lock + status.open()now brings the interface up with carrier off and starts the monitor instead of failing. While the link is down the monitor re-issues the MRMAC core/serdes reset (axienet_mrmac_reset) each cycle to re-attempt lock — the Versal GTY RX does not re-acquire block lock on a partner signal that stabilises after its last reset, and the GT reset is one-shot, so the MRMAC reset is the part that re-aligns the lane — and once up it polls for loss. The net effect is that a port comes up automatically at boot and recovers on cable re-seat or partner power-on, with link state reflected in the netdev carrier (MRMAC link up at 10000/MRMAC link down). It is registered viaSRC_URI:appendinrecipes-kernel/linux/linux-xlnx_%.bbappend.Loopback self-test app. The
mrmac-loopback-testrecipe (recipes-apps/mrmac-loopback-test/) installs the self-test script described in petalinux; it is force-installed viaIMAGE_INSTALL:appendinmeta-user/conf/petalinuxbsp.conf.Root filesystem additions.
ethtool,iperf3andphytool.
Adding a kernel config option, patch, package or device-tree node
The mechanisms are the standard PetaLinux ones:
Kernel config: append
CONFIG_<name>=ytobsp/vck190/project-spec/meta-user/recipes-kernel/linux/linux-xlnx/bsp.cfg.Kernel patch: drop the
.patchintorecipes-kernel/linux/linux-xlnx/and add aSRC_URI:appendline tolinux-xlnx_%.bbappend. Force a re-patch withpetalinux-build -c kernel -x cleansstate && petalinux-build.Rootfs package: add
CONFIG_<package>=ytoconfigs/rootfs_config(and declare it inmeta-user/conf/user-rootfsconfigif it is not in the default menu).Per-board device tree: edit
meta-user/recipes-bsp/device-tree/files/system-user.dtsi.Per-port device tree: edit the
bsp/ports-versal-0123[-25g]/…/port-config.dtsioverlay.
Tip
After a structurally-changed XSA (new peripherals/addresses), a
petalinux-config --get-hw-description on an existing project keeps the
stale SDT (“workspace already set up, leaving as-is”). Remove
<target>/components/plnx_workspace before re-importing to force a fresh
SDT, then rebuild (this reuses the sstate cache, so it is incremental).
Where build outputs land
Path |
Contents |
|---|---|
|
Vivado project. |
|
Device image / bitstream. |
|
Per-target Vivado build logs (xpr + xsa). |
|
Vitis workspace (platform + |
|
Standalone |
|
PetaLinux project. All Yocto build state lives here. |
|
|
|
Per-target zipped boot files ( |
None of these directories are committed to the repository.