😽

Vitisに入門してみる。(2)PetaLinuxを動かす

2023/04/10に公開

前回VitisでLチカを動かすことができた。
まーやったことはSDK時代とほとんど変わらない気がする。

次は以下のような構成を作ることを目指す。

基本的にシステムはFPGAで完結しており、Host PCは単にターミナルのイメージ。
PS側にLinuxを載せる必要があるか?っていうのはある。
Linuxを載せることのメリットは

  • 実運用に近いシステムになる?
  • 実機上でコンパイルできる
  • 実機上で計時とかできる。

くらいかなあ?
正直上二つはどうでもいいけど、経験を積むという意味でもlinuxを載せてやってみる。

環境

Vitis 2022.2
Vivado 2022.2
Windows 11
Ubuntu20.04 on WSL2
Arty Z7-20


Petalinux Tool Install

WSL2に入れれるっぽいのでやってみる。(Ubuntu 20.04)
以下を参照
https://docs.xilinx.com/r/en-US/ug1144-petalinux-tools-reference-guide/Setting-Up-Your-Environment
https://qiita.com/takusanToIssho/items/09371df20ce6c9608a70

Arty Z7のPetaLinux Supportは2017.4になっているけど、大丈夫と信じて2022.2を入れてみる。

サイトを参考に以下のコマンドを実行したところエラー

sudo dpkg --add-architecture i386
sudo apt update
sudo apt install -y gcc g++ net-tools libncurses5-dev zlib1g:i386 libssl-dev flex bison libselinux1 xterm autoconf libtool texinfo zlib1g-dev gcc-multilib build-essential screen pax gawk xz-utils debianutils iputils-ping libegl1-mesa libsdl1.2-dev libtinfo5
chmod +x petalinux-v2022.2-10141622-installer.run
sudo mkdir -p /opt/pkg/petalinux/2022.2
sudo chmod 755 /opt/pkg/petalinux/2022.2/
./petalinux-v2022.2-10141622-installer.run --dir /opt/pkg/petalinux/2022.2/

ログを見ると権限が足りないらしい。
インストール先に777をつけたりsudoで実行してもだめ

https://support.xilinx.com/s/question/0D52E00006iHmmaSAC/petalinux20182-installation-failed?language=ja

に書いてある通り、インストール先ディレクトリのオーナーをユーザーにして解決

source /opt/pkg/petalinux/2022.2/settings.sh

でパスを通し、.bashrcに登録してインストール完了。

Petalinux Project Build

UG1144によると2つの方法でプロジェクトを作れる?

  • BSPを使う方法
  • テンプレートを使う方法

まずBSPを使ってビルドしてみる。

Build from BSP

ArtyのBSPは
https://github.com/Digilent/Petalinux-Arty-Z7-20/releases
にあるのでダウンロードして使う。2017用だけどとりあえず気にしないことにする。

petalinux-create -t project -s Petalinux-Arty-Z7-20-2017.4-1.b
sp

でプロジェクトを作成。するとArty-Z7-20というディレクトリができる。
pre-builtの中にある

  • BOOT.bin:bitstreamとFSBL, u-boot
  • image.ub:kernel, rootfs

をSDカードにコピーする。(普通にエクスプローラーからコピーで行けた)
ここで面倒なのがSDカードをFATフォーマットする必要がある点。Windows 11ではドライブの右クリックメニューからはFATフォーマットできなかった。
怪しげなサードパーティツールはあんまり使いたくないので、cmdのdiskpartコマンドからフォーマットする。

SDブートにジャンパして、リセットすると起動を確認

Build from template

BSPからLinuxを起動することはできたが、PLと連携できないのではまったく面白くない。
https://www.acri.c.titech.ac.jp/wordpress/archives/10058
を参考に自作ハードウェア(Lチカで作ったやつ)をプラットフォームに組み込む。

テンプレートからプロジェクトを作成

petalinux-create -t project --template zynq -n test_led_blink

プロジェクトフォルダに入ってからエクスポートした.xsaハードウェアをプロジェクトに読み込む

petalinux-config --get-hw-description <path to xsa file>


こんな画面が出て、ハードウェアの設定ができるみたい。
UGによると評価ボードの場合はDTG settingsのMACHINE nameを変更するみたいだけどArtyなので変更不要。
他にもいろいろ設定できるみたいだが、そのままでSaveしてExit

