1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

UltraZed/Ultra96/Ultra96-V2/KV260/KR260 向け Debian(12.4) GNU/Linux ブートイメージの提供

Last updated at Posted at 2024-01-15

はじめに

この記事の目的

この記事は、UltraZed/Ultra96/Ultra96-V2/KV260/KR260 用に Boot Loader(U-Boot等)、Linux Kernel、Debian12.4(bookworm) Root File System を以下の URL に用意したので、そのインストール方法を説明します。Boot Loader や Linux Kernel のビルドが面倒くさいという方はどうぞ。

注意事項

この記事で紹介しているリポジトリで提供されている Linux カーネルと Debian12 ルートファイルシステムは、AMD社(旧Xilinx社)の公式のものではありません。筆者が道楽で自分好みに魔改造しています。使用する際にはこの点に留意して自己責任でお願いします。

注記

これまで 旧記事 で紹介していた https://github.com/ikwzm/ZynqMP-FPGA-Linux は現在更新を停止しています。その理由は、このリポジトリには大量のバイナリファイルが含まれており保守が困難になっているためです。今後はディストリビューションごとに個別のリポジトリを提供することにしました。

特徴

対応ボード

  • UltraZed-EG-IOCC : Xilinx Zynq UltraScale+ MPSoC Starter Kit by Avnet.
  • Ultra96 : Xilinx Zynq UltraScale+ MPSoC development board based on the Linaro 96Boards specification.
  • Ultra96-V2 : updates and refreshes the Ultra96 product that was released in 2018.
  • KV260 : Kria KV260 Vision AI Startar Kit.
  • KR260 : Kria KR260 Robotics Startar Kit.

ブートローダー

  • FSBL(First Stage Boot Loader for ZynqMP)
  • PMU Firmware(Platform Management Unit Firmware)
  • BL31(ARM Trusted Firmware Boot Loader stage 3-1)
  • U-Boot xilinx-v2019.2 (customized)

Linux Kernel

Debian12.4(bookwork) Root File System

インストール

ダウンロード

github から次のようにダウンロードしてください。

shell$ wget https://github.com/ikwzm/ZynqMP-FPGA-Debian12/archive/refs/tags/v4.1.0.tar.gz
shell$ tar xfz v4.1.0.tar.gz
shell$ cd ZynqMP-FPGA-Debian12-4.1.0

ファイルの説明

  • target/Kv260/boot/
    • boot.scr : U-Boot script file
    • uEnv.txt : U-Boot environment variables for linux boot
    • devicetree-6.1.70-zynqmp-fpga-generic-kv260-revB.dtb : Linux Device Tree Blob
    • devicetree-6.1.70-zynqmp-fpga-generic-kv260-revB.dts : Linux Device Tree Source
  • target/Kr260/boot/
    • boot.scr : U-Boot script file
    • uEnv.txt : U-Boot environment variables for linux boot
    • devicetree-6.1.70-zynqmp-fpga-generic-kr260-revB.dtb : Linux Device Tree Blob
    • devicetree-6.1.70-zynqmp-fpga-generic-kr260-revB.dts : Linux Device Tree Source
  • target/Ultra96/boot/
    • boot.bin : Stage 1 Boot Loader
    • uEnv.txt : U-Boot environment variables for linux boot
    • devicetree-6.1.70-zynqmp-fpga-generic-ultra96.dtb : Linux Device Tree Blob
    • devicetree-6.1.70-zynqmp-fpga-generic-ultra96.dts : Linux Device Tree Blob
  • target/Ultra96-V2/boot/
    • boot.bin : Stage 1 Boot Loader
    • uEnv.txt : U-Boot environment variables for linux boot
    • devicetree-6.1.70-zynqmp-fpga-generic-ultra96v2.dtb : Linux Device Tree Blob
    • devicetree-6.1.70-zynqmp-fpga-generic-ultra96v2.dts : Linux Device Tree Blob
  • target/UltraZed-EG-IOCC/boot/
    • boot.bin : Stage 1 Boot Loader
    • uEnv.txt : U-Boot environment variables for linux boot
    • devicetree-6.1.70-zynqmp-fpga-generic-uz3eg-iocc.dtb : Linux Device Tree Blob
    • devicetree-6.1.70-zynqmp-fpga-generic-uz3eg-iocc.dts : Linux Device Tree Source
  • files/
    • vmlinuz-6.1.70-zynqmp-fpga-generic-2 : Linux Kernel Image
    • config-6.1.70-zynqmp-fpga-generic-2 : Linux Kernel Configuration File
  • debian12-rootfs-vanilla.tgz.files/ : Debian12 Root File System
    • x00 .. x09 : (splited files)
  • debian/
    • linux-image-6.1.70-zynqmp-fpga-generic_6.1.70-zynqmp-fpga-generic-2_arm64.deb : Linux Image Package
    • linux-headers-6.1.70-zynqmp-fpga-generic_6.1.70-zynqmp-fpga-generic-2_arm64.deb : Linux Headers Package
    • fclkcfg-6.1.70-zynqmp-fpga-generic_1.7.3-1_arm64.deb : fclkcfg(1.7.3) Device Driver and Services Package
    • u-dma-buf-6.1.70-zynqmp-fpga-generic_4.5.2-0_arm64.deb : u-dma-buf(4.5.2) Device Driver and Services Package

