Prismjs

2022年6月30日木曜日

PetaLinuxなしでZYBOでLinuxを構築・起動するまでの手順(Linux on zynq)

linux.md

PetaLinuxなしでZYBOでLinuxを構築・起動するまでの手順(Linux on zynq)

PetaLinuxをインストールしたり環境を整えるのが大変なので、PetaLinuxを使わずにLinux on zynqを実現した。
ブートローダーはu-boot-xlnx、カーネルはlinux-xlnxを使用して作成する。

環境、準備

回路作成はWindowsPC上のVivadoで行い、ZYBO用Linux作成はWindowsPC上の仮想マシン(WSL2、一部作業のみVirtualBox)で動作するUbuntu20.04内で行った。
使用ボード:Zybo Z7-20(無印、Z7-10でもほぼ同じ手順なはず)
PC:Windows10 64bit
Vivadoバージョン:2018.3(諸事情で古い)
ZYBO用Linux作成環境:Ubuntu 20.04 LTS (WindowsのWSL2で構築)
ZYBOで動作させるディストリビューション:Ubuntu 20.04 LTS
ZYBOで動作させるLinuxカーネルバージョン:5.10

なおWindows10でWSL2を用いる場合、USBデバイスをWSL2側でマウントすることができない。そのためSDカードをext4でフォーマットできない。
Win10でもVirtualBoxで構築した仮想環境ならUSBデバイスをマウント可能なのでext4フォーマットもできる。
SDカードのext4フォーマット時・ext4領域にファイルをコピーする時、ルートファイルシステム構築の時にはVirtualBoxか、いっそのことラズパイや別のLinux機などを使う必要がある。
今回はできるだけWSL2上でやりたかっただけなので、特に希望がなければ基本的にはVirtualBoxを使うことをオススメする。

未確認だがWindows11ではUSBデバイスをWSL2側でマウントできるらしいので、Windowsの標準機能だけでLinux構築まで行えると思われる。

Vivadoでプロジェクトを作成しビットストリームファイルとLaunch SDKでSDK起動時に自動生成されるps7_init_gpl.cとps7_init_gpl.hを準備しておく。
上記ファイルさえ生成できていればVivadoはWindows版でもLinux版でもどちらでもよい。

WSL2にUbuntuをインストール

Ubuntu20.04が使えればWSL2ではなくVirtualBox等でもいいし実機のPCでもいい。
本説明ではWSL2使用前提で話を進める。
これ以降の操作は基本的にPCのUbuntu上での操作となる。

WSL2のUbuntu上にZYBO用Linux作成環境を構築

まずはaptのアップデート

sudo apt update sudo apt -y upgrade

下記パッケージをインストール

sudo apt install -y libssl-dev flex bison libncurses-dev build-essential git u-boot-tools qemu-user-static curl debootstrap

クロスコンパイルのためのtoolchainをダウンロード

mkdir toolchain cd toolchain curl -OL https://snapshots.linaro.org/gnu-toolchain/13.0-2022.10-1/arm-linux-gnueabihf/gcc-linaro-13.0.0-2022.10-x86_64_arm-linux-gnueabihf.tar.xz

toolchainを解凍

tar Jxf gcc-linaro-13.0.0-2022.10-x86_64_arm-linux-gnueabihf.tar.xz

toolchainのパスを通す、makeのエイリアスを登録する。
テキストエディタで~/.bashrcの末尾に下記を追記(doraの部分は各ユーザー名に置き換える)

alias zybomake="ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- make" export PATH=$PATH:/home/dora/toolchain/gcc-linaro-13.0.0-2022.10-x86_64_arm-linux-gnueabihf/bin

なおテキストエディタはなんでも良いが要root(下記はnanoの例。入力後ctrl+o後enterで保存、ctrl+xでエディタを閉じる)

sudo nano ~/.bashrc

Xilinxのu-boot(Xilinx/u-boot-xlnx)をダウンロード。容量は約380MBほど

