LoginSignup
3
2

More than 3 years have passed since last update.

Ultra96/Ultra96-V2 向け Debian GNU/Linux で XRT(Xilinx Runtime) を動かす(ビルド編)

Last updated at Posted at 2020-03-26

注意(2021年5月12日追記)

この記事は XRT 2.6.0 を元に書いていて古い内容が含まれています。2021年5月現在、XRT のバージョンは 2.8.0 になっていて、これに対応した記事を新たに投稿しています。そちらを参照してください。

はじめに

筆者は Ultra96/Ultra96-V2(ZynqMP) 向けに Debian GNU/Linux を提供しています1。また、XRT(Xilinx Runtime) はXilinx社が提供する開発環境(Vitis)で開発したプログラムをプラットフォームで動かすための環境です2

本来なら MPSoC Edge Device 用の XRT は Xilinx が提供する Linux 環境(Petalinux) でしか動きませんが、XRT を Ultra96/Ultra96-V2 向け Debian GNU/Linux で動かすための手順を幾つかのパートに分けて説明します。

この記事では XRT を Ultra96/Ultra96-V2 向け Debian GNU/Linux 用にビルドする手順について説明します。

注意

この記事で紹介している Debian Package は Xilinx 社の公式なものではありません。

XRT のビルド

ビルド環境

XRT を ZynqMP-FPGA-Linux 向けにビルドするのは少し面倒です。XRT のビルドには Ubuntu や CentOS などの Linux ディストリビューションが必要です。ビルドには色々な開発ツールがインストールされていなければなりません。さらに Debian Package を作るためか、PC をホストにして ARM64 用にクロスコンパイルするのがとても面倒です。

そこで、 Ultra96-V2 に Ubuntu 18.04 を動かして、その上でセルフビルドします。Ultra96-V2 用の Ubuntu 18.04 は以下の URL で公開しています。

XRT のダウンロード

以下の URL より XRT のソースコードをダウンロードします。

fpga@ubuntu-fpga:~$ cd work
fpga@ubuntu-fpga:~/work$ git clone https://github.com/Xilinx/XRT
Cloning into 'XRT'...
remote: Enumerating objects: 30, done.
remote: Counting objects: 100% (30/30), done.
remote: Compressing objects: 100% (30/30), done.
remote: Total 43591 (delta 13), reused 7 (delta 0), pack-reused 43561
Receiving objects: 100% (43591/43591), 58.10 MiB | 2.57 MiB/s, done.
Resolving deltas: 100% (33849/33849), done.
Checking out files: 100% (1682/1682), done.
fpga@ubuntu-fpga:~/work$ cd XRT
fpga@ubuntu-fpga:~/work/XRT$

XRT を ZynqMP-FPGA-Linux 用にビルドするためにはいくつかファイルを修正します。ですので、https://github.com/Xilinx/XRT を直接 clone するよりも、fork したほうが良いでしょう。

ビルドに必要な Debian Package をインストール

ビルドに必要なパッケージをインストールします。幸い XRT には、ビルドに必要なパッケージをインストールするスクリプトが用意されています。

./src/runtime_src/tools/scripts/xrtdeps.sh を super user 権限で実行すると、apt プログラムによって足りない Debian Package がインストールされます。

fpga@ubuntu-fpga:~/work/XRT$ sudo ./src/runtime_src/tools/scripts/xrtdeps.sh
Installing packages...
Reading package lists... Done
Building dependency tree
Reading state information... Done
    :
(中略)
    :
The following packages were automatically installed and are no longer required:
  libgl2ps1.4 libibverbs1 liblept5 libnetcdf-c++4 libnl-route-3-200
  libopencv-flann-dev libopencv-flann3.2 libopencv-ml-dev libopencv-ml3.2
  libopencv-photo-dev libopencv-photo3.2 libopencv-shape-dev
  libopencv-shape3.2 libopencv-ts-dev libopencv-video-dev libopencv-video3.2
  libtcl8.6 libtesseract4 libtk8.6 libxss1