SD-Card のフォーマット

  1. SD-Card のパーティション1を VFAT File System でファイルシステムを作ります。
  2. SD-Card のパーティション2を ext4 File System でファイルシステムを作ります。

Linux での SD-Card のフォーマット方法は次の URL を参照してください。

SD-Card への書き込み

0. SD-Card のマウント

SD-Card のパーティション1(ブートパーティション)とパーティション2(ルートパーティション)を読み書き出来るようにマウントします。
この例では、ブートパーティションを /mnt/usb1 に、ルートパーティションを /mnt/usb2 にそれぞれマウントしています。

shell# mount /dev/sdc1 /mnt/usb1
shell# mount /dev/sdc2 /mnt/usb2

1. ブートパーティションの作成

KV260 の場合

SD-Card のブートパーティション(例では/mnt/usb1)に target/Kv260/boot/ 下のファイルと Linux Kernel Image をコピーします。

shell# cp target/Kv260/boot/*                                  /mnt/usb1
shell# gzip -d -c files/vmlinuz-6.1.70-zynqmp-fpga-generic-2 > /mnt/usb1/image-6.1.70-zynqmp-fpga-generic
KR260 の場合

SD-Card のブートパーティション(例では/mnt/usb1)に target/Kr260/boot/ 下のファイルと Linux Kernel Image をコピーします。

shell# cp target/Kr260/boot/*                                  /mnt/usb1
shell# gzip -d -c files/vmlinuz-6.1.70-zynqmp-fpga-generic-2 > /mnt/usb1/image-6.1.70-zynqmp-fpga-generic
Ultra96 の場合

SD-Card のブートパーティション(例では/mnt/usb1)に target/Ultra96/boot/ 下のファイルと Linux Kernel Image をコピーします。

shell# cp target/Ultra96/boot/*                                /mnt/usb1
shell# gzip -d -c files/vmlinuz-6.1.70-zynqmp-fpga-generic-2 > /mnt/usb1/image-6.1.70-zynqmp-fpga-generic
Ultra96-V2 の場合

SD-Card のブートパーティション(例では/mnt/usb1)に target/Ultra96-V2/boot/ 下のファイルと Linux Kernel Image をコピーします。

shell# cp target/Ultra96-V2/boot/*                             /mnt/usb1
shell# gzip -d -c files/vmlinuz-6.1.70-zynqmp-fpga-generic-2 > /mnt/usb1/image-6.1.70-zynqmp-fpga-generic
UltraZed の場合

SD-Card のブートパーティション(例では/mnt/usb1)に target/UltraZed-EG-IOCC/boot/ 下のファイルと Linux Kernel Image をコピーします。

shell# cp target/UltraZed-EG-IOCC/boot/*                       /mnt/usb1
shell# gzip -d -c files/vmlinuz-6.1.70-zynqmp-fpga-generic-2 > /mnt/usb1/image-6.1.70-zynqmp-fpga-generic

