Petalinux2018.3でPLクロックを動的に変更する

(52d) 更新


電気回路/zynq

@ikwzm さんの fclkcfg を使うと ZYNQ の PL クロックを動的に変更できるそうです

ありがたく使わせていただこうと。

https://qiita.com/ikwzm/items/aae3dab578e28c13bc65

ZYNQ 上でビルドしようとした(失敗)

LANG:console
$ cd
$ git clone https://github.com/ikwzm/fclkcfg.git
$ cd fclkcfg
$ make
 make[1]: *** /lib/modules/4.14.0-xilinx-v2018.3/build: No such file or directory
$ ls -l /lib/modules/4.14.0-xilinx-v2018.3/build
 -> /home/takeuchi/petalinux/zturn-v2018.3/kernel-source

カーネルソースをコピーしてきておかなければならないらしい?

VirtualBox 内の /home/takeuchi/petalinux/zturn-v2018.3/kernel-source を SD カードにコピーした。

LANG:console
$ make
 make -C /lib/modules/4.14.0-xilinx-v2018.3/build ARCH=arm CROSS_COMPILE= M=/home/takeuchi/fclkcfg modules
 make[1]: Entering directory '/home/takeuchi/petalinux/zturn-v2018.3/kernel-source'
 CC [M]  /home/takeuchi/fclkcfg/fclkcfg.o
 /bin/sh: 1: scripts/basic/fixdep: Exec format error
 scripts/Makefile.build:320: recipe for target '/home/takeuchi/fclkcfg/fclkcfg.o' failed
 make[2]: *** [/home/takeuchi/fclkcfg/fclkcfg.o] Error 2
 Makefile:1503: recipe for target '_module_/home/takeuchi/fclkcfg' failed
 make[1]: *** [_module_/home/takeuchi/fclkcfg] Error 2
 make[1]: Leaving directory '/home/takeuchi/petalinux/zturn-v2018.3/kernel-source'
 Makefile:19: recipe for target 'all' failed
 make: *** [all] Error 2
$ file /home/takeuchi/petalinux/zturn-v2018.3/kernel-source/scripts/basic/fixdep
 scripts/basic/fixdep: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=5def8822765297e3272f03d4266380832bc46626, not stripped

kernel source の下に x86-64 の実行ファイルがあって、それが arm 上では動かないのが問題。

うん、まあこれは、そのままコピーしてきてもダメってことだね。

Petalinux 上でビルドした方が楽そうだ。

追記: やはり @ikwzm さんがこの問題についても記事にしてくださっていました。
https://qiita.com/ikwzm/items/0aa165fa21fa9cca15c0

Petalinux 上でビルド

環境変数を指定しないとクロスコンパイルにならず、x86-64 用のコードができてしまうため注意。

Petalinux 上で、

LANG:console
$ cd 
$ git clone https://github.com/ikwzm/fclkcfg.git
$ cd fclkcfg
$ KERNEL_SRC_DIR=/home/takeuchi/petalinux/zturn-v2018.3/kernel-source/ ARCH=arm make
 make -C /home/takeuchi/petalinux/zturn-v2018.3/kernel-source/ ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- M=/home/takeuchi/fclkcfg modules
 make[1]: ディレクトリ '/home/takeuchi/petalinux/zturn-v2018.3/kernel-source' に入ります
   CC [M]  /home/takeuchi/fclkcfg/fclkcfg.o
   Building modules, stage 2.
   MODPOST 1 modules
   CC      /home/takeuchi/fclkcfg/fclkcfg.mod.o
   LD [M]  /home/takeuchi/fclkcfg/fclkcfg.ko
 make[1]: ディレクトリ '/home/takeuchi/petalinux/zturn-v2018.3/kernel-source' から出ます
$ file fclkcfg.ko
 fclkcfg.ko: ELF 32-bit LSB relocatable, ARM, EABI5 version 1 (SYSV), BuildID[sha1]=9bc1d739156d3cdd06c3a28be79d8717eaf0541b, not stripped
