前回のUltra96ネタでは、ボードのチュートリアルを一通り試してみて、付属のマイクロSDの環境やVivado&SDKを使うことで基本的な開発を行うことが出来る感触を得た。
今回はせっかくのZynqボードなので、PS領域のブートローダーやLinux環境を構築して、マイクロSDからブートするイメージを自分で立ち上げてみようと思う。
Ultra96 ボード用ブートローダー&Linux
既に色々な方がUltra96用のLinux立ち上げの記事も書いてくださっていて、とても参考になった。特にikwzmさんの記事。
Zynqのブートシーケンスの記事を読めば、大体何がどう動いていて、それを作るために何が必要なのか、、、といったことがつかめると思う。
また、Ultra96向けのDebian GNU/Linuxの記事も書いてくださっていています。
で、今回は上記の記事でなんとなく概要を掴んだ上で、Ultra96用のPetaLinuxの構築を以下のガイド見ながら試していこうと思う。
関連パッケージのインストール
PetaLinuxは結構な数の依存パッケージが存在しているので、まずはそれをインストールする必要がある。筆者の環境(Ubuntu16.04LTS)で必要になるのは以下のツールorライブラリだ
- python (3.4.0)
- dos2unix
- ip
- gawk
- xvfb
- gcc
- git
- make
- netstat
- ncurses devel
- tftp server(使わない場合は不要)
- zlib devel(32bit版も必要)
- openssl devel
- flex
- bison
- libselinux
- gnupg
- wget
- diffstat
- chrpath
- socat
- xterm
- autoconf
- libtool
- tar
- unzip
- texinfo
- zlib1g-dev
- gcc-multilib
- build-essential
- libsdl1.2-dev
- libglib2.0-dev
- screen
- pax
- gzip
その他のプラットフォームをお使いの場合は、Xilinxの資料をチェック。
因みに必要なパッケージが入っていないとPetaLinuxのインストーラを起動した時にチェックが行われて、そこでエラーで終了する。その際に必要なパッケージを表示してくれるので、とりあえずPetaLinuxのインストーラを実行して、表示されたの入れても良いかもしれない。
PetaLinuxのインストール
まずはPetaLinuxのインストーラを取得してインストールするところから。
Ultra96はPetaLinuxの2018.2がサポートされていることが明言されていて2018.2のページにはUltra96用のBSPも公開されているので今回はそれを使う(要Xilinxのアカウント)。
上記のページから以下の2つをダウンロードする。
- PetaLinux 2018.2 Installer
- Ultra96 BSP
インストールしたインストーラを以下の感じで実行する
$ ./petalinux-v2018.2-final-installer.run <インストール先>
インストール先を省略することも可能だが、その場合はインストーラの実行ディレクトリにインストールされるので注意が必要だ。
インストーラを実行すると、ライセンスに関しての選択があるのでYesを選択して、後は放置しよう。
INFO: Checking installer checksum... INFO: Extracting PetaLinux installer... LICENSE AGREEMENTS PetaLinux SDK contains software from a number of sources. Please review the following licenses and indicate your acceptance of each to continue. You do not have to accept the licenses, however if you do not then you may not use PetaLinux SDK. Use PgUp/PgDn to navigate the license viewer, and press 'q' to close Press Enter to display the license agreements ## この後にライセンスのテキストが開くので"q"を押して終了 Do you accept Xilinx End User License Agreement? [y/N] > (同意なら"y")
これが終わるとインストールが始まってしばらくすると正常に終わるはず。
プロジェクトの作成
PetaLinuxの環境設定
PetaLinuxのインストールが完了したら適当なディレクトリに移動して、PetaLinuxのプロジェクトを作成しよう。その際にまずはPetaLinuxの環境設定が必要になるので、以下を実行。
$ cd <petalinux-install-directory> $ source peta/settings.sh
因みにUbuntuを使っていると、/bin/sh
の実体がdash
になっており、警告が表示される。変更したい場合は以下の要領で/bin/sh
のリンク先をbash
に切り替えよう。
$ rm /bin/sh $ ln -s /bin/bash /bin/sh
PetaLinuxのプロジェクト作成
PetaLinuxのインストーラと一緒にダウンロードしたUltra96のBSPを-s
オプションに指定してプロジェクトを作成する。
$ petalinux-create -t project -s <path-to>/xilinx-ultra96-reva-v2018.2-final.bsp
すると実行したディレクトリの下に以下のディレクトリが作成されるはずだ。
- xilinx-ultra96-reva-2018.2
デザインしたPL領域の取り込み
petalinux-create
が終わるとビルドをすることは可能なのだが、ただ単に標準のフローに従うと前回作ったメモリだけがインスタンスされているPL領域が作成されるデータには含まれなくなってしまう。
そのため、今回はもう1ステップ挟むことにする。
$ petalinux-config --get-hw-description=<Vivadoで生成できる*.hdfファイルのあるディレクトリ>
上記のコマンドを実行すると、HDFファイルに含まれているPS領域のレジスタ設定プログラムがプロジェクト内部に取り込まれるようになる。以下のようなログの後にプロジェクトの設定画面が開くので、何もせずにExit
を選んで終了する。
INFO: Getting hardware description... INFO: Rename ultra96_trial_wrapper.hdf to system.hdf [INFO] generating Kconfig for project
PetaLinuxのビルド
ここまで来たら後はビルドするだけ。以下のコマンドを実行してビルドが終わるのを気長にまとう。
$ petalinux-build
このコマンドを実行すると中でYoctoのbitbake
コマンドが走り、必要なパッケージのダウンロード、設定、ビルドが走る。個人的にはこの作業を行う際には高速なストレージ上でやることをおすすめしたい。(HDDだとランダムアクセス発生しすぎて時間かかる&結果が安定しない→Ultra96向けの作業では最後の方のタスクが8時間位放置しても終わらなかった。)
もう一点ハマったこととしては、ビルドの終盤の処理でLinuxのrootfsを作る際にext3/ext4向けのビルドが失敗するというものがあった。これはその時の筆者の作業環境がzfsで作られたファイルシステムになっており、zfs上だと失敗するというものだった。どうも必要なサイズの計算が狂って、ext3/ext4のファイルに必要なデータを詰める際にディスクフルになった模様。Yoctoの設定を修正するbbappend
作れば回避できそうというコメントも見かけたが、対応するタスク探すのが面倒だったため、ディスク変更して事なきを得た。
BOOT.BINの生成
正常にpetalinux-build
コマンドが終了すると、プロジェクト直下にimages
というディレクトリが出来ており、その中に各種成果物が格納されているはずだ。
-rw-r--r-- 1 dnn-admin dnn-admin 14684672 12月 29 01:01 Image -rw-r--r-- 1 dnn-admin dnn-admin 3278371 12月 29 01:01 System.map.linux -rw-r--r-- 1 dnn-admin dnn-admin 51152 12月 29 00:58 bl31.bin -rw-r--r-- 1 dnn-admin dnn-admin 150248 12月 29 00:58 bl31.elf -rw-r--r-- 1 dnn-admin dnn-admin 6999348 12月 29 01:01 image.ub -rw-r--r-- 1 dnn-admin dnn-admin 118408 12月 29 01:03 pmufw.elf -rw-r--r-- 1 dnn-admin dnn-admin 1141345792 12月 29 01:06 rootfs.cpio -rw-r--r-- 1 dnn-admin dnn-admin 357363543 12月 29 01:06 rootfs.cpio.bz2 -rw-r--r-- 1 dnn-admin dnn-admin 404942175 12月 29 01:06 rootfs.cpio.gz -rw-r--r-- 1 dnn-admin dnn-admin 404942239 12月 29 01:06 rootfs.cpio.gz.u-boot -rw-r--r-- 1 dnn-admin dnn-admin 1630629888 12月 29 01:06 rootfs.ext3 -rw-r--r-- 1 dnn-admin dnn-admin 359294137 12月 29 01:06 rootfs.ext3.bz2 -rw-r--r-- 1 dnn-admin dnn-admin 1630629888 12月 29 01:06 rootfs.ext4 -rw-r--r-- 1 dnn-admin dnn-admin 408489496 12月 29 01:07 rootfs.ext4.gz -rw-r--r-- 1 dnn-admin dnn-admin 536346624 12月 29 01:07 rootfs.jffs2 -rw-r--r-- 1 dnn-admin dnn-admin 74522 12月 29 01:05 rootfs.manifest -rw-r--r-- 1 dnn-admin dnn-admin 357618745 12月 29 01:05 rootfs.tar.bz2 -rw-r--r-- 1 dnn-admin dnn-admin 406125713 12月 29 01:06 rootfs.tar.gz -rw-r--r-- 1 dnn-admin dnn-admin 302812 12月 29 01:05 rootfs.testdata.json -rw-r--r-- 1 dnn-admin dnn-admin 5568793 12月 29 00:45 system.bit -rw-r--r-- 1 dnn-admin dnn-admin 37055 12月 29 00:57 system.dtb -rw-r--r-- 1 dnn-admin dnn-admin 581000 12月 29 00:58 u-boot.bin -rw-r--r-- 1 dnn-admin dnn-admin 647328 12月 29 00:58 u-boot.elf -rw-r--r-- 1 dnn-admin dnn-admin 217007744 12月 29 01:01 vmlinux -rw-r--r-- 1 dnn-admin dnn-admin 114984 12月 30 12:20 zynqmp_fsbl.elf
このデータからブート用に各種データを詰めて一つのファイルにまとめたBOOT.BINというファイルを生成する。
$ petalinux-package --boot --fsbl components/plnx_workspace/fsbl/fsbl/Release/fsbl.elf --fpga <自分で作ったbitファイルデータのパス> --pmufw components/plnx_workspace/pmu-firmware/pmu-firmware/Release/pmu-firmware.elf --u-boot --force
冒頭で紹介したチュートリアルのリンク先では、上記コマンドで読み込む"*.bit"ファイルがBSP付属の物になっているが、その部分を自分で合成したPL領域のデータを含む"*.bit"に変更する必要があるのでそこだけ注意。
因みに--force
は二回目以降にBOOT.BIN
が存在している場合にのみ必要なのだが、あっても問題ないのでつけてます。
マイクロSDの更新
今回は面倒だったのでUltra96付属のマイクロSDのパーティション構成をそのまま流用して、しかも作ったrootfsは使わずにブートイメージだけを更新して使うことにした。
そのための作業は以下の通り。
- マイクロSD認識させて"boot"というパーティションに以下の2つのファイルをコピーする
テスト用のプログラムのビルド
今回はPL領域のメモリが追加された状態のイメージを作成しているので、そこにほんとにアクセスが出来ているかも確認しておきたい。
そのためには本来Linux用のテストドライバを書いたり、、とかするのが真っ当な手ではあるのだが、デバイスツリーいじったり、ドライバ書いたり、、、と面倒なのでLinuxの/dev/mem
を使ってダイレクトにメモリにアクセスして確認を行った。
手順は簡単で、以下のgithubのプログラムをSDK上でa53-Linux向けにビルドするだけである。
ビルドして出来上がったELFファイルをマイクロSDのrootfs上の/home/root
のしたあたりに放り込んだら準備完了。前回と同様にminicom
の設定を行い、Ultra96を起動しよう。
起動したら以下の様にdevmem2.elf
を実行する
$ ./Devmemx.elf -r 0xa0000000 w 0xdeadbeaf
-r
はライトを実行すると、直後にリードを行い結果を表示してくれるオプションだ。
実行結果は以下。
Written 0xdeadbeaf; readback 0xdeadbeaf
正常に書いた値が読めていることが確認できる。
この時の波形を取得したものが以下の画像で、正常にAXIのライト→リードが実行されていることが確認できた。
今回は、PetaLinuxを使ってマイクロSDからのブートを試してみた。手順としては一通り確認できたので、次はLinuxの簡単なドライバを書いて確認してみようと思う。