2. ルートパーティションの作成

SD-Card のルートパーティション(例では/mnt/usb2)に debian12-rootfs-vanilla.tgz.files の中身を展開します。展開したルートファイルシステムの home/fpga にデバイスドライバの Debian パッケージをあらかじめコピーしておくと良いでしょう。後から network 経由でコピーしてもかまいません。

shell# cat debian12-rootfs-vanilla.tgz.files/* | tar xfz - -C /mnt/usb2
shell# mkdir                                                  /mnt/usb2/home/fpga/debian
shell# cp debian/*                                            /mnt/usb2/home/fpga/debian

3. ブートパーティションが見えるように fstab を設定

ブートパーティションを Linux 側から常時見えるようにしておくと便利です。その場合は、あらかじめ fstab にブートパーティションをマウントするように設定しておくと良いでしょう。すでに fstab には configfs のマウントが設定されているので注意してください。

Ultra96/Ultra96-V2 のブートパーティションは /dev/mmcblk0p1 です。

shell# mkdir /mnt/usb2/mnt/boot
shell# cat <<EOT >> /mnt/usb2/etc/fstab
/dev/mmcblk0p1	/mnt/boot	auto	defaults	0	0
EOT

KV260/UltraZed のブートパーティションは /dev/mmcblk1p1 です。

shell# mkdir /mnt/usb2/mnt/boot
shell# cat <<EOT >> /mnt/usb2/etc/fstab
/dev/mmcblk1p1	/mnt/boot	auto	defaults	0	0
EOT

KR260 のブートパーティションは /dev/sda1 です。

shell# mkdir /mnt/usb2/mnt/boot
shell# cat <<EOT >> /mnt/usb2/etc/fstab
/dev/sda1	/mnt/boot	auto	defaults	0	0
EOT

余談: このくらいの記述ならあらかじめ debian12-rootfs-vanilla.tgz に書いておけば良いのに、何故わざわざ後で設定するのか疑問に思われるかもしれません。その理由は、debian12-rootfs-vanilla.tgz が Ultra96/Ultra96V2/UltraZed/KV260/KR260 と共用だからです。Ultra96/Ultra96-V2 の SD-Card のブートパーティションは /dev/mmcblk0p1 ですが、UltraZed/KV260 の SD-Card のブートパーティションは /dev/mmcblk1p1 で、さらに KR260 の SD-Card のブートパーティションは /dev/sda1 です。しかも UltraZed には /dev/mmcblk0p1 というのも存在していて、あらかじめ debian12-rootfs-vanilla.tgz に書いてしまっていると UltraZed では間違えて別のデバイスにアクセスしてしまいます。そこで、面倒ですが後で設定するようにしました。

4. ネットワークの設定

Ultra96/Ultra96-V2 は WiFi を通じてネットワークに接続します。あらかじめホスト側で設定ファイルを作って RootFS に書いておくと良いかもしれません。もちろん、後で Ultra96/Ultra96-V2 を起動してそちらで設定してもかまいません。

ここでは SSID を ssssssssに、パスフレーズを ppppppppp に、暗号化したアクセスキーを xxxx とします。

まずは wpa_passphrase に SSID とパスフレーズを入力して暗号化したアクセスキーを作ります。

shell# wpa_passphrase ssssssss ppppppppp
network={
	ssid="ssssssss"
	#psk="ppppppppp"
	psk=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
}
4.1 /etc/network/interfaces.d/wlan0 に直接記述

SSID と暗号化したアクセスキーをネットワーク設定ファイル(/etc/network/interfaces.d/wlan0)に直接記述します。

/mnt/usb2/etc/network/interfaces.d/wlan0

auto  wlan0
iface wlan0 inet dhcp
	wpa-ssid ssssssss
	wpa-psk  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
4.2 /etc/wpa_supplicant/wpa_supplicant.conf に記述

ネットワーク設定ファイル(/etc/network/interfaces.d/wlan0)に、次のように、ブート時に wpa_supplicant.conf を読み込んで Wifi を設定するように記述します。

/mnt/usb2/etc/network/interfaces.d/wlan0

auto  wlan0
iface wlan0 inet dhcp
wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf

