Simple framebufferを有効にする
Linux上からディスプレイに出力する方法を調べているとSimple framebufferという物がある様なのでqemu上で試したメモ。
qemuは前回のqemu2svの環境を流用。
qemu側の変更点
sysbus_create_simple("hw_if", 0xE1000000, NULL);
kernel側の変更点
make menuconfig
を実行
Simple framebuffer supportを有効にする。
Device Drivers→Graphics support→Support for frame buffer deviceと選択する。
device treeに以下を追加
ps7_fb: framebuffer@E1000000 { compatible = "simple-framebuffer"; reg = <0xE1000000 (800 * 600 * 2)>; width = <800>; height = <600>; stride = <(800 * 2)>; format = "r5g6b5"; };
ひな形は↓にあった。
Documentation/devicetree/bindings/video/simple-framebuffer.txt
qemu起動
起動後にdmesg
を実行するとログ内でsimple framebufferが認識しているのがわかる。
simple-framebuffer e1000000.framebuffer: framebuffer at 0xe1000000, 0xea600 bytes, mapped to 0xf010000 0 simple-framebuffer e1000000.framebuffer: format=r5g6b5, mode=800x600x16, linelength=1600
また、/dev/fb0
が追加されている。
もうちょっと確認する
hw_if.cを修正する。
hw/char/hw_if.c
static void hw_if_write(void *opaque, hwaddr offset,uint64_t value, unsigned size){ if (value != 0) { printf("write::%lx %lx %x\n",offset >> 2,value,size); } }
value != 0
がないと黒のドットがすべてprintされるので0以外を出力している。
この状態でecho -ne "a" > /dev/fb0
とやってみた。
zynq> echo -ne "a" > /dev/fb0 write::0 61 1
0x61はASCIIコードで"a"なのでライトできてる様です。
実機に実装する際はデュアルポートメモリを置いて片方は0xE1000000にバスからライトして片方はVGAなりHDMIなりに同期信号付けて渡せば動作しそう。
リフレッシュレートの設定が見つからないけどLinuxは同期をどうしてるんだろう?書けるだけ書いているのかな?