Use 'sudo apt autoremove' to remove them.
0 upgraded, 0 newly installed, 0 to remove and 26 not upgraded.

XRT の変更

XRT のビルド用ファイルにいくつかの修正をしますので、ブランチを作成します。現時点(2020年3月25日)でのmaster ブランチの最新のコミット(aac1e6871e95da47ccff4392d5849462bbd4ecad) をベースにします。

fpga@ubuntu-fpga:~/work/XRT$ git checkout aac1e6871e95da47ccff4392d5849462bbd4ecad 
fpga@ubuntu-fpga:~/work/XRT$ git checkout -b 2019.2_Ultra96
Switched to a new branch '2019.2_Ultra96'

このブランチに対して変更を加えていきます。具体的な変更内容は次章の「XRTの変更内容」を参照してください。

ここでは変更点をパッチファイルにして用意していますので、それをあてていきます。パッチファイルは以下の URL に用意しています。

パッケージファイル名を変更

fpga@ubuntu-fpga:~/work/XRT$ patch -p1 < ../files/00-xrt.patch 
patching file src/CMake/cpackLin.cmake
fpga@ubuntu-fpga:~/work/XRT$ git add --update
fpga@ubuntu-fpga:~/work/XRT$ git commit -m "[add] linux flavor name to built debian package name"
[2019.2_Ultra96 9ff0a408] [add] linux flavor name to built debian package name
 1 file changed, 1 insertion(+), 1 deletion(-)

依存する Debian Package のバージョンの上限を撤廃

fpga@ubuntu-fpga:~/work/XRT$ patch -p1 < ../files/01-xrt.patch 
patching file src/CMake/cpackLin.cmake
fpga@ubuntu-fpga:~/work/XRT$ git add --update
fpga@ubuntu-fpga:~/work/XRT$ git commit -m "[remove] upper limit of version of depend packages"
[2019.2_Ultra96 7e93ed34] [remove] upper limit of version of depend packages
 1 file changed, 1 insertion(+), 1 deletion(-)

XRT_EDGE_BUILD を追加

fpga@ubuntu-fpga:~/work/XRT$ patch -p1 < ../files/02-xrt.patch 
patching file build/build.sh
patching file src/CMake/config/dkms-zocl/dkms.conf.in
patching file src/CMake/config/edge/postinst.in
patching file src/CMake/config/edge/prerm.in
patching file src/CMake/cpackLin.cmake
patching file src/CMake/dkms-edge.cmake
patching file src/CMake/nativeLnx.cmake
patching file src/CMakeLists.txt
patching file src/runtime_src/CMakeLists.txt
patching file src/runtime_src/core/CMakeLists.txt
patching file src/CMake/cpackLin.cmake
fpga@ubuntu-fpga:~/work/XRT$ git add --update
fpga@ubuntu-fpga:~/work/XRT$ git add src/CMake/config/dkms-zocl
fpga@ubuntu-fpga:~/work/XRT$ git add src/CMake/config/edge
fpga@ubuntu-fpga:~/work/XRT$ git add src/CMake/dkms-edge.cmake
fpga@ubuntu-fpga:~/work/XRT$ git commit -m "[add] XRT_EDGE_BUILD for MPSoC Edge"
[2019.2_Ultra96 95287c93] [add] XRT_EDGE_BUILD for MPSoC Edge
 10 files changed, 376 insertions(+), 10 deletions(-)
 create mode 100644 src/CMake/config/dkms-zocl/dkms.conf.in
 create mode 100644 src/CMake/config/edge/postinst.in
 create mode 100644 src/CMake/config/edge/prerm.in
 create mode 100644 src/CMake/dkms-edge.cmake

10-zocl.rules を追加