SSID と暗号化したアクセスキーをWifi設定ファイル(/etc/wpa_supplicant/wpa_supplicant.conf)に記述します。

/etc/wpa_supplicant/wpa_supplicant.conf
ctrl_interface=/run/wpa_supplicant
update_config=1

network={
	ssid="ssssssss"
	psk=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
}

なお、ステルス SSID の場合、スキャンを強制的に行う必要があります。この場合は、/etc/wpa_supplicant/wpa_supplicant.conf に scan_ssid=1 を追加します。

/etc/wpa_supplicant/wpa_supplicant.conf
ctrl_interface=/run/wpa_supplicant
update_config=1

network={
	ssid="ssssssss"
	scan_ssid=1
	key_mgmt=WPA-PSK
	psk=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
}

パスフレーズ無し の SSID に接続する場合は、key_mgmt=NONE(NONE は大文字) にすると良いようです。

/etc/wpa_supplicant/wpa_supplicant.conf
ctrl_interface=/run/wpa_supplicant
update_config=1

network={
	ssid="ssssssss"
	scan_ssid=1
	key_mgmt=NONE
}

5. SD-Card のアンマウント

shell# umount /mnt/usb1
shell# umount /mnt/usb2

デバイスドライバパッケージのインストール

ターゲットのブート

デバイスドライバなどの Debian パッケージをインストールするためには、上記で作成した SD-Card を使ってターゲットをブートする必要があります。

root でログイン

root でログインします。debian12-rootfs-vanilla の root のパスワードは admin です。root のパスワードは適時変更しておくと良いでしょう。

debian-fpga login: root
Password:
root@debian-fpga:~#

Linux Image Package のインストール

debian12-rootfs-vanilla にはすでに Linux Image Package(linux-image-6.1.70-zynqmp-fpga-generic_6.1.70-zynqmp-fpga-generic-2_arm64.deb) がインストールされています。ですので、以下の作業は不要ですが、なんらかの事情で再インストールする際の参考にしてください。

なお、Linux Image Package はカーネルモジュールが含まれており、Debian が正常に起動するためには必須のパッケージです。必ずインストールしておいてください。

root@debian-fpga:~# cd /home/fpga/debian
root@debian-fpga:/home/fpga/debian# dpkg -i linux-image-6.1.70-zynqmp-fpga-generic_6.1.70-zynqmp-fpga-generic-2_arm64.deb
(Reading database ... 29866 files and directories currently installed.)
Preparing to unpack linux-image-6.1.70-zynqmp-fpga-generic_6.1.70-zynqmp-fpga-generic-2_arm64.deb ...
Unpacking linux-image-6.1.70-zynqmp-fpga-generic (6.1.70-zynqmp-fpga-generic-2) over (6.1.70-zynqmp-fpga-generic-2) ...
Setting up linux-image-6.1.70-zynqmp-fpga-generic (6.1.70-zynqmp-fpga-generic-2) ...

Linux Header Package のインストール

dpkg を使って linux-headers-6.1.70-zynqmp-fpga-generic_6.1.70-zynqmp-fpga-generic-2_arm64.deb をインストールします。途中で何故か ARM64_BTI、ARM64_E0PD、ARCH_RANDOM、ARM64_MTE、KASAN についてどうするか聞かれますが、かまわず ENTER キーを押してください。

なお、Linux Header Package のインストールは必須ではありませんが、デバイスドライバをセルフでビルドしたり、DKMS をつかってサードパーティが提供するドライバをインストールする際に必要になります。必要に応じてインストールしてください。