git clone https://github.com/Xilinx/u-boot-xlnx.git

下記コマンドでチェックアウトしておく

cd u-boot-xlnx git checkout xilinx-v2018.1

XilinxのLinuxカーネル(Xilinx/linux-xlnx)をダウンロード。容量約4GBで数十分ほどかかることもある。

git clone https://github.com/Xilinx/linux-xlnx.git

下記コマンドでチェックアウトしておく

cd linux-xlnx git checkout xlnx_rebase_v5.10

SDカードのパーティション作成

SDカードの1区画目をfat32で、2区画目をext4にする。1区画目はboot領域として使われるので10MB以上、2区画目はrootfs領域として使われるので残りの領域全部を割り当てる。 パーティションの作成さえできれば下記手順で行わなくてもいい。(GUIならgpartedなどを使うともっと楽にできるかも)

SDカードをリーダ等を使ってLinuxマシンに認識させる。(windows10でwsl2を使用してる場合はVirtualBoxか別のLinux機を使う)
dmesgコマンドでSDカードが/devになんと認識されているか調べる。/dev/sdxとして認識されているはず。(xにはaやbやcなどのアルファベットが入る)

fdisk等でパーティションを設定する。1区画目を20MB程度、2区画目を残りの領域となるように設定する。
以下はfdiskでのコマンド例

sudo fdisk /dev/sdx コマンド(mでヘルプ):n p 1 +20M n p 2 t 1 b w

下記コマンドで作成したパーティションをフォーマットする。

sudo mkfs.vfat /dev/sdx1 sudo mkfs.ext4 /dev/sdx2

フォーマット時、環境によってはvfat(fat32)フォーマットができないことがある。
その際はwindowsでSDカードを認識させてパーティションの作成とフォーマットにて1区画目をfat32でフォーマットすれば大丈夫だった。(力業だが。。。)

下記コマンドでパーティションにラベルを付ける。

sudo mlabel -i /dev/sdx1 ::BOOT sudo e2label /dev/sdx2 ROOTFS

u-bootの作成

vivadoでbitstream作成後にLaunch SDKでXilinx SDKを起動すると自動生成される~~~~_hw_platform_x内にある、ps7_init_gpl.c、ps7_init_gpl.hをu-boot-xlnx/board/xilinx/zynq/zynq-zybo/内にコピーする。

z7を使用する場合はu-boot/arch/arm/dts/zynq-zybo.dtsをテキストエディタを用いてps-clk-frequency = <50000000>;をps-clk-frequency = <33333333>;に書き換える。(無印ZYBOなら50000000のままにする)

u-boot/include/configs/zynq-common.hの
227行目付近の「"bitstream_image=system.bit.bin\0" \」を
"bitstream_image=fpga.bit\0" \」に修正。
250行目付近の「"fpga load 0 ${loadbit_addr} ${filesize}\0" \」を
"fpga loadb 0 ${loadbit_addr} ${filesize}\0" \」に修正。
271行目付近の「"run uenvboot; " \」を「"run mmc_loadbit && " \」に、
"bootm ${kernel_load_address} ${ramdisk_load_address} ${devicetree_load_address}; " \」を
"bootm ${kernel_load_address} - ${devicetree_load_address}; "\」に修正、
"load mmc 0 ${ramdisk_load_address} ${ramdisk_image} && " \」を削除

こうすることでfpga.bitという名前にしたbitstreamファイルをu-bootで自動ロードするようになる。

下記コマンドでコンパイル

cd u-boot zybomake zynq_zybo_defconfig zybomake

生成されたu-boot-xlnx/spl/boot.binをSDカードのBOOTパーティションにコピー、 u-boot-xlnx/u-boot-dtb.imgをSDカードのBOOTパーティションにコピーしu-boot.imgにリネームする。

カーネルの作成