fpga@ubuntu-fpga:~/work/XRT$ patch -p1 < ../files/03-xrt.patch 
patching file src/CMake/config/edge/postinst.in
patching file src/CMake/dkms-edge.cmake
patching file src/runtime_src/core/edge/drm/zocl/10-zocl.rules
fpga@ubuntu-fpga:~/work/XRT$ git add --update
fpga@ubuntu-fpga:~/work/XRT$ git add src/runtime_src/core/edge/drm/zocl/10-zocl.rules
fpga@ubuntu-fpga:~/work/XRT$ git commit -m "[add] 10-zocl.rules for udev"
[2019.2_Ultra96 04a8069d] [add] 10-zocl.rules for udev
 3 files changed, 3 insertions(+)
 create mode 100644 src/runtime_src/core/edge/drm/zocl/10-zocl.rules

ビルド

build ディレクトリに移動して、そこにある build.sh に "-edge" オプションをつけて実行することで、ビルドが開始されます。Ultra96/Ultra96-V2 だとけっこう時間がかかります。私の環境では1時間ほどかかりました。

fpga@ubuntu-fpga:~/work/XRT$ cd build/
fpga@ubuntu-fpga:~/work/XRT/build$ ./build.sh -edge
cmake -DRDI_CCACHE=0 -DCMAKE_BUILD_TYPE=Debug -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_TOOLCHAIN_FILE= ../../src
-- The C compiler identification is GNU 8.3.0
-- The CXX compiler identification is GNU 8.3.0
-- Check for working C compiler: /usr/bin/gcc-8
-- Check for working C compiler: /usr/bin/gcc-8 -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/g++-8
-- Check for working CXX compiler: /usr/bin/g++-8 -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Host system processor is aarch64
-- Target system processor is aarch64
    :
(後略)
    :
fpga@ubuntu-fpga:~/work/XRT/build$ 

ビルドが終了すると、build/Edge ディレクトリの下に Debian Package が出来ています。

fpga@ubuntu-fpga:~/work/XRT$ cd build/
fpga@ubuntu-fpga:~/work/XRT/build$ ls -1 Edge/xrt_*
Edge/xrt_202010.2.6.0_Ubuntu_18.04-arm64-xbtest.deb
Edge/xrt_202010.2.6.0_Ubuntu_18.04-arm64-xbtest.tar.gz
Edge/xrt_202010.2.6.0_Ubuntu_18.04-arm64-xrt.deb
Edge/xrt_202010.2.6.0_Ubuntu_18.04-arm64-xrt.tar.gz

このうち Ultra96/Ultra96-V2 に必要な Debian Package は、Edge/xrt_202010.2.6.0_Ubuntu_18.04-arm64-xrt.deb です。

XRT の変更内容

この章では、オリジナルの XRT に対して、私が独自に変更した点について説明します。

パッケージファイル名を変更

オリジナルの XRT では、ビルドした Debian Package の名前は xrt_202010.2.6.0_18.04-arm64-xrt.deb になりますが、Ubuntu 用のパッケージであることを明示するためにxrt_202010.2.6.0_Ubuntu_18.04-arm64-xrt.deb にします。

ZynqMP-FPGA-XRT/files/00-xrt.patch
diff --git a/src/CMake/cpackLin.cmake b/src/CMake/cpackLin.cmake
index 4f45f97a..9f6eebe4 100644
--- a/src/CMake/cpackLin.cmake
+++ b/src/CMake/cpackLin.cmake
@@ -79,7 +79,7 @@ else ()
   SET (CPACK_GENERATOR "TGZ")
 endif()

-SET(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}_${XRT_VERSION_RELEASE}.${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}_${CPACK_REL_VER}-${CPACK_ARCH}")
+SET(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}_${XRT_VERSION_RELEASE}.${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}_${LINUX_FLAVOR}_${CPACK_REL_VER}-${CPACK_ARCH}")

 message("-- ${CMAKE_BUILD_TYPE} ${PACKAGE_KIND} package")


