参照[Xilinx FPGA_as_a_Service 概述](https://feishujun.blog.csdn.net/article/details/107910624) 的安装流程,本篇博客对Xilinx Base Runtime脚本进行分析。第一个脚本是在宿主机中执行的host_setup.sh。脚本的主要用途是按照XRT和刷新Shell。
看其中的usage函数,列出了脚本参数的使用,如下:
./host_setup.sh --version <version>
./host_setup.sh -v <version>
<version> : 2018.3 / 2019.1 / 2019.2 / 2020.1
--skip-xrt-install : skip install XRT
--skip-shell-flash : skip flash Shell
--install-docker : install docker service
比如Install 2019.2 XRT and flash Shell的命令如下:./host_setup.sh -v 2019.2
根据从conf/spec.txt中提取出相关包
VERSION="2020.1"
for OSVERSION in "centos" "ubuntu-16.04" "ubuntu-18.04"; do
for PLATFORM in "alveo-u200" "alveo-u250" "alveo-u280" "alveo-u50" ; do
echo "${PLATFORM}_${VERSION}_${OSVERSION}"
get_packages
echo "$XRT_PACKAGE, $DSA, $SHELL_PACKAGE, $TIMESTAMP, $PACKAGE_NAME, $PACKAGE_VERSION, $XRT_VERSION, $CMC_PACKAGE, $SC_PACKAGE, $SHELL_TARBALL"
done
done
exit 0
echo “KaTeX parse error: Expected group after '_' at position 11: {PLATFORM}_̲{VERSION}_${OSVERSION}” 打印的输出如下所示:
awk -F’:’ 以冒号为分隔符 awk -F’:’ ‘{print $2}’ —> XRT_PACKAGE=xrt_201830.2.1.1794_16.04-xrt.deb;… | awk -F’;’ ‘{print $1}’ —> XRT_PACKAGE=xrt_201830.2.1.1794_16.04-xrt.deb | awk -F= ‘{print $2}’ —> xrt_201830.2.1.1794_16.04-xrt.deb
get_packages() {
COMB="${PLATFORM}_${VERSION}_${OSVERSION}"
if grep -q $COMB "conf/spec.txt"; then # 从conf/spec.txt中找出相关包
XRT_PACKAGE=`grep ^$COMB: conf/spec.txt | awk -F':' '{print $2}' | awk -F';' '{print $1}' | awk -F= '{print $2}'`
SHELL_PACKAGE=`grep ^$COMB: conf/spec.txt | awk -F':' '{print $2}' | awk -F';' '{print $2}' | awk -F= '{print $2}'`
DSA=`grep ^$COMB: conf/spec.txt | awk -F':' '{print $2}' | awk -F';' '{print $3}' | awk -F= '{print $2}'`
TIMESTAMP=`grep ^$COMB: conf/spec.txt | awk -F':' '{print $2}' | awk -F';' '{print $4}' | awk -F= '{print $2}'`
PACKAGE_NAME=`grep ^$COMB: conf/spec.txt | awk -F':' '{print $2}' | awk -F';' '{print $6}' | awk -F= '{print $2}'`
PACKAGE_VERSION=`grep ^$COMB: conf/spec.txt | awk -F':' '{print $2}' | awk -F';' '{print $7}' | awk -F= '{print $2}'`
XRT_VERSION=`grep ^$COMB: conf/spec.txt | awk -F':' '{print $2}' | awk -F';' '{print $8}' | awk -F= '{print $2}'`
if [[ "$PLATFORM" == "alveo-u50" ]]; then
CMC_PACKAGE=`grep ^$COMB: conf/spec.txt | awk -F':' '{print $2}' | awk -F';' '{print $9}' | awk -F= '{print $2}'`
SC_PACKAGE=`grep ^$COMB: conf/spec.txt | awk -F':' '{print $2}' | awk -F';' '{print $10}' | awk -F= '{print $2}'`
SHELL_TARBALL=`grep ^$COMB: conf/spec.txt | awk -F':' '{print $2}' | awk -F';' '{print $11}' | awk -F= '{print $2}'`
fi
else
usage
echo ""
list
exit 1
fi
}
grep -q用于if逻辑判断 -q 参数,本意是 Quiet; do not write anything to standard output. Exit immediately with zero status if any match is found, even if an error was detected. 中文意思为,安静模式,不打印任何标准输出。如果有匹配的内容则立即返回状态值0。
例子:
# cat a.txt
nihao
nihaooo
hello
# if grep -q hello a.txt ; then echo yes;else echo no; fi
yes
# if grep -q word a.txt; then echo yes; else echo no; fi
no
if [[ $EUID -ne 0 ]]; then
echo "This script must be run as root"
exit 1
fi
read的用法参见:linux脚本read的用法
XRT=1
SHELL=1
PLATFORM="alveo-u200"
VERSION="NONE"
INSTALL_DOCKER=0
notice_disclaimer
confirm
notice_disclaimer() {
cat doc/notice_disclaimer.txt
}
confirm() { # 用于向用户提示确认
# call with a prompt string or use a default
read -r -p "${1:-Are you sure you wish to proceed? [y/n]:} " response
case "$response" in
[yY][eE][sS]|[yY])
true
;;
*)
exit 1
;;
esac
}
判别输入参数
while true
do
case "$1" in
--skip-xrt-install ) XRT=0 ; shift 1 ;;
--skip-shell-flash ) SHELL=0 ; shift 1 ;;
-v|--version ) VERSION="$2" ; shift 2 ;;
--install-docker ) INSTALL_DOCKER=1 ; shift 1 ;;
-h|--help ) usage ; exit 1 ;;
"" ) break ;;
*) echo "invalid option: $1"; usage; exit 1 ;;
esac
done
if [ $? != 0 ] ; then echo "Failed parsing options." >&2 ; usage; exit 1 ; fi
寻找操作系统的版本 ubuntu需要特殊处理
OSVERSION=`grep '^ID=' /etc/os-release | awk -F= '{print $2}'`
OSVERSION=`echo $OSVERSION | tr -d '"'`
if [[ "$OSVERSION" == "ubuntu" ]]; then
VERSION_ID=`grep '^VERSION_ID=' /etc/os-release | awk -F= '{print $2}'`
VERSION_ID=`echo $VERSION_ID | tr -d '"'`
OSVERSION="$OSVERSION-$VERSION_ID"
fi
测试系统是否安装了wget
wget --help > /dev/null
if [ $? != 0 ] ; then
if [[ "$OSVERSION" == "ubuntu-16.04" ]] || [[ "$OSVERSION" == "ubuntu-18.04" ]]; then
apt-get install -y wget
elif [[ "$OSVERSION" == "centos" ]]; then
yum install -y wget
fi
fi
处理path
echo $PATH | grep -q "/your/search/path"
if [[ $? != 0 ]]; then
export PATH=$PATH:"/usr/local/sbin"
fi
echo $PATH | grep -q "/usr/sbin"
if [[ $? != 0 ]]; then
export PATH=$PATH:"/usr/sbin"
fi
echo $PATH | grep -q "/sbin"
if [[ $? != 0 ]]; then
export PATH=$PATH:"/sbin"
fi
调用docker安装脚本
if [[ "$INSTALL_DOCKER" == 1 ]]; then
./utilities/docker_install.sh
fi
安装xrt和shell包都需要从xilinx官网上用crul下载响应的包到/tmp目录下。
安装xrt
if [[ "$XRT" == 0 && "$SHELL" == 0 ]] ; then echo "Please do NOT skip both XRT installation and card flashing." >&2 ; usage; exit 1 ; fi
if [[ "$XRT" == 1 ]]; then
get_packages
install_xrt
fi
install_xrt() {
echo "Download XRT installation package"
wget -cO - "https://www.xilinx.com/bin/public/openDownload?filename=$XRT_PACKAGE" > /tmp/$XRT_PACKAGE
echo "Install XRT"
if [[ "$OSVERSION" == "ubuntu-16.04" ]] || [[ "$OSVERSION" == "ubuntu-18.04" ]]; then
apt-get install --reinstall /tmp/$XRT_PACKAGE
elif [[ "$OSVERSION" == "centos" ]]; then
XRT_VERSION_INSTALLED=`yum info installed xrt 2> /dev/null | grep Version`
if [[ $? == 0 ]]; then
XRT_VERSION_INSTALLED=`echo "$XRT_VERSION_INSTALLED" | cut -d ":" -f2| cut -d " " -f2`
XRT_VERSION_INSTALLED=`echo "${XRT_VERSION_INSTALLED/-/.}"`
vercomp $XRT_VERSION_INSTALLED $XRT_VERSION
case $? in
0) yum reinstall /tmp/$XRT_PACKAGE;; # 再次安装
1) yum downgrade /tmp/$XRT_PACKAGE;; # 降级
2) yum install /tmp/$XRT_PACKAGE;; # 升级
esac
else
yum install epel-release
yum install /tmp/$XRT_PACKAGE
fi
fi
rm /tmp/$XRT_PACKAGE
}
刷新板卡和shell
if [[ "$SHELL" == 1 ]]; then
lspci > /dev/null
if [ $? != 0 ] ; then
if [[ "$OSVERSION" == "ubuntu-16.04" ]] || [[ "$OSVERSION" == "ubuntu-18.04" ]]; then
apt-get install -y pciutils
elif [[ "$OSVERSION" == "centos" ]]; then
yum install -y pciutils
fi
fi
U200=0
U250=0
U280=0
U50=0
for DEVICE_ID in $(lspci -d 10ee: | grep " Processing accelerators" | grep "Xilinx" | grep ".0 " | cut -d" " -f7); do
if [[ "$DEVICE_ID" == "5000" ]]; then
U200=$((U200 + 1))
elif [[ "$DEVICE_ID" == "5004" ]]; then
U250=$((U250 + 1))
elif [[ "$DEVICE_ID" == "5008" ]]; then
U280=$((U280 + 1))
elif [[ "$DEVICE_ID" == "5020" ]]; then
U50=$((U50 + 1))
fi
done
if [[ "$U200" == 0 && "$U250" == 0 && "$U280" == 0 ]]; then
echo "[WARNING] No FPGA Board Detected. Skip shell flash."
exit 0;
fi
if [[ "$U200" != 0 ]]; then
echo "You have $U200 U200 card(s)."
PLATFORM="alveo-u200"
flash_cards
fi
if [[ "$U250" != 0 ]]; then
echo "You have $U250 U250 card(s)."
PLATFORM="alveo-u250"
flash_card
fi
if [[ "$U280" != 0 ]]; then
echo "You have $U280 U280 card(s)."
PLATFORM="alveo-u280"
flash_card
fi
if [[ "$U50" != 0 ]]; then
echo "You have $U50 U50 card(s)."
PLATFORM="alveo-u50"
flash_cards_u50
fi
fi
刷新FPGA板卡
check_packages() {
if [[ "$OSVERSION" == "ubuntu-16.04" ]] || [[ "$OSVERSION" == "ubuntu-18.04" ]]; then
PACKAGE_INSTALL_INFO=`apt list --installed 2>/dev/null | grep "$PACKAGE_NAME" | grep "$PACKAGE_VERSION"`
elif [[ "$OSVERSION" == "centos" ]]; then
PACKAGE_INSTALL_INFO=`yum list installed 2>/dev/null | grep "$PACKAGE_NAME" | grep "$PACKAGE_VERSION"`
fi
}
flash_cards() {
get_packages
check_packages
if [[ $? != 0 ]]; then
echo "Download Shell package"
wget -cO - "https://www.xilinx.com/bin/public/openDownload?filename=$SHELL_PACKAGE" > /tmp/$SHELL_PACKAGE
echo "Install Shell"
if [[ "$OSVERSION" == "ubuntu-16.04" ]] || [[ "$OSVERSION" == "ubuntu-18.04" ]]; then
apt-get install /tmp/$SHELL_PACKAGE
elif [[ "$OSVERSION" == "centos" ]]; then
yum remove -y $PACKAGE_NAME
yum install /tmp/$SHELL_PACKAGE
fi
rm /tmp/$SHELL_PACKAGE
fi
if [[ "$VERSION" == "2018.3" ]]; then
/opt/xilinx/xrt/bin/xbutil flash -a $DSA $TIMESTAMP
elif [[ "$VERSION" == "2019.1" ]]; then
/opt/xilinx/xrt/bin/xbmgmt flash -a $DSA $TIMESTAMP
elif [[ "$VERSION" == "2019.2" || "$VERSION" == "2020.1" ]]; then
/opt/xilinx/xrt/bin/xbmgmt flash --update --shell $DSA
fi
}
flash_cards_u50() {
get_packages
check_packages
if [[ $? != 0 ]]; then
echo "Download Shell package"
wget -cO - "https://www.xilinx.com/bin/public/openDownload?filename=$SHELL_TARBALL" > /tmp/$SHELL_TARBALL
# Unpack tarball
tar -zxvf $SHELL_TARBALL -C /tmp
echo "Install Shell"
if [[ "$OSVERSION" == "ubuntu-16.04" ]] || [[ "$OSVERSION" == "ubuntu-18.04" ]]; then
apt-get install --reinstall /tmp/$CMC_PACKAGE
apt-get install --reinstall /tmp/$SC_PACKAGE
apt-get install --reinstall /tmp/$SHELL_PACKAGE
elif [[ "$OSVERSION" == "centos" ]]; then
yum remove -y xilinx-cmc-u50 xilinx-sc-fw-u50
yum install /tmp/$CMC_PACKAGE
yum install /tmp/$SC_PACKAGE
yum install /tmp/$SHELL_PACKAGE
fi
rm /tmp/$SHELL_PACKAGE
fi
/opt/xilinx/xrt/bin/xbmgmt flash --update --shell $DSA
}
从整个流程可以看得出来,host_setup.sh比手动安装xrt和部署环境方便多了。