FC2カウンター FPGAの部屋 ZedBoard用Digilent Linuxの解析1(フレームバッファの領域確保)
FC2ブログ

FPGAやCPLDの話題やFPGA用のツールの話題などです。 マニアックです。 日記も書きます。

FPGAの部屋

FPGAの部屋の有用と思われるコンテンツのまとめサイトを作りました。Xilinx ISEの初心者の方には、FPGAリテラシーおよびチュートリアルのページをお勧めいたします。

ZedBoard用Digilent Linuxの解析1(フレームバッファの領域確保)

このごろ、ZedBoard用Digilent Linuxの解析をしている。Digilent Linuxを起動するとHDMIに2頭のペンギンが表示されるが、このフレームバッファを使用して、カメラの画像を書き込みたいからだ。フレームバッファは固定アドレスでなく、アロケートされているようで、物理アドレスが異なる時があるようだ。そのアドレスを取得して、自作カスタムIPのレジスタに物理アドレスを書き込むのを目的とする。つまり、安全にフレームバッファをカメラ画像用に使用する目的のためにLinuxを解析しようと思っている。Linuxのバージョンは下を参照のこと。

[ 0.000000] Linux version 3.6.0-digilent-13.01 (masaaki@masaaki-VirtualBox) (gcc version 4.6.3 (Sourcery CodeBench Lite 2012.03-79) ) #1 SMP PREEMPT Sun Mar 3 06:20:07 JST 2013


最初に、フレームバッファをアロケートしているのは、linux-digilent-master/drivers/gpu/drm/drm_fb_cma_helper.c の drm_fbdev_cma_create() のようだ。

struct fb_info *fbi;


を宣言して、

fbi = framebuffer_alloc(0, dev->dev);


で領域を確保している。
他にも領域を確保しているので、実体は違うのかもしないが、この関数でフレームバッファを確保しようとしているのはわかった。
そこで、下のようにprintk()を挿入してアドレスを確認してみた。

dev->mode_config.fb_base = (resource_size_t)obj->paddr;
fbi->screen_base = obj->vaddr + offset;
printk("fbi->screen_base = 0x%x\n" ,fbi->screen_base); // DEBUG Message by Masaaki
fbi->fix.smem_start = (unsigned long)(obj->paddr + offset);
printk("fbi->fix.smem_start = 0x%x\n" ,fbi->fix.smem_start); // DEBUG Message by Masaaki
fbi->screen_size = size;
printk("fbi->screen_size = 0x%x\n" ,fbi->screen_size); // DEBUG Message by Masaaki
fbi->fix.smem_len = size;


これで、カーネル・イメージをMakeして、SDカードにコピーして起動してみた。その結果を下に示す。

1回目

[ 0.960000] fbi->screen_base = 0xe08b1000
[ 0.960000] fbi->fix.smem_start = 0x19000000
[ 0.960000] fbi->screen_size = 0x7e9000


2回目

[ 1.030000] fbi->screen_base = 0xe08b1000
[ 1.030000] fbi->fix.smem_start = 0x19000000
[ 1.030000] fbi->screen_size = 0x7e9000


3回目

[ 1.010000] fbi->screen_base = 0xe08b1000
[ 1.010000] fbi->fix.smem_start = 0x19000000
[ 1.010000] fbi->screen_size = 0x7e9000


4回目

[ 1.360000] fbi->screen_base = 0xe08b1000
[ 1.370000] fbi->fix.smem_start = 0x19800000
[ 1.370000] fbi->screen_size = 0x7e9000


5回目

++ Setting up mdev
[ 1.320000] new mode: 1280x720 1650x750 74250
[ 1.320000] new mode: 1920x1080 2200x1125 74250
[ 1.330000] new mode: 1920x1080 2200x1125 148500
[ 1.330000] new mode: 720x576 864x625 27000
[ 1.340000] new mode: 720x576 864x625 27000
[ 1.340000] new mode: 1280x720 1980x750 74250
[ 1.350000] new mode: 1920x1080 2640x1125 74250
[ 1.350000] new mode: 1440x576 1728x625 54000
[ 1.360000] new mode: 1920x1080 2640x1125 148500
[ 1.380000] fbi->screen_base = 0xe08b1000
[ 1.380000] fbi->fix.smem_start = 0x19800000
[ 1.390000] fbi->screen_size = 0x7e9000
[ 1.390000] setting clock to: 148500
[ 1.390000] raw_edid: d8b15b80 7
[ 1.390000] Using YCbCr output
[ 1.440000] Console: switching to colour frame buffer device 240x67
[ 1.490000] fb0: frame buffer device
[ 1.490000] drm: registered panic notifier
[ 1.490000] [drm] Initialized analog_drm 1.0.0 20110530 on minor 0


5回目は周りも切り取ってみた。1,2,3回目はフレームバッファの物理アドレスの先頭が0x19000000番地に割り当てられているが、4,5回目は0x19800000に割り当てられている。現在のカメラ画像のフレームバッファのアドレスは0x1A000000からの固定アドレスとなっている。これでも、カメラ画像の表示に問題は無く、Linuxも正常に動作しているように見える。
ここから、アドレス決め打ちでカメラ画像表示用のカスタムIPのレジスタアドレスに書き込むこともできるが、それは出来ればやりたくない。標準的な方法では、devicetree_ramdisk.dts にIPのレジスタマップがテキストで書いてあって、それをコンパイルしたdevicetree_ramdisk.dtb をu-boot? が読んで、Linuxカーネルに知らせて、それを元にAXI VDMAのレジスタを設定しているはずだ。AXI VDMAのレジスタを設定している部分を特定して、同様に、デバイスツリーから読んだ自作カスタムIPのレジスタアドレスに書き込みたいと思っている。

なお、Linuxカーネルコードの解析に多大なる力を貸していただいた”まっちゃん”さん、ありがとうございました。

皆さん、私はよくわからないので、何か情報がありましたら、教えてください。よろしくお願いします。

次回は、デバイスツリーを作る方法とコンパイルする方法をやってみる予定だ。(自作カスタムIPの情報の入ったデバイスツリーを作れないと意味が無いので。。。)
  1. 2013年03月09日 05:28 |
  2. Linux
  3. | トラックバック:0
  4. | コメント:0

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック URL
https://marsee101.blog.fc2.com/tb.php/2406-b4698d48
この記事にトラックバックする(FC2ブログユーザー)