« FPGAロックインアンプの誤差の原因は何? | トップページ | ZYNQの管理者パネル「zynq-admin」をgithubで公開 »

2022.04.24

ZYNQのLinux上でbootgenを動かして、boot.binをセルフで書き換える

ZYNQの起動ファイル「boot.bin」は、bootgenというコマンドを使って、BitStreamとfsbl.elfとu-boot.elfを固めて作ります。

通常のZYNQ開発の手順では、FPGAの論理合成が終わったらホストPC上でbootgenコマンドを実行してBitStreamからboot.binを作り、SCPなどの手段を使ってZYNQのシステムに転送して、boot.binを置き換えて新しいデザインで動かすことになります。

バッチファイルにしておけばboot.binを作る毎回のコマンド操作はしなくてもよくなりますが、それでも

  • bootgenでbit→boot.binを作る
  • ZYNQ Linuxのシステムに転送する
  • 転送した先のLinuxでboot.binを置き換える
  • rebootする

という4つの手順を踏むことになり、面倒です。

できれば出来上がったBitStreamをZYNQのLinuxのシステムに送れば自動的にboot.binを作って新しいデザインで再起動してほしいものです。

そこで、ZYNQ Linux上でbootgenを動かす方法を調べました。

 

bootgenのソースコード自体はXilinxのgithubからダウンロードすることができます。

https://github.com/Xilinx/bootgen

これはARMのLinux用にコンパイルして動くと書かれていますので、やってみました。

ZYNQのLinux上で、

git clone https://github.com/Xilinx/bootgen

でダウンロードします。OpenSSLのライブラリが必要と書かれているので、次に、

sudo apt install libssl-dev

でlibssl-devをインストールします。

Libssl

ライブラリとヘッダファイルがインストールされたディレクトリを調べて、makeのコマンドは以下のようにします。

make "LIBS=/usr/lib/arm-linux-gnueabihf/libssl.a /usr/lib/arm-linux-gnueabihf/libcrypto.a -ldl -lpthread" "INCLUDE_USER=-I/usr/include/openssl -I/usr/include/arm-linux-gnueabihf/openssl"

さて、これでビルドができるかと思ったのですが、

authkeys.cpp: In member function 'uint8_t Key::ParseOpenSSLKey(FILE*)':
authkeys.cpp:198:32: error: 'RSA_get0_n' was not declared in this scope
keySzRd = BN_num_bytes(RSA_get0_n(rsaInst.rsa));
^
authkeys.cpp:198:32: note: suggested alternative: 'RSA_get0_key'
authkeys.cpp:207:19: error: 'RSA_get0_d' was not declared in this scope
memcpy(D, RSA_get0_d(rsaInst.rsa)->d, keySize);
^~~~~~~~~~
authkeys.cpp:207:19: note: suggested alternative: 'RSA_get0_key'
memcpy(D, RSA_get0_d(rsaInst.rsa)->d, keySize);
・・・

というエラーが大量に出て、ビルドは失敗!!

エラーメッセージによればRSA_get0_dという関数がないようです。

調べてみると、RSA_get0_dはOpenSSLの1.1.1から使用できるようになった関数で、Ubuntu18のARM版ではaptでインストールされるlibssl-devのバージョンは1.1.0gどまりのようです。

仕方がないので、OpenSSLから1.1.1nのソースコードをダウンロードして解凍してビルドします。

やり方は、

wget https://www.openssl.org/source/openssl-1.1.1n.tar.gz
tar -xvf openssl-1.1.1n.tar.gz
./config --openssldir=/home/cosmoz/openssl
make

configureのオプション --openssldir= で指定しているのはインストール先のディレクトリです。