$ mount /mnt/sdcard2
$ cp -r * /mnt/sdcard2/home/takeuchi/fclkcfg
$ umount /mnt/sdcard2

ちゃんと arm32 用の fclkcfg.ko を作成できたので SD カードに入れた。

動作確認

z-turn ボードを立ち上げて、

LANG:console
$ cd /home/takeuchi/fclkcfg
$ sudo insmod fclkcfg.ko
$ ls /sys/class/fclkcfg
$ # device tree を指定していないため今は空っぽ
$ cat > fclkcfg_zynq.dtos
 /dts-v1/;/plugin/;
 / {
     fragment@0 {
         target-path = "/amba";
         __overlay__ {
             fclk0 {
                 compatible    = "ikwzm,fclkcfg-0.10.a";
                 clocks        = <&clkc 15>;
             };
             fclk1 {
                 compatible    = "ikwzm,fclkcfg-0.10.a";
                 clocks        = <&clkc 16>;
             };
             fclk2 {
                 compatible    = "ikwzm,fclkcfg-0.10.a";
                 clocks        = <&clkc 17>;
             };
             fclk3 {
                 compatible    = "ikwzm,fclkcfg-0.10.a";
                 clocks        = <&clkc 18>;
             };
         };
     };
 };
 ^D
$ dto fclkcfg fclkcfg_zynq.dtos
$ ls /sys/class/fclkcfg/
 amba:fclk0  amba:fclk1  amba:fclk2  amba:fclk3
$ cat /sys/class/fclkcfg/amba\:fclk0/enable
 1
$ cat /sys/class/fclkcfg/amba\:fclk0/rate
 100000000
$ echo 250000000 | sudo tee /sys/class/fclkcfg/amba\:fclk0/rate 
 250000000
$ cat /sys/class/fclkcfg/amba\:fclk0/rate
 250000000

簡単だった。

fclkcfg.ko を自動で読み込ませる

http://www.silex.jp/blog/wireless/2015/08/linux.html より:

modprobe を適切に動作させるためには幾つかのルールを守らなければなりません。まず、modprobe で扱うモジュールは全て規定のディレクトリに収められていなければなりません。通常、これは /lib/modules/<KernelVersion> 下に置かれています。 しかし *.ko ファイルを /lib/modules/<KernelVersion> 下に置くだけではまだ不十分で、/lib/modules/<KernelVersion> 下のカーネルファイルの一覧が modules.dep ファイル(およびそのバイナリ版である modules.dep.bin) に登録されていなければなりません。この登録は「depmod」コマンドを /lib/modules/<KernelVersion> 下で実行することによって行われます(※註)。

(※註) つまり、/lib/modules 下に何らかの変更(追加、削除、置き換え)をするたびに depmod を実行しなければ modprobe の動作は保証されない、ということです。デスクトップ Linux のセルフ環境では make modules_install などのスクリプトによって /lib/modules への *.ko ファイルコピーと depmod の実行が自動で行われたりしますが、組み込み系のクロス開発環境では誰がどこでどうやって *.ko をコピーし depmod を実行するかは環境によってまちまちなので、何も考えずに手作業で *.ko だけ追加コピーして「動かない」というトラブルになりがちです。また depmod は「一覧を作る」だけが仕事で同名のモジュールを持つファイルが複数あることの警告なども出してくれないので、新しいドライバをインストールしたつもりが modprobe は残っている古いドライバを使い続けていた、なんてトラブルも割とよくあります。

ふむ。

初期値を uEnv.txt で指定

https://qiita.com/ikwzm/items/3253940484591da84777 を参考にすれば良かった。

slcr_unlock_cmd=mw.l 0xF8000008 0xDF0D
slcr_lock_cmd=mw.l 0xF8000004 0x767B
fpga_set_cmd=run slcr_unlock_cmd && mw.l 0xF8000170 0x00101400 && run slcr_lock_cmd

のように書いておいて、適当なところで fpga_set_cmd を呼べば良い。

詳細は後で書く。

コメント・質問





Counter: 210 (from 2010/06/03), today: 2, yesterday: 2