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をインストールします。
ライブラリとヘッダファイルがインストールされたディレクトリを調べて、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は終了しました。
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/"
いけー!
無事に通りました!bootgenのビルドも結構時間がかかりました。
bootgenが出来上がったら、とりあえず実行してみましょう。
なんかいい感じで動いています。
そうしたら、bifファイルを作り、
the_ROM_image:
{
[bootloader]./FSBL.elf
./cosmoz_main_wrapper.bit
./u-boot.elf
}
fsbl.elfとu-boot.elfをZYNQのシステム上にコピーしておいて、bootgenを実行します。
ちゃんとbootgenが動いてboot.binを生成してくれました。
Windows上のbootgenで作ったboot.binとdiffやcmpで比べてみても、1バイトの違いもなく同じものが出来ていました。
上の手順で生成したbootgenをダウロードできるようにしておきます。自分でビルドするのが面倒だという方はご利用ください。
■追記■
さらに、Webのインタフェースからできるようにしてみました。
「boot.binまたは.bitを送信」というボタンを押して、ファイルを選択します。
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;
}
bitを選択するとbootimage.bifを生成し、bootgenを起動し、boot.binが作られます。
実行結果も表示するようにしました。
これで、ZYNQ Linux上に作りこんだWeb管理画面でbitstreamを送信して、内部でboot.binを生成して自動的に置き換えてくれるようになりました。
ZYNQデザインのアップデートがWebで完結するようになりました。
| 固定リンク
コメント