依存する Debian Package のバージョンの上限を撤廃

オリジナルでは、ビルドした Debian Package が依存する Package のうち、libboost-dev、libboost-filesystem-dev、libc6 のバージョンに上限が設定されています。これだと、インストールするディストリビューションの制約が強すぎてインストールに失敗することがあります。例えば、この Debian Package を Debian10 にインストールを試みると失敗します。

そこで、後で問題になるかもしれませんが、次のように cpackLin.cmake を修正してバージョンの上限を撤廃します。

ZynqMP-FPGA-XRT/files/01-xrt.patch
diff --git a/src/CMake/cpackLin.cmake b/src/CMake/cpackLin.cmake
index 9f6eebe4..5b056580 100644
--- a/src/CMake/cpackLin.cmake
+++ b/src/CMake/cpackLin.cmake
@@ -49,7 +49,7 @@ if (${LINUX_FLAVOR} MATCHES "^(Ubuntu|Debian)")
   SET(CPACK_DEBIAN_PACKAGE_SHLIBDEPS "OFF")
   SET(CPACK_DEBIAN_AWS_PACKAGE_DEPENDS "xrt (>= ${XRT_VERSION_MAJOR}.${XRT_VERSION_MINOR}.${XRT_VERSION_PATCH})")
   SET(CPACK_DEBIAN_XBTEST_PACKAGE_DEPENDS "xrt (>= ${XRT_VERSION_MAJOR}.${XRT_VERSION_MINOR}.${XRT_VERSION_PATCH}), libjson-glib-dev")