上記サイトではほかにもrootfsやカーネルの設定を行っているが、省略してそのままビルドを行う。

petalinux-build

パッケージング

petalinux-package --boot --u-boot
  • BOOT.BIN
  • image.ub
  • boot.scr

がimages下にできるので、FAT32フォーマットされたSDカードに入れて、起動!
するとコンソールには以下のように表示された。

mmc0 is current device
** No partition table - mmc 0 **
Couldn't find partition mmc 0:1
JTAG: Trying to boot script at 3000000
## Executing script at 03000000
Wrong image format for "source" command
JTAG: SCRIPT FAILED: continuing...
switch to partitions #0, OK
mmc0 is current device
** No partition table - mmc 0 **
Couldn't find partition mmc 0:1
MMC Device 1 not found
no mmc device at slot 1
SF: Detected n25q128a13 with page size 256 Bytes, erase size 4 KiB, total 16 MiB
device 0 offset 0x9c0000, size 0x40000
SF: 262144 bytes @ 0x9c0000 Read: OK
QSPI: Trying to boot script at 3000000
## Executing script at 03000000
Wrong image format for "source" command
QSPI: SCRIPT FAILED: continuing...


no devices available
NAND: SCRIPT FAILED: continuing...
NOR: Trying to boot script at 3000000
## Executing script at 03000000
Wrong image format for "source" command
NOR: SCRIPT FAILED: continuing...
starting USB...
Bus usb@e0002000: USB EHCI 1.00
scanning bus usb@e0002000 for devices... 1 USB Device(s) found
       scanning usb for storage devices... 0 Storage Device(s) found

Device 0: unknown device

Device 1: unknown device
ethernet@e000b000 Waiting for PHY auto negotiation to complete......... TIMEOUT !
missing environment variable: pxeuuid
Retrieving file: pxelinux.cfg/01-00-0a-35-00-1e-53
ethernet@e000b000 Waiting for PHY auto negotiation to complete......... TIMEOUT !

パーティションが見つからないと怒られている。
パーティションのやり方は以下
https://docs.xilinx.com/r/en-US/ug1144-petalinux-tools-reference-guide/Partitioning-and-Formatting-an-SD-Card

結局こういう感じでパーティション分ければいいみたい。

サイズは何でもいいんじゃないかと思う。
Linuxマシンがないのであまりやりたくないが、diskpartでやってみる。

diskpart
list disk
select disk [番号]
list volume
select volume [番号]
clean
create partition primary size=# (in MB)
create partition primary size=# (in MB)
select partition 1
format fs=fat32
select partition 2

cmdを管理者権限で起動し、上記のコマンドでパーティション分割はできた。しかしdiskpartではext4フォーマットできないことにここで気づく。
どうもWindows標準機能じゃどうやってもext4フォーマットできないらしいので、怪しげなソフトEaseUS Partition Master Freeを使うことに屈した。(GUIでフォーマットできて使いやすかった。)
下のやり方でWSL2にSDカードをマウントできることを確認。

こんな感じのパーティションにした。

FATのほうのパーティションはWindowsからアクセスできるので、BOOT.BIN, image.ub, boot.scrをそのまま入れればよい。
このまま動かないかと期待したがそんなことはない。ext4のほうにrootfsを展開する必要がある。これが問題。
WSL2にext4をマウントする方法をいかに記す。
https://zenn.dev/ankoma/articles/45d4bc892bf9d3

rootfsはddコマンドで

sudo dd if=images/linux/rootfs.ext4 of=/dev/sdd2 status=progress
sync
sudo resize2fs /dev/sdd2 
sync

のように転送する。ddはまあまあ遅いので注意

これで完成!起動!と思いきや途中までうまくいくが以下の起動ログで実行停止する。

U-Boot 2022.01 (Sep 20 2022 - 06:35:33 +0000)

CPU:   Zynq 7z020
Silicon: v3.1
Model: Zynq Arty Z7 Development Board
DRAM:  ECC disabled 512 MiB
Flash: 0 Bytes
NAND:  0 MiB
MMC:   mmc@e0100000: 0
Loading Environment from FAT... *** Error - No Valid Environment Area found
*** Warning - bad env area, using default environment

In:    serial@e0000000
Out:   serial@e0000000
Err:   serial@e0000000
Net:   FEC: can't find phy-handle