cosmoz@cosmoz:~/openssl/openssl-1.1.1n$ ./config --openssldir=/home/cosmoz/openssl
Operating system: armv7l-whatever-linux2
Configuring OpenSSL version 1.1.1n (0x101010efL) for linux-armv4
Using os-specific seed configuration
Creating configdata.pm
Creating Makefile
**********************************************************************
*** ***
*** OpenSSL has been successfully configured ***
*** ***
*** If you encounter a problem while building, please open an ***
*** issue on GitHub <https://github.com/openssl/openssl/issues> ***
*** and include the output from the following command: ***
*** ***
*** perl configdata.pm --dump ***
*** ***
*** (If you are new to OpenSSL, you might want to consult the ***
*** 'Troubleshooting' section in the INSTALL file first) ***
*** ***
**********************************************************************

何も苦労することなく、configureとmakeは終了しました。

Build_ssl

makeは40分程度かかりました。 

次にbootgenのビルドです。makeのオプションにはopensslをインストールしたディレクトリを指定します。

make "LIBS=/home/cosmoz/openssl/openssl-1.1.1n/libssl.a /home/cosmoz/openssl/openssl-1.1.1n/libcrypto.a -ldl -lpthread" "INCLUDE_USER=-I/home/cosmoz/openssl/openssl-1.1.1n/include/"

Build_start

いけー!

Building

無事に通りました!bootgenのビルドも結構時間がかかりました。

bootgenが出来上がったら、とりあえず実行してみましょう。

Bootgen

なんかいい感じで動いています。

 

そうしたら、bifファイルを作り、

the_ROM_image:
{
[bootloader]./FSBL.elf
./cosmoz_main_wrapper.bit
./u-boot.elf
}

fsbl.elfとu-boot.elfをZYNQのシステム上にコピーしておいて、bootgenを実行します。

Bootgendone

ちゃんとbootgenが動いてboot.binを生成してくれました。

Windows上のbootgenで作ったboot.binとdiffやcmpで比べてみても、1バイトの違いもなく同じものが出来ていました。

 

上の手順で生成したbootgenをダウロードできるようにしておきます。自分でビルドするのが面倒だという方はご利用ください。

ダウンロード - bootgen

 

■追記■

さらに、Webのインタフェースからできるようにしてみました。

「boot.binまたは.bitを送信」というボタンを押して、ファイルを選択します。

Webui1

ZYNQの上ではPerlのスクリプトをCGIとして動かして、.binファイルが選択されればそのままSDカードに転送し、.bitファイルが選択されればbootgenを起動するようにしました。

スクリプトのコアの部分を抜粋します

my ($base_name, $dir, $suffix) = fileparse($in{'filename'}, '.bit');
if ($suffix eq '.bit') {
my $biffile = "/home/share/mkboot/bootimage.bif";
open(OUT, "> $biffile");
print(OUT "the_ROM_image:\n");
print(OUT "{\n");
print(OUT " [bootloader]/home/share/mkboot/FSBL.elf\n");
print(OUT " $tmpfile\n");
print(OUT " /home/share/mkboot/u-boot.elf\n");
print(OUT "}\n");
close(OUT);
print("------boot.binを生成します------\n");
system("/home/share/mkboot/bootgen -w -image /home/share/mkboot/bootimage.bif -o i /home/share/mkboot/boot.bin 2>&1");
print("------/mntにコピーします------\n");
system("echo $in{'password'} | sudo -S cp -p /home/share/mkboot/boot.bin /mnt/boot.bin");
print("------/mntの状況------\n");
system("ls -altr /mnt/boot.bin");
unlink $biffile;
}

Fileselect

bitを選択するとbootimage.bifを生成し、bootgenを起動し、boot.binが作られます。

実行結果も表示するようにしました。

Webui

これで、ZYNQ Linux上に作りこんだWeb管理画面でbitstreamを送信して、内部でboot.binを生成して自動的に置き換えてくれるようになりました。

ZYNQデザインのアップデートがWebで完結するようになりました。

 

|

« FPGAロックインアンプの誤差の原因は何? | トップページ | ZYNQの管理者パネル「zynq-admin」をgithubで公開 »

コメント

コメントを書く



(ウェブ上には掲載しません)




« FPGAロックインアンプの誤差の原因は何? | トップページ | ZYNQの管理者パネル「zynq-admin」をgithubで公開 »