-  SET(CPACK_DEBIAN_XRT_PACKAGE_DEPENDS "ocl-icd-opencl-dev (>= 2.2.0), libboost-dev (>= ${Boost_VER_STR}), libboost-dev (<< ${Boost_VER_STR_ONEGREATER}), libboost-filesystem-dev (>=${Boost_VER_STR}), libboost-filesystem-dev (<<${Boost_VER_STR_ONEGREATER}), uuid-dev (>= 2.27.1), dkms (>= 2.2.0), libprotoc-dev (>=2.6.1), libssl-dev (>=1.0.2), protobuf-compiler (>=2.6.1), libncurses5-dev (>=6.0), lsb-release, libxml2-dev (>=2.9.1), libyaml-dev (>= 0.1.6), libc6 (>= ${GLIBC_VERSION}), libc6 (<< ${GLIBC_VERSION_ONEGREATER}), python (>= 2.7), python-pip, libudev-dev ")
+  SET(CPACK_DEBIAN_XRT_PACKAGE_DEPENDS "ocl-icd-opencl-dev (>= 2.2.0), libboost-dev (>= ${Boost_VER_STR}), libboost-filesystem-dev (>=${Boost_VER_STR}), uuid-dev (>= 2.27.1), dkms (>= 2.2.0), libprotoc-dev (>=2.6.1), libssl-dev (>=1.0.2), protobuf-compiler (>=2.6.1), libncurses5-dev (>=6.0), lsb-release, libxml2-dev (>=2.9.1), libyaml-dev (>= 0.1.6), libc6 (>= ${GLIBC_VERSION}), python (>= 2.7), python-pip, libudev-dev ")

 elseif (${LINUX_FLAVOR} MATCHES "^(RedHat|CentOS|Amazon)")
   execute_process(

XRT_EDGE_BUILD を追加

オリジナルではホストプロセッサとターゲットプロセッサが同じ場合に XRT_NATIVE_BUILD という変数が "yes" にセットされます。 そして、XRT_NATIVE_BUILD が "yes" の時(ホストプロセッサとターゲットプロセッサが同じ時)に src/runtime_src/core/pcie が、"no" の時(ホストプロセッサとターゲットプロセッサが異なる時)に src/runtime_src/core/edge がビルドされるように src/runtime_src/core/CMakeLists.txt が定義されています。

src/runtime_src/core/CMakeLists.txt
include_directories(
  ${CMAKE_CURRENT_SOURCE_DIR}
  )
add_subdirectory(include)
add_subdirectory(common)
 if (${XRT_NATIVE_BUILD} STREQUAL "yes")
   add_subdirectory(pcie)
   add_subdirectory(tools)
 else()
   add_subdirectory(edge)
 endif()

また、XRT_NATIVE_BUILD が "yes" の時(ホストプロセッサとターゲットプロセッサが同じ時)にインクルードされる src/CMake/nativeLnx.cmake には、次のようにホスト用のドライバをビルド&インストールするようになっています。

src/CMake/nativeLnx.cmakext
    :
    (前略)
    :
include (CMake/dkms.cmake)
include (CMake/dkms-aws.cmake)
include (CMake/dkms-azure.cmake)
include (CMake/dkms-container.cmake)
    :
    (後略)

Ultra96-V2 に Ubuntu 18.04 を動かしてその上でセルフビルドする場合は、ホストプロセッサとターゲットプロセッサが同じ arm64 になります。このままだと、edge 用のではなく pcie 用にビルドされてしまいます。

そこで、次のように src/CMakfile.txt に XRT_EDGE_BUILD 変数を追加します。

src/CMakeLists.txt
    :
    (前略)
    :   
set(XRT_EDGE_BUILD "no")
if (XRT_NATIVE_BUILD STREQUAL "no")
  set(XRT_EDGE_BUILD "no")
endif()
if (DEFINED ENV{XRT_EDGE_BUILD})
  set(XRT_EDGE_BUILD $ENV{XRT_EDGE_BUILD})
endif():
    :
    (後略)

そして XRT_EDGE_BUILD が "yes" の場合は edge 用のビルドを行うように、それぞれのファイルを変更します。

src/runtime_src/core/CMakeLists.txt
include_directories(
  ${CMAKE_CURRENT_SOURCE_DIR}
  )
add_subdirectory(include)
add_subdirectory(common)
 if (${XRT_EDGE_BUILD} STREQUAL "yes")
   add_subdirectory(edge)
 else()
   add_subdirectory(pcie)
   add_subdirectory(tools)
 endif()

src/CMake/nativeLnx.cmakext
    :
    (前略)
    :
if (${XRT_EDGE_BUILD} STREQUAL "yes")
  include (CMake/dkms-edge.cmake)
else()
  include (CMake/dkms.cmake)
  include (CMake/dkms-aws.cmake)
  include (CMake/dkms-azure.cmake)
  include (CMake/dkms-container.cmake)
endif()
    :
    (後略)

そして、edge 用のドライバ(zocl) を Debian パッケージに追加してインストール時に dkms を使ってビルドするように以下のファイルを追加します。

  • src/CMake/dkms-edge.cmake
  • src/CMake/config/dkms-zocl/dkms.conf.in
  • src/CMake/config/edge/postinst.in
  • src/CMake/config/edge/prerm.in

また、XRT_NATIVE_BUILD が "yes" の時(ホストプロセッサとターゲットプロセッサが同じ時)、コンパイルのオプションに "-Wall" と -"Werror" が追加されるような設定が src/runtime_src/CMakeLists.txt にあります。

src/runtime_src/CMakeLists.txt
    :
    (前略)
    :
# TODO CL_TARGET_OPENCL_VERSION is not defined..
if (${XRT_NATIVE_BUILD} STREQUAL "yes")
  add_compile_options("-Wall" "-Werror")
endif()
    :
    (後略)

"-Werror" オプションがあると src/runtime_src/core/edge 以下のビルド時にエラーが出てコンパイルに失敗します。そこで XRT_EDGE_BUILD が "yes" の時はコンパイルオプションに "-Wall" と "-Werror" が追加されないように src/runtime_src/CMakeLists.txt を修正します。

src/runtime_src/CMakeLists.txt
    :
    (前略)
    :
# TODO CL_TARGET_OPENCL_VERSION is not defined..
if (${XRT_EDGE_BUILD} STREQUAL "no")
  add_compile_options("-Wall" "-Werror")
endif() :
    (後略)

最後に build/build.sh を修正して、ホストプロセッサが arm64 かつ "-edge" オプションが追加された場合は XRT_EDGE_BUILD が "yes" になるように修正します。

build/build/sh
    :
    (前略)
    :
f [[ $CPU == "aarch64" ]] && [[ $edge == 1 ]]; then
  mkdir -p $edge_dir
  cd $edge_dir
  if [[ $nocmake == 0 ]]; then
    echo "$CMAKE -DRDI_CCACHE=$ccache -DCMAKE_BUILD_TYPE=Release -DCMAKE_EXPORT\\
_COMPILE_COMMANDS=ON ../../src"
    time env XRT_EDGE_BUILD=yes $CMAKE -DRDI_CCACHE=$ccache -DCMAKE_BUILD_TYPE=\\
Release -DCMAKE_EXPORT_COMPILE_COMMANDS=ON ../../src
  fi
  if [[ $docs == 1 ]]; then
    echo "make xrt_docs"
    make xrt_docs
  else
    echo "make -j $jcore $verbose DESTDIR=$PWD"
    time make -j $jcore $verbose DESTDIR=$PWD
    time ctest --output-on-failure
    time make package
  fi
  cd $BUILDDIR
fi
    :
    (後略)

10-zocl.rules を追加

zocl がユーザーから書き込めるようにパーミッションを変更します。具体的には /etc/udev/rule.d に次のような 10-zocl.rules を追加します。

/etc/udev/rule.d/10-zocl.rules
KERNEL=="renderD*",MODE="0666"

Debian Package をインストールした際に 10-zocl.rules が /etc/udev/rule.d にインストールされるようにします。

ZynqMP-FPGA-XRT/files/03-xrt.patch
diff --git a/src/CMake/config/edge/postinst.in b/src/CMake/config/edge/postinst.in
index 22136c09..b85a1032 100644
--- a/src/CMake/config/edge/postinst.in
+++ b/src/CMake/config/edge/postinst.in
@@ -48,6 +48,7 @@ echo "Invoking DKMS common.postinst for xrt"
 /usr/lib/dkms/common.postinst xrt @XRT_VERSION_STRING@ "" "" $2
 if [ $? -eq 0 ]; then
     echo "Finished DKMS common.postinst"
+    install -m 644 /usr/src/xrt-@XRT_VERSION_STRING@/driver/edge/drm/zocl/10-zocl.rules /etc/udev/rules.d
     echo "Loading new XRT Linux kernel modules"
     udevadm control --reload-rules
     modprobe zocl
diff --git a/src/CMake/dkms-edge.cmake b/src/CMake/dkms-edge.cmake
index d1d39750..61664945 100644
--- a/src/CMake/dkms-edge.cmake
+++ b/src/CMake/dkms-edge.cmake
@@ -38,6 +38,7 @@ SET (XRT_DKMS_CORE_COMMON_DRV    ${XRT_DKMS_CORE_DIR}/common/drv)
 SET (XRT_DKMS_DRIVER_SRCS
   edge/drm/zocl/LICENSE
   edge/drm/zocl/Makefile
+  edge/drm/zocl/10-zocl.rules
   edge/drm/zocl/sched_exec.c
   edge/drm/zocl/sched_exec.h
   edge/drm/zocl/zocl_bo.c
diff --git a/src/runtime_src/core/edge/drm/zocl/10-zocl.rules b/src/runtime_src/core/edge/drm/zocl/10-zocl.rules
new file mode 100644
index 00000000..11ed38e1
--- /dev/null
+++ b/src/runtime_src/core/edge/drm/zocl/10-zocl.rules
@@ -0,0 +1 @@
+KERNEL=="renderD*",MODE="0666"

参考

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2