ZYNQ GEM: e000b000, mdio bus e000b000, phyaddr 0, interface rgmii-id
eth0: ethernet@e000b000
Hit any key to stop autoboot:  0
switch to partitions #0, OK
mmc0 is current device
Scanning mmc 0:1...
Found U-Boot script /boot.scr
2776 bytes read in 13 ms (208 KiB/s)
## Executing script at 03000000
Trying to load boot images from mmc0
4535396 bytes read in 261 ms (16.6 MiB/s)
## Loading kernel from FIT Image at 10000000 ...
   Using 'conf-system-top.dtb' configuration
   Verifying Hash Integrity ... OK
   Trying 'kernel-1' kernel subimage
     Description:  Linux kernel
     Type:         Kernel Image
     Compression:  uncompressed
     Data Start:   0x100000fc
     Data Size:    4513552 Bytes = 4.3 MiB
     Architecture: ARM
     OS:           Linux
     Load Address: 0x00200000
     Entry Point:  0x00200000
     Hash algo:    sha256
     Hash value:   192129b638f881d8a6f6f14f3ad949eee5b8ad5d74d1ff53fe9dc234b0893d70
   Verifying Hash Integrity ... sha256+ OK
## Loading fdt from FIT Image at 10000000 ...
   Using 'conf-system-top.dtb' configuration
   Verifying Hash Integrity ... OK
   Trying 'fdt-system-top.dtb' fdt subimage
     Description:  Flattened Device Tree blob
     Type:         Flat Device Tree
     Compression:  uncompressed
     Data Start:   0x1044e118
     Data Size:    19941 Bytes = 19.5 KiB
     Architecture: ARM
     Hash algo:    sha256
     Hash value:   88f9c6b8d40187b4096c2d924a0beb0e70f0de994126db38e0ee4d0928f454df
   Verifying Hash Integrity ... sha256+ OK
   Booting using the fdt blob at 0x1044e118
   Loading Kernel Image
   Loading Device Tree to 1ead3000, end 1eadade4 ... OK

Starting kernel ...

Booting Linux on physical CPU 0x0
Linux version 5.15.36-xilinx-v2022.2 (oe-user@oe-host) (arm-xilinx-linux-gnueabi-gcc (GCC) 11.2.0, GNU ld (GNU Binutils) 2.37.20210721) #1 SMP PREEMPT Mon Oct 3 07:50:07 UTC 2022
CPU: ARMv7 Processor [413fc090] revision 0 (ARMv7), cr=18c5387d
CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
OF: fdt: Machine model: Zynq Arty Z7 Development Board
earlycon: cdns0 at MMIO 0xe0000000 (options '115200n8')
printk: bootconsole [cdns0] enabled
Memory policy: Data cache writealloc
cma: Failed to reserve 512 MiB
Zone ranges:
  Normal   [mem 0x0000000000000000-0x000000001fffffff]
  HighMem  empty
Movable zone start for each node
Early memory node ranges
  node   0: [mem 0x0000000000000000-0x000000001fffffff]
Initmem setup node 0 [mem 0x0000000000000000-0x000000001fffffff]
percpu: Embedded 11 pages/cpu s15180 r8192 d21684 u45056
Built 1 zonelists, mobility grouping on.  Total pages: 130048
Kernel command line: console=ttyPS0,115200 earlycon root=/dev/mmcblk0p2 rw rootwait clk_ignore_unused cma=512M earlyprintk uio_pdrv_genirq.of_id=generic-uio
Unknown kernel command line parameters "earlyprintk", will be passed to user space.
Dentry cache hash table entries: 65536 (order: 6, 262144 bytes, linear)
Inode-cache hash table entries: 32768 (order: 5, 131072 bytes, linear)
mem auto-init: stack:off, heap alloc:off, heap free:off
Memory: 507488K/524288K available (7168K kernel code, 241K rwdata, 1884K rodata, 1024K init, 122K bss, 16800K reserved, 0K cma-reserved, 0K highmem)
rcu: Preemptible hierarchical RCU implementation.
rcu:    RCU event tracing is enabled.
rcu:    RCU restricting CPUs from NR_CPUS=4 to nr_cpu_ids=2.
        Trampoline variant of Tasks RCU enabled.