root@debian-fpga:~# cd /home/fpga/debian
root@debian-fpga:/home/fpga/debian# dpkg -i linux-headers-6.1.70-zynqmp-fpga-generic_6.1.70-zynqmp-fpga-generic-2_arm64.deb
Selecting previously unselected package linux-headers-6.1.70-zynqmp-fpga-generic.
(Reading database ... 30894 files and directories currently installed.)
Preparing to unpack linux-headers-6.1.70-zynqmp-fpga-generic_6.1.70-zynqmp-fpga-generic-2_arm64.deb ...
Unpacking linux-headers-6.1.70-zynqmp-fpga-generic (6.1.70-zynqmp-fpga-generic-2) ...
Setting up linux-headers-6.1.70-zynqmp-fpga-generic (6.1.70-zynqmp-fpga-generic-2) ...
make: Entering directory '/usr/src/linux-headers-6.1.70-zynqmp-fpga-generic'
  SYNC    include/config/auto.conf.cmd
  HOSTCC  scripts/basic/fixdep
  HOSTCC  scripts/kconfig/conf.o
  HOSTCC  scripts/kconfig/confdata.o
  HOSTCC  scripts/kconfig/expr.o
  LEX     scripts/kconfig/lexer.lex.c
  YACC    scripts/kconfig/parser.tab.[ch]
  HOSTCC  scripts/kconfig/lexer.lex.o
  HOSTCC  scripts/kconfig/menu.o
  HOSTCC  scripts/kconfig/parser.tab.o
  HOSTCC  scripts/kconfig/preprocess.o
  HOSTCC  scripts/kconfig/symbol.o
  HOSTCC  scripts/kconfig/util.o
  HOSTLD  scripts/kconfig/conf
*
* Restart config...
*
*
* General architecture-dependent options
*
Kprobes (KPROBES) [N/y/?] n
Optimize very unlikely/likely branches (JUMP_LABEL) [N/y/?] n
Enable seccomp to safely execute untrusted bytecode (SECCOMP) [Y/n/?] y
  Show seccomp filter cache status in /proc/pid/seccomp_cache (SECCOMP_CACHE_DEBUG) [N/y/?] n
Stack Protector buffer overflow detection (STACKPROTECTOR) [Y/n/?] y
  Strong Stack Protector (STACKPROTECTOR_STRONG) [Y/n/?] y
Shadow Call Stack (SHADOW_CALL_STACK) [N/y/?] (NEW)
Link Time Optimization (LTO)
> 1. None (LTO_NONE)
choice[1]: 1
Number of bits to use for ASLR of mmap base address (ARCH_MMAP_RND_BITS) [18] 18
Number of bits to use for ASLR of mmap base address for compatible applications (ARCH_MMAP_RND_COMPAT_BITS) [11] 11
Provide system calls for 32-bit time_t (COMPAT_32BIT_TIME) [Y/n/?] y
Use a virtually-mapped stack (VMAP_STACK) [Y/n/?] y
Support for randomizing kernel stack offset on syscall entry (RANDOMIZE_KSTACK_OFFSET) [Y/n/?] y
  Default state of kernel stack offset randomization (RANDOMIZE_KSTACK_OFFSET_DEFAULT) [N/y/?] n
Locking event counts collection (LOCK_EVENT_COUNTS) [N/y/?] n
*
* Memory initialization
*
Initialize kernel stack variables at function entry
> 1. no automatic stack variable initialization (weakest) (INIT_STACK_NONE)
  2. pattern-init everything (strongest) (INIT_STACK_ALL_PATTERN) (NEW)
  3. zero-init everything (strongest and safest) (INIT_STACK_ALL_ZERO) (NEW)