linux-xlnx/arch/arm/boot/dts/zynq-zybo.dtsを下記のように修正する。
chosen部を以下のように修正

chosen { bootargs = "mem=512M console=ttyPS0,115200 earlyprintk rw rootfstyep=ext4 root=/dev/mmcblk0p2 rootwait uio_pdrv_genirq.of_id=generic-uio"; stdout-path = "serial0:115200n8"; };

clock部を以下のように修正

&clkc { ps-clk-frequency = <33333333>; };

下記コマンドでコンフィグメニューを開き所望のデバイスドライバなどをカーネルに組み込む。

cd linux-xlnx zybomake xilinx_zynq_defconfig zybomake menuconfig

上下キーで項目選択アイコン、左右キーでSelectやExitなどの選択アイコンが動き、Selectで決定、Exitで戻る

何も設定しなくてもZyboでLinuxは起動するはずだが以下に最低限入れておくと役立つものを示す。

File Systems > Network File Systems > SMB3 and CIFS support (advanced network filesystem) Kernel hacking > arm Debugging > Kernel low-level debugging port(Kernel low-level debugging on Xilinx...を選択し表示されたメニューのKernel low-level debugging~~ using UART1 を選択 Kernel hacking > arm Debugging > Early printk

設定後、Exitで戻りyesを選択し設定を保存しコマンド入力状態に戻る。

下記コマンドでコンパイル

zybomake LOADADDR=0x2080000 zybomake uImage

生成されたlinux-xlnx/arch/arm/boot/uImageをSDカードのBOOTパーティションにコピーし、
linux-xlnx/arch/arm/boot/dts/zynq-zybo.dtbをSDカードのBOOTパーティションにコピーしdevicetree.dtbにリネームする。

ルートファイルシステムの作成

あとはSDカードの第2パーティション(ext4にフォーマットした領域)にルートファイルシステムを構築すればよい。
方法はいろいろあるがここではdebootstrapを使うこととする。
僕の場合ext4領域がVirtualBox環境でしかアクセスできなかったのでVirtualBox上のUbuntu20.04で実行した。

まずはSDカードの第2パーティションをloopでマウントする。(自動でマウントされてる場合はいったんアンマウントしてから)

sudo mount -o loop /dev/sdb3 /mnt

なぜSDカードをループバックデバイスとしてマウントするのかは調べてもよくわからなかった。

debootstrapでSDカードにUbuntuをダウンロードする。ここでは20.04LTS(focal)を指定した。

sudo debootstrap --foreign --arch armhf focal /mnt/

プロキシ環境下ではsudoの後にhttp_proxy=$http_proxyと記述しておけばよい。(exportコマンド等でhttp_proxyは指定してある前提)
コマンド末尾にダウンロードサーバ(http://ports.ubuntu.com/ とかその他ミラーサーバとか)を記述することもできる。
Failed getting release fileなどで終了するときはほかのミラーサーバを指定すると良い。

以下debian11 の場合

sudo debootstrap --foreign --arch=armhf bullseye /mnt/ http://ftp.yz.yamagata-u.ac.jp/debian/

エミュレータをSDカードにコピーしておく。

sudo cp /usr/bin/qemu-arm-static /mnt/usr/bin/

chrootでrootをSDカードにする

sudo chroot /mnt

下記コマンドでdebootstrapを完了させる。

./debootstrap/debootstrap --second-stage

passwdコマンドでパスワードを設定。

その後ユーザーを追加する。

su adduser ユーザー名

exitでSDカードから抜けたら完成。

ZYBOでLinuxを起動

vivadoで作成されたビットストリームファイルをfpga.bitという名前にしてSDカードのBOOTパーティションに入れる。

microBケーブルでPCと接続しteraterm等で接続、その後電源をONするとu-bootが立ち上がったあと自動でUbuntuが立ち上がる。
さっき作成したユーザーでログイン可能。

0 件のコメント:

コメントを投稿