2016年12月4日日曜日

ZYBO26 (Linux + simple framebuffer でX Windowを動かすまで)

ZYBOでLinuxを動かし、その上で X Windowを立ち上げ X アプリを動作させることが出来た。
以下はgnome-terminalとgnome-system-monitorを起動しgnome-screenshotで撮ったscreenshotだ。


これまでDFT IPのスペクトル表示等、ZYBOのHDMIを使うデザインを作成してきたが、これらはフレームバッファを使わずデータをリアルタイムに波形化してビデオ出力していた。 しかし今後カメラ等を接続して映像を表示したり、波形にグリッドや文字等も重ねて表示したりもしたいので、フレームバッファ方式のディスプレイコントローラを作成しようと思う。が、その前にZYBO(で動くLinux)でビットマップを表示する方法について知る必要がある。 ということで、X Windowを動かせるかやってみた。

ZYBOでLinuxを動かすということについては、以前 DigilentのEmbedded Linux Hands-on Tutorial for the ZYBOで学習した(ZYBO 7 (DigilentのEmbedded Linux Hands-on Tutorial for the ZYBOを試してみる))が、この時のユーザーランド側のバイナリはramdiskに入る程の規模のものでX Window関連のバイナリは含まれていない。  ネットを検索したらEmbedded Linux Hands-on Tutorial for the ZYBOとほぼ同じ内容だが、ユーザーランドのバイナリとしてLinaroを使うTutorialのサイトが見つかった。(ZYBO Zync-7000 Development Board Work Booting Linux on the ZYBO)  そこで、今回はそのサイトの記述を参考にしてユーザーランドのバイナリとしてLinaroを使うことにした。

・ framebufferについて、
LinuxのmenuconfigでLinuxがサポートしているframebuffer deviceを調べたところ、simple framebufferというのがあることが判り、簡単そうだったのでこれを試してみることにした。この方式の場合、framebufferのアドレスとサイズ、画素数等の情報をデバイスツリーに記述するだけで良いらしい。

ZynqのPL側にはframebufferとして使えるだけのメモリは無いので、SDRAMの一部をframebufferとして使う必要がある。また、デバイスツリーにアドレス等を記述するのでデバイスドライバ内部で領域をアロケートしてそれをframebufferとして使うといった方法は、多分使えない。 カーネル起動時には既にアドレス等は決定している必要がある。そこで、ZYBOのSDRAMサイズは512MBだが、その内の496MBをLinux用とし残りの16MB(0x1F000000〜0x1FFFFFFF)をframebuffer用として使うことにした。そのため、u-boot-Digilent-Dev/include/configs/zynq_zybo.h内のSDRAM SIZEの定義と、デバイスツリーソース(Linux-Digilent-Dev/arch/arm/boot/dts/zynq-zybo.dts)のbootargsの部分を以下のように記述した。



また、simple framebufferに関するデバイスツリーソースの記述は以下のようにした。


・PS部の変更
今回使用するZynqのデザインはDigilentのzybo_base_systemを使うが、USB HOST機能関連で1箇所Zynqの設定を変更する必要がある。 ZYBOではUSB HOST機能用にUSB OTG LSIのUSB3320というデバイスを使っており、そのデバイスへのリセットはZynqのMIO46に接続されていて、GPIO経由で制御してやる必要があるのだが、zybo_base_systemではその設定がされていない。

USB HOST機能はframbufferでビットマップ表示をする事とは直接の関係は無いが、コンソール用のキーボードやマウスを使用するためにはUSB HOST機能が必要だ。

以下のようにGPIOの設定を変更した。
変更前

変更後


・ デバイスドライバの修正
このリセット制御については、デバイスドライバの修正も必要なようだ。このサイト(ZYBOのUSB修正)が参考になった。


・Display controllerとVDMAの起動
simple framebuffer用のdevice driverは下記のドキュメントにあるとおり、Display controllerやVDMA等のハードウェアの制御は行わず、それは起動時に既にセットアップが完了し動作しているという前提になっているので、セットアップはシステムの起動時に自分でやる必要がある。

今回は、FSBLのfsbl_hook.cのFsblHookBeforeHandoff 関数内でそれを行うことにした。
display controllerを設定するコードはzynq_base_systemのbase_demoの関連部分を流用した。

今回の実験では画面サイズは1024x768にすることにしたのだが、base_demoのvga_modes.hには1024x768用のパラメータが定義されていなかったため以下のように追加した。

また、display_ctl.cのDisplayInitialize関数のVMODE設定部も以下のように変更した。


・カーネルビルド
simple framebufferを使うためには、arch/arm/configs/にあるxilinx_zynq_defconfig.hにCONFIG_FB_SIMPLE=y という記述を追加する必要がある。

追加したら、make xilinx_zynq_defconfig し、次にカーネルをビルドしてuImageを作成する。

ビルドの作業は先述のサイト(ZYBO Zync-7000 Development Board Work Booting Linux on the ZYBO)のTutorialに従って行うが、その中で変更が必要な部分のみを上述した。また、ユーザーランドに使うLinaroのバイナリは以下を使用した。
https://releases.linaro.org/ubuntu/images/gnome/latest/
linaro-vivid-gnome-20151215-714.tar.gz


ここまででバイナリは準備できたので、micro sdカードに書いてZYBOにセットし起動した。

起動時のログ
simple framebufferが認識されている。

/dev/下にfb0も作られている。

メモリサイズも設定通りの496MBとなっている。


HDMI出力を見てみたら、真っ黒でたま〜にlogin画面が表示される。何か変だ。
この時点ではOSのrunlevelは5で、psコマンドで動作しているプロセスを確認したら、Xの他にgdm等も動作していた。
そこで、runlevelを3にしてX関連のプログラムを全て止めてみた。
HDMI出力を見たらlogin画面が安定して表示されるようになっていた。
そこで今度は手動でXのみを起動し、次にgnome-terminalを起動してみたところ成功した。
gdmを起動すると以下のようなエラーが表示されHDMI出力は症状が再現したので、gdmに何かあるようだ。
gdmを動かさない状態ではgnome-terminalやgnome-calculator等のアプリは正常に動作した。USB HOSTに接続したキーボードやマウス等も機能している。

動かしている様子
キーボードとマウスはUSB-HUBを介して接続している。

冒頭のスクリーンショットの再掲だが、gnome-screenshotでスクリーンショットも撮れた。
ということで、simple framebufferを使いX Windowを動かすことは出来た。
gdmは旨く動かなかったがdisplay managerにlightdm等を使うと動くかも知れないので今度試してみようと思う。


0 件のコメント:

コメントを投稿

TE0720 No.4 (BNN-PYNQを動かしてみる 2)

TE0720でBNN-PYNQを動かすことが出来た。 以下は前回に続いてBNN-PYNQが動くまでの記録。 gdb (GNU debugger)で例外が出る原因を調べてみた。 例外が発生しているのはシェアードライブラリ(python_hw-cnv-pynq.so)の中であ...