はじめに
本記事ではKR260に実装されている4つのEthernet PortをPSが内蔵するEthernet ControllerのGEMに接続する方法について記述します。
KR260には4つのEthernet Portがありますが、GEMに直接接続されているのは2つだけです。残り2つはPLから接続するのですが、ネット上で調べてみると有償のIPを利用する方法しか見当たりませんでした。IPには試用ライセンスもあるのですが、継続的に利用したい場合はちょっと不便という事で、GEMへの接続を模索した結果を記述します。
システム概要
OSはPetaLinuxを利用しますが、u-boot起動時には全てのポートを利用可能にする為、BOOT.BINでPLのコンフィグレーションを行い、PetaLinuxではdfx-mgr.serviceを無効化します。
開発環境
Board
Kria KR260 Robotics Starter Kit
Tools
Vivado 2024.2
PetaLinux 2024.2
PetaLinux BSP
xilinx-kr260-starterkit-xsct-v2024.2-12072024.bsp
Host OS
Ubuntu 24.04 Desktop
構成
Block Design
今回実装するBlock Designは以下の通りです。
PSにはGEMが4つ内蔵されており、GEM0/GEM1/GEM2/GEM3という形で識別されます。この内、GEM0/GEM1にはMIOを利用してPHYが接続されています。本記事ではGEM2/GEM3に未接続のPHYを接続します。
PLから接続する2つのPHYはEMIO I/Fを利用してGEMに接続します。GEMのEMIO I/FはGMIIですが、PHY側のI/FはRGMIIです。その為、信号を変換するIP(GMII to RGMII)を介してGEMとPHYを接続します。
GMII to RGMII
GMII to RGMIIのインスタンスは2つ存在しますが、Shared Logicの有無により入出力信号が異なります。Shared Logicは内部で利用するクロック生成に関わっており、Shared Logicを含むenet2_gmii_to_rgmiiはclkinに接続されたクロックから125MHz, 25MHz, 2.5MHzのクロックを生成し、それらを外部にも出力します。
Shared Logicを含まないenet3_gmii_to_rgmiiではこのクロックを利用しています。
この他、デバッグ用途として各インスタンスのlink_status信号をボード上のLEDに接続してあります。
クロック
MPSoCの場合、GMII to RGMIには375MHzのクロックを接続します。この仕様はPG160に記載されています。このクロックはShared Logicを含むenet2_gmii_to_rgmiiへ接続します。
リセット
各IPのリセット信号はProcessor System Resetに接続してあります。この他、PHYのリセット信号も接続する必要がありますが、KR260のSchematicsを見るとGEM0/GEM1に接続しているPHYはリセット信号が固定されている様でしたので、同様にGEM2/GEM3のリセット信号もHighに固定しています。
PHYのリセット信号はActive Lowなので、何も接続しない状態だとPHYは動作不可能となります。
Vivado作業手順
以下のTCLスクリプトと制約ファイルを使い、プロジェクトの作成からXSAファイルの生成までを行います。kr260-4eth.tclの最初に定義しているパラメータは環境に合わせて変更して下さい。
kr260-4eth.tcl - プロジェクト作成&XSAファイル生成
# parameters
set JOBS 8
set PROJ_NAME kr260-4eth
set PROJ_DIR $env(HOME)/ws/vivado/$PROJ_NAME
set SCRIPT_DIR [file dirname [info script]]
set XDC_FILE $SCRIPT_DIR/$PROJ_NAME.xdc
set BD_FILE $SCRIPT_DIR/${PROJ_NAME}-bd.tcl
# create the project
create_project $PROJ_NAME $PROJ_DIR -part xck26-sfvc784-2LV-c
set_property board_part xilinx.com:kr260_som:part0:1.1 [current_project]
set_property board_connections {som240_1_connector xilinx.com:kr260_carrier:som240_1_connector:1.1 som240_2_connector xilinx.com:kr260_carrier:som240_2_connector:1.1} [current_project]
set_property STEPS.WRITE_BITSTREAM.ARGS.BIN_FILE true [get_runs impl_1]
# create the block design
create_bd_design design_1
source $SCRIPT_DIR/$BD_FILE
save_bd_design
# create the wrapper file
make_wrapper -files [get_files $PROJ_DIR/$PROJ_NAME.srcs/sources_1/bd/design_1/design_1.bd] -top
add_files -norecurse $PROJ_DIR/$PROJ_NAME.gen/sources_1/bd/design_1/hdl/design_1_wrapper.v
# add the constraint file
add_files -fileset constrs_1 -norecurse $XDC_FILE
import_files -fileset constrs_1 $XDC_FILE
# generate the bitstream file
update_compile_order -fileset sources_1
launch_runs impl_1 -to_step write_bitstream -jobs $JOBS
wait_on_run impl_1
# write the XSA file
write_hw_platform -fixed -include_bit -force -file $PROJ_DIR/$PROJ_NAME.xsa
kr260-4eth-bd.tcl - Block Design作成
#
# local functions
#
namespace eval local {
proc create_xip_cell {ip name args} {
set cell [create_bd_cell -type ip -vlnv xilinx.com:ip:$ip $name]
if {[llength $args] > 0} {
set_property -dict [lindex $args 0] $cell
}
return $cell
}
proc connect_pins {pin_a pin_b} {
connect_bd_net [get_bd_pins $pin_a] [get_bd_pins $pin_b]
}
proc connect_pins_list {obj_a obj_b pins_list} {
if {[llength $pins_list] > 0} {
set pins [lindex $pins_list 0]
set pin_a $obj_a/[lindex $pins 0]
set pin_b $obj_b/[lindex $pins 1]
connect_pins $pin_a $pin_b
connect_pins_list $obj_a $obj_b [lrange $pins_list 1 end]
}
}
proc connect_ifs {if_a if_b} {
connect_bd_intf_net [get_bd_intf_pins $if_a] [get_bd_intf_pins $if_b]
}
proc make_pin_external {bd_pin name} {
make_bd_pins_external [get_bd_pins $bd_pin] -name $name
}
proc make_if_external {bd_if name} {
make_bd_intf_pins_external [get_bd_intf_pins $bd_if] -name $name
}
}
#
# MPSoC
#
set mpsoc [eval create_bd_cell -type ip -vlnv xilinx.com:ip:zynq_ultra_ps_e:3.5 zynq_ultra_ps]
apply_bd_automation -rule xilinx.com:bd_rule:zynq_ultra_ps_e -config {apply_board_preset "1" } $mpsoc
set_property -dict {
CONFIG.PSU__ENET2__GRP_MDIO__ENABLE 1
CONFIG.PSU__ENET2__GRP_MDIO__IO EMIO
CONFIG.PSU__ENET2__PERIPHERAL__ENABLE 1
CONFIG.PSU__ENET2__PERIPHERAL__IO EMIO
CONFIG.PSU__ENET3__GRP_MDIO__ENABLE 1
CONFIG.PSU__ENET3__GRP_MDIO__IO EMIO
CONFIG.PSU__ENET3__PERIPHERAL__ENABLE 1
CONFIG.PSU__ENET3__PERIPHERAL__IO EMIO
CONFIG.PSU__TTC0__WAVEOUT__ENABLE 1
CONFIG.PSU__TTC0__WAVEOUT__IO EMIO
} $mpsoc
local::connect_pins zynq_ultra_ps/pl_clk0 zynq_ultra_ps/maxihpm0_fpd_aclk
local::connect_pins zynq_ultra_ps/pl_clk0 zynq_ultra_ps/maxihpm1_fpd_aclk
#
# FAN_CTRL
#
local::create_xip_cell xlslice:1.0 ttc0_msb {
CONFIG.DIN_WIDTH 3
CONFIG.DIN_FROM 2
CONFIG.DIN_TO 2
}
local::make_pin_external ttc0_msb/Dout FAN_CTRL
local::connect_pins ttc0_msb/Din zynq_ultra_ps/emio_ttc0_wave_o
#
# GMII to RGMII
#
local::create_xip_cell gmii_to_rgmii:4.1 enet2_gmii_to_rgmii {
CONFIG.SupportLevel {Include_Shared_Logic_in_Core}
}
local::connect_ifs enet2_gmii_to_rgmii/MDIO_GEM zynq_ultra_ps/MDIO_ENET2
local::connect_ifs enet2_gmii_to_rgmii/GMII zynq_ultra_ps/GMII_ENET2
local::make_if_external enet2_gmii_to_rgmii/MDIO_PHY MDIO_PL_GEM2_PHY
local::make_if_external enet2_gmii_to_rgmii/RGMII RGMII_PL_GEM2_PHY
local::create_xip_cell gmii_to_rgmii:4.1 enet3_gmii_to_rgmii
local::connect_ifs enet3_gmii_to_rgmii/MDIO_GEM zynq_ultra_ps/MDIO_ENET3
local::connect_ifs enet3_gmii_to_rgmii/GMII zynq_ultra_ps/GMII_ENET3
local::make_if_external enet3_gmii_to_rgmii/MDIO_PHY MDIO_PL_GEM3_PHY
local::make_if_external enet3_gmii_to_rgmii/RGMII RGMII_PL_GEM3_PHY
local::connect_pins_list enet2_gmii_to_rgmii enet3_gmii_to_rgmii {
{mmcm_locked_out mmcm_locked_in}
{ref_clk_out ref_clk_in}
{gmii_clk_125m_out gmii_clk_125m_in}
{gmii_clk_25m_out gmii_clk_25m_in}
{gmii_clk_2_5m_out gmii_clk_2_5m_in}
}
# for debugging
local::make_pin_external enet2_gmii_to_rgmii/link_status LED_UF1
local::make_pin_external enet3_gmii_to_rgmii/link_status LED_UF2
# suplly 375MHz to GMII-to-RGMII
local::create_xip_cell clk_wiz:6.0 clk_wiz {
CONFIG.CLKOUT1_JITTER 107.361
CONFIG.CLKOUT1_PHASE_ERROR 152.147
CONFIG.CLKOUT1_REQUESTED_OUT_FREQ 375
CONFIG.MMCM_CLKFBOUT_MULT_F 24.375
CONFIG.MMCM_CLKOUT0_DIVIDE_F 3.250
CONFIG.MMCM_DIVCLK_DIVIDE 2
CONFIG.USE_LOCKED false
CONFIG.USE_RESET false
}
apply_bd_automation -rule xilinx.com:bd_rule:board -config { Board_Interface {som240_1_connector_hpa_clk0p_clk ( HPA_CLK0P_CLK (som240_1_connector) ) } Manual_Source {Auto}} [get_bd_pins clk_wiz/clk_in1]
local::connect_pins clk_wiz/clk_out1 enet2_gmii_to_rgmii/clkin
#
# PHY reset signals
#
create_bd_port -dir O -type rst PL_GEM2_RESETN
create_bd_port -dir O -type rst PL_GEM3_RESETN
local::create_xip_cell xlconstant:1.1 SIGNAL_HIGH
local::connect_pins SIGNAL_HIGH/Dout PL_GEM2_RESETN
local::connect_pins SIGNAL_HIGH/Dout PL_GEM3_RESETN
#
# system reset
#
local::create_xip_cell proc_sys_reset:5.0 sys_reset
local::connect_pins zynq_ultra_ps/pl_clk0 sys_reset/slowest_sync_clk
local::connect_pins zynq_ultra_ps/pl_resetn0 sys_reset/ext_reset_in
local::connect_pins sys_reset/peripheral_reset enet2_gmii_to_rgmii/tx_reset
local::connect_pins sys_reset/peripheral_reset enet2_gmii_to_rgmii/rx_reset
local::connect_pins sys_reset/peripheral_reset enet3_gmii_to_rgmii/tx_reset
local::connect_pins sys_reset/peripheral_reset enet3_gmii_to_rgmii/rx_reset
#
# epilogue
#
upgrade_project -migrate_to_inline_hdl
regenerate_bd_layout
kr260-4eth.xdc - 制約ファイル
# FAN controller
set_property PACKAGE_PIN A12 [get_ports {FAN_CTRL[0]}]
set_property IOSTANDARD LVCMOS18 [get_ports {FAN_CTRL[0]}]
# PL_GEM2_PHY
set_property IOSTANDARD LVCMOS18 [get_ports MDIO_PL_GEM2_PHY_mdc]
set_property IOSTANDARD LVCMOS18 [get_ports MDIO_PL_GEM2_PHY_mdio_io]
set_property IOSTANDARD LVCMOS18 [get_ports RGMII_PL_GEM2_PHY_rx_ctl]
set_property IOSTANDARD LVCMOS18 [get_ports RGMII_PL_GEM2_PHY_rxc]
set_property IOSTANDARD LVCMOS18 [get_ports RGMII_PL_GEM2_PHY_tx_ctl]
set_property IOSTANDARD LVCMOS18 [get_ports RGMII_PL_GEM2_PHY_txc]
set_property IOSTANDARD LVCMOS18 [get_ports {RGMII_PL_GEM2_PHY_rd[3]}]
set_property IOSTANDARD LVCMOS18 [get_ports {RGMII_PL_GEM2_PHY_rd[2]}]
set_property IOSTANDARD LVCMOS18 [get_ports {RGMII_PL_GEM2_PHY_rd[1]}]
set_property IOSTANDARD LVCMOS18 [get_ports {RGMII_PL_GEM2_PHY_rd[0]}]
set_property IOSTANDARD LVCMOS18 [get_ports {RGMII_PL_GEM2_PHY_td[3]}]
set_property IOSTANDARD LVCMOS18 [get_ports {RGMII_PL_GEM2_PHY_td[2]}]
set_property IOSTANDARD LVCMOS18 [get_ports {RGMII_PL_GEM2_PHY_td[1]}]
set_property IOSTANDARD LVCMOS18 [get_ports {RGMII_PL_GEM2_PHY_td[0]}]
set_property PACKAGE_PIN A1 [get_ports {RGMII_PL_GEM2_PHY_rd[0]}]
set_property PACKAGE_PIN B3 [get_ports {RGMII_PL_GEM2_PHY_rd[1]}]
set_property PACKAGE_PIN A3 [get_ports {RGMII_PL_GEM2_PHY_rd[2]}]
set_property PACKAGE_PIN B4 [get_ports {RGMII_PL_GEM2_PHY_rd[3]}]
set_property PACKAGE_PIN E1 [get_ports {RGMII_PL_GEM2_PHY_td[0]}]
set_property PACKAGE_PIN D1 [get_ports {RGMII_PL_GEM2_PHY_td[1]}]
set_property PACKAGE_PIN F2 [get_ports {RGMII_PL_GEM2_PHY_td[2]}]
set_property PACKAGE_PIN E2 [get_ports {RGMII_PL_GEM2_PHY_td[3]}]
set_property PACKAGE_PIN A4 [get_ports RGMII_PL_GEM2_PHY_rx_ctl]
set_property PACKAGE_PIN F1 [get_ports RGMII_PL_GEM2_PHY_tx_ctl]
set_property PACKAGE_PIN A2 [get_ports RGMII_PL_GEM2_PHY_txc]
set_property PACKAGE_PIN D4 [get_ports RGMII_PL_GEM2_PHY_rxc]
set_property PACKAGE_PIN G3 [get_ports MDIO_PL_GEM2_PHY_mdc]
set_property PACKAGE_PIN F3 [get_ports MDIO_PL_GEM2_PHY_mdio_io]
set_property SLEW SLOW [get_ports MDIO_PL_GEM2_PHY_mdc]
set_property SLEW SLOW [get_ports MDIO_PL_GEM2_PHY_mdio_io]
set_property PACKAGE_PIN B1 [get_ports {PL_GEM2_RESETN[0]}]
set_property IOSTANDARD LVCMOS18 [get_ports {PL_GEM2_RESETN[0]}]
# PL_GEM3_PHY
set_property PACKAGE_PIN R8 [get_ports MDIO_PL_GEM3_PHY_mdc]
set_property PACKAGE_PIN T8 [get_ports MDIO_PL_GEM3_PHY_mdio_io]
set_property PACKAGE_PIN H3 [get_ports RGMII_PL_GEM3_PHY_rx_ctl]
set_property PACKAGE_PIN K4 [get_ports RGMII_PL_GEM3_PHY_rxc]
set_property PACKAGE_PIN Y8 [get_ports RGMII_PL_GEM3_PHY_tx_ctl]
set_property PACKAGE_PIN J1 [get_ports RGMII_PL_GEM3_PHY_txc]
set_property PACKAGE_PIN H4 [get_ports {RGMII_PL_GEM3_PHY_rd[3]}]
set_property PACKAGE_PIN J2 [get_ports {RGMII_PL_GEM3_PHY_rd[2]}]
set_property PACKAGE_PIN K2 [get_ports {RGMII_PL_GEM3_PHY_rd[1]}]
set_property PACKAGE_PIN H1 [get_ports {RGMII_PL_GEM3_PHY_rd[0]}]
set_property PACKAGE_PIN V8 [get_ports {RGMII_PL_GEM3_PHY_td[3]}]
set_property PACKAGE_PIN U8 [get_ports {RGMII_PL_GEM3_PHY_td[2]}]
set_property PACKAGE_PIN V9 [get_ports {RGMII_PL_GEM3_PHY_td[1]}]
set_property PACKAGE_PIN U9 [get_ports {RGMII_PL_GEM3_PHY_td[0]}]
set_property IOSTANDARD LVCMOS18 [get_ports MDIO_PL_GEM3_PHY_mdc]
set_property IOSTANDARD LVCMOS18 [get_ports MDIO_PL_GEM3_PHY_mdio_io]
set_property IOSTANDARD LVCMOS18 [get_ports RGMII_PL_GEM3_PHY_rx_ctl]
set_property IOSTANDARD LVCMOS18 [get_ports RGMII_PL_GEM3_PHY_rxc]
set_property IOSTANDARD LVCMOS18 [get_ports RGMII_PL_GEM3_PHY_tx_ctl]
set_property IOSTANDARD LVCMOS18 [get_ports RGMII_PL_GEM3_PHY_txc]
set_property IOSTANDARD LVCMOS18 [get_ports {RGMII_PL_GEM3_PHY_rd[3]}]
set_property IOSTANDARD LVCMOS18 [get_ports {RGMII_PL_GEM3_PHY_rd[2]}]
set_property IOSTANDARD LVCMOS18 [get_ports {RGMII_PL_GEM3_PHY_rd[1]}]
set_property IOSTANDARD LVCMOS18 [get_ports {RGMII_PL_GEM3_PHY_rd[0]}]
set_property IOSTANDARD LVCMOS18 [get_ports {RGMII_PL_GEM3_PHY_td[3]}]
set_property IOSTANDARD LVCMOS18 [get_ports {RGMII_PL_GEM3_PHY_td[2]}]
set_property IOSTANDARD LVCMOS18 [get_ports {RGMII_PL_GEM3_PHY_td[1]}]
set_property IOSTANDARD LVCMOS18 [get_ports {RGMII_PL_GEM3_PHY_td[0]}]
set_property PACKAGE_PIN K1 [get_ports {PL_GEM3_RESETN[0]}]
set_property IOSTANDARD LVCMOS18 [get_ports {PL_GEM3_RESETN[0]}]
# LED
set_property PACKAGE_PIN F8 [get_ports LED_UF1]
set_property IOSTANDARD LVCMOS18 [get_ports LED_UF2]
set_property PACKAGE_PIN E8 [get_ports LED_UF2]
set_property IOSTANDARD LVCMOS18 [get_ports LED_UF1]
全てのファイルを同じフォルダ配下に置いたら、下記コマンドを実行します。実行が完了するとプロジェクト配下にXSAファイルが生成されます。
source /tools/Xilinx/Vivado/2024.2/settings64.sh
vivado -mode batch -source kr260-4eth.tcl
PetaLinux作業手順
環境変数定義
作業時に利用する環境変数を以下の様に定義します。
BSP_FILE=$HOME/xilinx-kr260-starterkit-xsct-v2024.2-12072024.bsp
PROJ_NAME=kr260-4eth
PROJ_DIR=$HOME/ws/petalinux/$PROJ_NAME
XSA_FILE=$HOME/ws/vivado/$PROJ_NAME/${PROJ_NAME}.xsa
BSP_FILEはPetaLinuxのプロジェクト作成で利用するファイルです。記事執筆時点では下記から入手可能です。
BSP_FILEはホームディレクトリ配下に置いている事を想定しています。ここのパスも作業環境に合わせて変更して下さい。
今回はXSCT版のBSPを使用します。XSCT版は既にOBSOLETE扱いで最新の2025.1ではサポートされていません。しかし、今回のBlock Designを使ったビルドでは、SDT版のBSPだとfsblとpmu-firmwareがビルド出来ない問題がありました。
SDTを元に自動生成されるxparameters.hが空になっているのがビルド出来ない原因でした。解決する手段を模索しましたが作業が煩雑になる為、今回はビルド可能なXSCT版のBSPを利用しています。
プロジェクト作成
BSP_FILEを元にプロジェクトを作成します。コマンドの実行前にPetaLinuxのsettings.shを実行しておいて下さい。
petalinux-create project -n $PROJ_DIR -s $BSP_FILE
cd $PROJ_DIR
petalinux-config --get-hw-description $XSA_FILE --silentconfig
petalinux-configを実行して下記メッセージが表示されたら"y"を入力して下さい。
[WARNING] Your yocto SDK was changed in tool
Please input "y" to proceed the installing SDK into project, "n" to use existing yocto SDK:
dfx-mgr.serviceのマスク処理追加
以前の記事同様、dfx-mgr.serviceを起動しない様に設定します。
dfx-mgr_%.bbappendのファイル名でdfx-mgr.serviceをマスクする処理を追加します。
INST_DIR = "/etc/systemd/system"
SYMLINK_INST_DIR = "${sysconfdir}/systemd/system"
do_install:append() {
install -d ${D}${SYMLINK_INST_DIR};
ln -sf /dev/null ${D}${SYMLINK_INST_DIR}/${PN}.service
}
FILE:${PN}:append = " ${SYMLINK_INST_DIR}"
Devicetree修正
PL部に実装したGMII to RGMIIのDevicetreeは自動で生成されますが、外付けのPHYは生成されません。そこで、PHYに関する記述をsystem-user.dtsiに追記します。
/include/ "system-conf.dtsi"
/ {
};
&gem2 {
phy-handle = <&phy2>;
};
&enet2_gmii_to_rgmii {
phy-handle = <&phy2>;
};
&psu_ethernet_2_mdio {
phy2: ethernet-phy@2 {
ti,dp83867-rxctrl-strap-quirk;
ti,fifo-depth = <0x01>;
ti,tx-internal-delay = <0x04>;
ti,rx-internal-delay = <0x04>;
reg = <0x02>;
compatible = "ethernet-phy-id2000.a231";
};
};
&gem3 {
phy-handle = <&phy3>;
};
&enet3_gmii_to_rgmii {
phy-handle = <&phy3>;
};
&psu_ethernet_3_mdio {
phy3: ethernet-phy@3 {
ti,dp83867-rxctrl-strap-quirk;
ti,fifo-depth = <0x01>;
ti,tx-internal-delay = <0x04>;
ti,rx-internal-delay = <0x04>;
reg = <0x03>;
compatible = "ethernet-phy-id2000.a231";
};
};
PetaLinuxのビルド
レシピの修正を終えたらPetaLinuxのビルドを行います。
petalinux-build
BIFファイル作成
BOOT.BINを作成する為のBIFファイルを作成します。通常petalinux-packageコマンドでBOOT.BINが作成可能なのですが、KR260のBSPで作成したプロジェクトではBOOT.BINにBitstreamを含んでくれませんので、bootgenコマンドを直接実行してBOOT.BINを作成します。BIFファイルの中にはファイル名が含まれますが、ここではPetaLinuxのプロジェクト配下で実行する事を想定したパス指定となっています。
the_ROM_image:
{
[bootloader, destination_cpu=a53-0] images/linux/zynqmp_fsbl.elf
[pmufw_image] images/linux/pmufw.elf
[destination_device=pl] images/linux/system.bit
[destination_cpu=a53-0, exception_level=el-3, trustzone] images/linux/bl31.elf
[destination_cpu=a53-0, load=0x100000] images/linux/system.dtb
[destination_cpu=a53-0, exception_level=el-2] images/linux/u-boot.elf
}
BOOT.BIN生成
先程作成したBIFファイルを使いBOOT.BINを生成します。bootgenコマンドの実行はPetaLinuxのプロジェクト配下で実行して下さい。
cd $PROJ_DIR
bootgen -arch zynqmp -image kr260-bootgen.bif -o images/linux/BOOT.BIN
SDイメージ作成
最後にSDイメージを作成します。
petalinux-package wic --images-dir images/linux/ --bootfiles "ramdisk.cpio.gz.u-boot,boot.scr,Image,system.dtb,system-zynqmp-sck-kr-g-revB.dtb"
コマンド実行が成功すると$PROJ_DIR/image/linux/petalinux-sdimage.wicが生成されます。
各イメージ・ファイルの書き込み
BOOT.BINとpetalinux-sdimage.wicをKR260へ書き込みます。BOOT.BINの書き込みは下記ページを参考に実行して下さい。
WICイメージはbalenaEtcher等のツールを利用してSDメモリに書き込んで下さい。
動作確認
起動
4つのEthernet Port全てをネットワークに接続して起動して下さい。各ポートはDHCPでアドレスが付与されます。以下は私の環境で立ち上げた時の状態です。
5: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:0a:35:17:82:f7 brd ff:ff:ff:ff:ff:ff permaddr 00:0a:35:15:cc:94
inet 192.168.0.35/24 metric 10 brd 192.168.0.255 scope global dynamic eth0
valid_lft 3589sec preferred_lft 3589sec
inet6 fe80::20a:35ff:fe17:82f7/64 scope link proto kernel_ll
valid_lft forever preferred_lft forever
6: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:0a:35:15:cc:93 brd ff:ff:ff:ff:ff:ff permaddr 00:0a:35:15:cc:95
inet 192.168.0.36/24 metric 10 brd 192.168.0.255 scope global dynamic eth1
valid_lft 3589sec preferred_lft 3589sec
inet6 fe80::20a:35ff:fe15:cc93/64 scope link proto kernel_ll
valid_lft forever preferred_lft forever
8: eth2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 16:c7:9f:4a:57:26 brd ff:ff:ff:ff:ff:ff
inet 192.168.0.37/24 metric 10 brd 192.168.0.255 scope global dynamic eth2
valid_lft 3589sec preferred_lft 3589sec
inet6 fe80::e4fb:c9ff:fe6e:6c7d/64 scope link proto kernel_ll
valid_lft forever preferred_lft forever
9: eth3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 7a:7b:92:15:65:0b brd ff:ff:ff:ff:ff:ff
inet 192.168.0.38/24 metric 10 brd 192.168.0.255 scope global dynamic eth3
valid_lft 3589sec preferred_lft 3589sec
inet6 fe80::4c5c:8fff:fe18:2b25/64 scope link proto kernel_ll
valid_lft forever preferred_lft forever
各ポートの疎通確認はping6で行いました。
ping6 ff02::1%eth0
ping6 ff02::1%eth1
ping6 ff02::1%eth2
ping6 ff02::1%eth3
ネットワークケーブルを抜き差しすると以下の様なメッセージが出る所がイマイチですが、一応通信は出来ています。
Jul 30 02:11:45 xilinx-kr260-starterkit-xsct-20242 kernel: macb ff0d0000.ethernet eth0: unable to generate target frequency: 125000000 Hz
Ethernet Portの割り当て
各ポートとインターフェース名称の割り当ては以下の通りです。これはポートを正面から見た時を表しています。
| eth0 | eth3 |
| eth1 | eth2 |
eth0/eth1のリンク状態に応じてボード上のLED(UF1/UF2)も点灯します。
補足
GMII to RGMIIのDevicetree
今回利用したGMII to RGMIIのDevicetreeは以下の通りです。記述例なのでGEMに関しては一部記述を省略しています。最終的な形は生成されるsystem.dtbで確認して下さい。
gem2: ethernet@ff0d0000 {
compatible = "xlnx,zynqmp-gem", "cdns,gem";
status = "okay";
phy-mode = "gmii";
phy-handle = <&phy2>;
psu_ethernet_2_mdio: mdio {
#address-cells = <1>;
#size-cells = <0>;
enet2_gmii_to_rgmii: enet2_gmii_to_rgmii@8 {
compatible = "xlnx,gmii-to-rgmii-1.0";
phy-handle = <&phy2>;
reg = <8>;
};
phy2: ethernet-phy@2 {
ti,dp83867-rxctrl-strap-quirk;
ti,fifo-depth = <0x01>;
ti,tx-internal-delay = <0x04>;
ti,rx-internal-delay = <0x04>;
reg = <0x02>;
compatible = "ethernet-phy-id2000.a231";
};
};
};
ほとんどの記述は自動で生成されますが、外付けのPHYに関する部分は追記する必要があります。追記部分はsystem-user.dtsiで記述しています。
ビルドされたsystem.dtbを見ると解りますが、今回実装したGMII to RGMIIは2つともPHYアドレスがデフォルト値の8となっています。各インスタンスは異なるMDIOバスに接続されているので、同じアドレス値でも問題ありません。
おわりに
今回のネタはKR260を購入して最初に取り掛かった作業でした。しかし、KR260のPetaLinuxはそれまで利用していたZCU104とは異なる点があり、色々と難儀しました。
今回の作業の過程で調査した結果がこんな記事やあんな記事になっています。
ケーブルの抜き差し時の挙動やSDTを使ったビルドが不可能など、怪しい所がありますが、とりあえずこの状態で作業完了とします。