choice[1-3?]:
Enable heap memory zeroing on allocation by default (INIT_ON_ALLOC_DEFAULT_ON) [N/y/?] n
Enable heap memory zeroing on free by default (INIT_ON_FREE_DEFAULT_ON) [N/y/?] n
Enable register zeroing on function exit (ZERO_CALL_USED_REGS) [N/y/?] (NEW)
*
* KCSAN: dynamic data race detector
*
KCSAN: dynamic data race detector (KCSAN) [N/y/?] (NEW)
*
* Kernel Testing and Coverage
*
Notifier error injection (NOTIFIER_ERROR_INJECTION) [N/m/y/?] n
Fault-injection framework (FAULT_INJECTION) [N/y/?] n
Code coverage for fuzzing (KCOV) [N/y/?] (NEW)
Memtest (MEMTEST) [N/y/?] n
  HOSTCC  scripts/dtc/dtc.o
  HOSTCC  scripts/dtc/flattree.o
  HOSTCC  scripts/dtc/fstree.o
  HOSTCC  scripts/dtc/data.o
  HOSTCC  scripts/dtc/livetree.o
  HOSTCC  scripts/dtc/treesource.o
  HOSTCC  scripts/dtc/srcpos.o
  HOSTCC  scripts/dtc/checks.o
  HOSTCC  scripts/dtc/util.o
  HOSTCC  scripts/dtc/dtc-lexer.lex.o
  HOSTCC  scripts/dtc/dtc-parser.tab.o
  HOSTLD  scripts/dtc/dtc
  HOSTCC  scripts/dtc/libfdt/fdt.o
  HOSTCC  scripts/dtc/libfdt/fdt_ro.o
  HOSTCC  scripts/dtc/libfdt/fdt_wip.o
  HOSTCC  scripts/dtc/libfdt/fdt_sw.o
  HOSTCC  scripts/dtc/libfdt/fdt_rw.o
  HOSTCC  scripts/dtc/libfdt/fdt_strerror.o
  HOSTCC  scripts/dtc/libfdt/fdt_empty_tree.o
  HOSTCC  scripts/dtc/libfdt/fdt_addresses.o
  HOSTCC  scripts/dtc/libfdt/fdt_overlay.o
  HOSTCC  scripts/dtc/fdtoverlay.o
  HOSTLD  scripts/dtc/fdtoverlay
  HOSTCC  scripts/selinux/genheaders/genheaders
  HOSTCC  scripts/selinux/mdp/mdp
  HOSTCC  scripts/kallsyms
  HOSTCC  scripts/sorttable
  HOSTCC  scripts/asn1_compiler
  CC      scripts/mod/empty.o
  HOSTCC  scripts/mod/mk_elfconfig
  MKELF   scripts/mod/elfconfig.h
  CC      scripts/mod/devicetable-offsets.s
  HOSTCC  scripts/mod/modpost.o
  HOSTCC  scripts/mod/file2alias.o
  HOSTCC  scripts/mod/sumversion.o
  HOSTLD  scripts/mod/modpost
make: Leaving directory '/usr/src/linux-headers-6.1.70-zynqmp-fpga-generic'

fclkcfg デバイスドライバのインストール

dpkg を使って fclkcfg-6.1.70-zynqmp-fpga-generic_1.7.3-1_arm64.deb をインストールします。

このパッケージは必須ではありません。

root@debian-fpga:~# cd /home/fpga/debian
root@debian-fpga:/home/fpga/debian# dpkg -i fclkcfg-6.1.70-zynqmp-fpga-generic_1.7.3-1_arm64.deb
Selecting previously unselected package fclkcfg-6.1.70-zynqmp-fpga-generic.
(Reading database ... 48233 files and directories currently installed.)
Preparing to unpack fclkcfg-6.1.70-zynqmp-fpga-generic_1.7.3-1_arm64.deb ...
Unpacking fclkcfg-6.1.70-zynqmp-fpga-generic (1.7.3-1) ...
Setting up fclkcfg-6.1.70-zynqmp-fpga-generic (1.7.3-1) ...

udmabuf デバイスドライバのインストール

dpkg を使って u-dma-buf-6.1.70-zynqmp-fpga-generic_4.5.2-0_arm64.deb をインストールします。

このパッケージは必須ではありません。

root@debian-fpga:~# cd /home/fpga/debian
root@debian-fpga:/home/fpga/debian# dpkg -i u-dma-buf-6.1.70-zynqmp-fpga-generic_4.5.2-0_arm64.deb
Selecting previously unselected package u-dma-buf-6.1.70-zynqmp-fpga-generic.
(Reading database ... 48239 files and directories currently installed.)
Preparing to unpack u-dma-buf-6.1.70-zynqmp-fpga-generic_4.5.2-0_arm64.deb ...
Unpacking u-dma-buf-6.1.70-zynqmp-fpga-generic (4.5.2-0) ...
Setting up u-dma-buf-6.1.70-zynqmp-fpga-generic (4.5.2-0) ...

参考

旧記事

現時点の最新バージョンは ZynqMP-FPGA-Debian12 v4.1.0 ですが、それ以前のバージョンをインストールする際は以下の記事を参照してください。

1
0
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?