rcu: RCU calculated value of scheduler-enlistment delay is 10 jiffies.
rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=2
NR_IRQS: 16, nr_irqs: 16, preallocated irqs: 16
efuse mapped to (ptrval)
slcr mapped to (ptrval)
GIC physical location is 0xf8f01000
L2C: platform modifies aux control register: 0x72360000 -> 0x72760000
L2C: DT/platform modifies aux control register: 0x72360000 -> 0x72760000
L2C-310 erratum 769419 enabled
L2C-310 enabling early BRESP for Cortex-A9
L2C-310 full line of zeros enabled for Cortex-A9
L2C-310 ID prefetch enabled, offset 1 lines
L2C-310 dynamic clock gating enabled, standby mode enabled
L2C-310 cache controller enabled, 8 ways, 512 kB
L2C-310: CACHE_ID 0x410000c8, AUX_CTRL 0x76760001
random: get_random_bytes called from start_kernel+0x364/0x5d8 with crng_init=0
zynq_clock_init: clkc starts at (ptrval)
Zynq clock init
sched_clock: 64 bits at 162MHz, resolution 6ns, wraps every 4398046511101ns
clocksource: arm_global_timer: mask: 0xffffffffffffffff max_cycles: 0x257a3bfb55, max_idle_ns: 440795207830 ns
Switching to timer-based delay loop, resolution 6ns
Console: colour dummy device 80x30
Calibrating delay loop (skipped), value calculated using timer frequency.. 325.00 BogoMIPS (lpj=1625000)
pid_max: default: 32768 minimum: 301
Mount-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
CPU: Testing write buffer coherency: ok
CPU0: Spectre v2: using BPIALL workaround
CPU0: thread -1, cpu 0, socket 0, mpidr 80000000
Setting up static identity map for 0x100000 - 0x100060
rcu: Hierarchical SRCU implementation.
smp: Bringing up secondary CPUs ...
CPU1: thread -1, cpu 1, socket 0, mpidr 80000001
CPU1: Spectre v2: using BPIALL workaround
smp: Brought up 1 node, 2 CPUs
SMP: Total of 2 processors activated (650.00 BogoMIPS).
CPU: All CPU(s) started in SVC mode.
devtmpfs: initialized
VFP support v0.3: implementor 41 architecture 3 part 30 variant 9 rev 4
clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
futex hash table entries: 512 (order: 3, 32768 bytes, linear)
pinctrl core: initialized pinctrl subsystem
NET: Registered PF_NETLINK/PF_ROUTE protocol family
DMA: preallocated 256 KiB pool for atomic coherent allocations
thermal_sys: Registered thermal governor 'step_wise'
amba f8801000.etb: Fixing up cyclic dependency with replicator
amba f8803000.tpiu: Fixing up cyclic dependency with replicator
amba f8804000.funnel: Fixing up cyclic dependency with replicator
amba f889c000.ptm: Fixing up cyclic dependency with f8804000.funnel
amba f889d000.ptm: Fixing up cyclic dependency with f8804000.funnel
hw-breakpoint: found 5 (+1 reserved) breakpoint and 1 watchpoint registers.
hw-breakpoint: maximum watchpoint size is 4 bytes.
e0000000.serial: ttyPS0 at MMIO 0xe0000000 (irq = 31, base_baud = 6250000) is a xuartps
printk: console [ttyPS0] enabled
printk: console [ttyPS0] enabled
printk: bootconsole [cdns0] disabled
printk: bootconsole [cdns0] disabled

https://support.xilinx.com/s/question/0D52E00006hpmlWSAQ/linux-hangs-at-bootconsole-cdns0-disabled-when-i-try-xilinx-answer-72076?language=ja
同じことで悩んでる人はいるっぽいのだがいまいち解決法が分からない。。。
bootargにいろいろ追加したりCLK PMをオフにしたりrootfsの読み先をEXT4にしたりしたが功を奏さない。

結構調べてたどり着いた正解はこれ
https://support.xilinx.com/s/question/0D52E00006hpXNMSA2/petalinux-boot-stuck-at-console-ttyps0-enabled?language=en_US
system.bitファイルがロードされていないらしい。
system.bitが何か不明だが、取り急ぎpetalinux-configから
DTG Settings --->[*] Remove PL from devicetree
するといいらしい。

ビルドして実行すると、ログインできる。
ちなみにroot:rootでは入れなかった。
petalinux-config -c rootfsのRootFS Srttingを見ると、petalinuxユーザーで入れることがわかる。

gccとか入ってないので、特に面白いこともできない。
次はrootfsにパッケージの追加かな

Discussion