今更ですが、メモしていなかった気がするので、Tinker Board(Rockchip RK3288 搭載)で HDMI Audio を有効にする方法です。
方法は簡単で Linux の CONFIG_DRM_DW_HDMI_I2S_AUDIO を有効にすれば良いです。5/3 時点の linux-next のツリーでは、make defconfig するとこのコンフィグは n で、ビルド対象外になっています。手動で下記の設定を有効にする必要があります。
$ make menuconfig Device Drivers ---> Graphics support ---> Display Interface Bridges ---> [*] Synopsys Designware I2S Audio interface
設定とビルドがうまく行くと、下記のように i2s-i2s-hifi というちょっと変わった名前のオーディオデバイスが見えるようになるはずです。
# cat /proc/asound/pcm 00-00: USB Audio : USB Audio : playback 1 : capture 1 00-01: USB Audio : USB Audio #1 : playback 1 : capture 1 00-02: USB Audio : USB Audio #2 : playback 1 01-00: ff890000.i2s-i2s-hifi i2s-hifi-0 : : playback 1
HDMI は画像と音声が一緒に転送されますから、本来は画像側のドライバも合わせて有効にする必要があるはずです。が、画像側のドライバは defconfig で y ないし m になるようで、特殊なカーネルコンフィグを使っている人以外は気にしなくて良いでしょう。
どうして音声系のドライバだけ defconfig からハブられているのか?については謎です。私は画像側のドライバと音声側のドライバ両方とも defconfig で有効にした方が良いのでは……と思いますが、何か理由があるのでしょう。
CONFIG_DRM_DW_HDMI_I2S_AUDIO は CODEC 側なので、CPU 側のコンフィグ CONFIG_SND_SOC_ROCKCHIP_I2S も紹介しておきます。とはいえ defconfig で有効になるようなので、これも通常は気にしなくて良いでしょう。
ROCKPro64 の PCIe が動かなくて、しばらく放置(2019年 3月 16日の日記参照)していたのですが、今日久しぶりに見てみたところ、意外とあっさり直せました。
PCIe が動かなかった理由は単純で、PERST# 信号を全く制御しておらず、PCIe カードのリセットを解除していなかったためでした。それは動かないわ。
不思議なことに linux-next では ROCKPro64 以外の RK3399 搭載ボードは PCIe が使えるように対応が入っているのに、ROCKPro64 だけハブられています。悲しいので、作ったパッチを LKML にぶん投げておきました。誰かの役に立てば嬉しいですね。
ちなみに ROCKPro64 の PCIe PERST# 信号は、こんな経路で来ていました。
RK3399 GPIO2_D4 -> PCIE_PERST_L -> PCIE_PERST_3V3_L -> PERST#
我が家には PCIe のカードが 3つあります。あります、というか、わざわざ ROCKPro64 の PCIe 接続テストのために買ったという方が正しいです。
リセットを制御していない場合、基本的にはどのボードも動きません。しかし USB 拡張カードだけはたまに動きます。不思議な挙動です。カードが PERST# を無視しているのか、偶然か、深追いしていないのでわかりません。
PERST# の制御をするように直したところ、USB 3.0 カードと、SATA カードはバッチリ認識するようになりました。PCIe - PCI ブリッジカードは起動中になぜか ROCKPro64 にリセットが掛かってしまい、うまくいきませんでした。
ROCKPro64 からの給電では足りないのかと疑って、外部からブリッジカードに電源を供給してみましたが、ダメでした。PC でも使えたり使えなかったりする、割と特殊なカードらしいので、ROCKPro64 では動かないのかもしれません。
さらに調べるにせよ、何にせよ、また次の機会ですね。
メモ: 技術系の話は Facebook から転記しておくことにした。多少修正。
最近 GCC のコードを書き換えたり、デバッガで追ったり、GCC とお友達になろうとしています。まだ仲良くなれていませんが、入り口に立つまでが色々大変だったのと、間違いなく数カ月後に手順を忘れるので、方法を書き残しておこうと思います。
GCC のコードを書き換えて、結果を反映させるには、何らかの方法で GCC をビルドする必要があります。クロスビルド用ツールチェーンの構築は、昔の日記(2019年 4月 28日の日記参照)に書いたとおりです。コンパイラを追うだけで、ルートファイルシステムが必要なければ、おそらく crosstool-NG を使うのが無難です。差分ビルドがうまく行かないので、何か変更した後に再ビルドするのがちょっと面倒ですが、それ以外は簡単で便利です。
私は再ビルドが遅くてイライラしたのと、ビルドの仕組みにも興味があったので、以前の日記(2019年 4月 29日の日記参照)に書いたとおり、昔作ったクロスコンパイラをビルドする Makefile(GitHub へのリンク)を改造して使っています。ブランチは origin/develop/separate-makefile です。もうこちらを本線にしても良い気がしてきたな。
これも使い方を忘れるのでメモしておきます。手動でビルドするのとあまり変わりません。
#### ビルド用ディレクトリ $ mkdir build_my_toolchain $ cd build_my_toolchain #### 環境構築用のリポジトリ $ git clone https://github.com/katsuster/crosstool-builder $ cd crosstool-builder $ git checkout -t origin/develop/separate-makefile $ cd ../ #### GCC だけリポジトリで取得する(git diff したいから) $ git clone https://gcc.gnu.org/git/gcc.git ## GCC-8.3.0 を使う、他のバージョンでもある程度ビルドできるはず $ cd gcc $ git checkout gcc-8_3_0-release $ cd ../ #### その他の依存モジュールは tarball を使用する $ mkdir tmp $ cd tmp $ wget https://mirrors.edge.kernel.org/pub/linux/kernel/v4.x/linux-4.19.1.tar.xz $ wget https://ftp.gnu.org/gnu/binutils/binutils-2.31.1.tar.bz2 $ wget https://ftp.gnu.org/gnu/glibc/glibc-2.28.tar.xz $ wget https://ftp.gnu.org/gnu/gmp/gmp-6.1.2.tar.lz $ wget https://ftp.gnu.org/gnu/mpc/mpc-1.1.0.tar.gz $ wget https://ftp.gnu.org/gnu/mpfr/mpfr-4.0.2.tar.xz $ cd ../ #### ツールチェーンに必要なモジュール $ tar xf tmp/linux-4.19.1.tar.xz $ tar xf tmp/binutils-2.31.1.tar.bz2 $ tar xf tmp/glibc-2.28.tar.xz $ ln -s linux-4.19.1 linux $ ln -s binutils-2.31.1 binutils $ ln -s glibc-2.28 glibc #### GCC に必要なモジュール $ tar xf tmp/gmp-6.1.2.tar.lz $ tar xf tmp/mpc-1.1.0.tar.gz $ tar xf tmp/mpfr-4.0.2.tar.xz $ cd gcc $ ln -s ../gmp-6.1.2 gmp $ ln -s ../mpc-1.1.0 mpc $ ln -s ../mpfr-4.0.2 mpfr $ cd ../
自分で書いていて面倒くさいなあと思いました。スクリプトにしたほうが良かったかもしれない。もし binutils も変更したりデバッグしたければ、tarball の代わりにリポジトリをチェックアウトしてくると良いです。
$ source crosstool-builder/env.sh $ cd crosstool-builder $ make -j4 install
デフォルトでは RISC-V 64bit Linux 向けのクロスコンパイラをビルドします。env.sh を書き換えれば AArch64 や ARM 向けもビルド可能です。RISC-V 32bit 向けは gcc-static(ベアメタル用コンパイラとして使用可能)までしかビルドできません。以降は glibc のビルドでエラーになり Linux 用のクロスコンパイラはビルドできません。
$ cd crosstool-builder $ make -f gcc-static.mk -j4 install
GCC に何か修正を入れてビルドし直すときは、ビルドし直したい *.mk ファイルを指定して make します。
最近はたくさんの ARM のシングルボードコンピュータ(SBC)が市販されています。嬉しい時代になりました。これからのお買い物の参考としてリストアップしました。値段は変動するので参考です。
少し古い世代の SoC を採用したボード達です。
以前(2018年 8月 12日の日記参照)載せた情報も含んでいます。
GCC をデバッグする入り口まで辿り着くのも案外大変だったので、方法を書き残しておこうと思います。
C 言語(じゃなくても良いですが)をコンパイルする際に、gcc a.c のようにコマンドを起動します。一般的に gcc コマンドをコンパイラと呼びますが、正確にいえば gcc はコンパイラドライバ(コンパイラ、アセンブラ、リンカを順に呼び出すプログラム)です。
GCC の場合、コンパイラは cc1 という名前で、コンパイラドライバ gcc とは別のプログラムとして存在します。コンパイラの役目は高級言語(C なら *.c ファイル)からアセンブリ言語(*.s ファイル)に変換することです。
Debian の GCC 8.0 だと /usr/lib/gcc/x86_64-linux-gnu/8/cc1 に置かれています。クロスコンパイラの場合は様々ですが、crostool-NG で RISC-V 64bit Linux 向けにビルドした場合(ビルド方法は 2019年 2月 26日の日記参照)は、~/x-tools/riscv64-unknown-linux-gnu/libexec/gcc/riscv64-unknown-linux-gnu/8.2.0/cc1 に置かれます。ローカルビルドしないときは、~/x-tools をクロスコンパイラをインストールしたディレクトリで読み替えてください。
デバッガでコンパイラを追うとき、コンパイラドライバ → コンパイラだと余計な処理がたくさん挟まって邪魔なので、コンパイラ単体で起動したくなりますよね?私はなりました。特に気にならない人は読み飛ばしてください。
コンパイラ cc1 のオプションは、コンパイラドライバ gcc に渡したオプション以外にも、cc1 用のオプションが渡されます。そのため cc1 をシェルなどから手打ちで起動するのはちょっと難しいです。
しかし無理してコンパイラ cc1 のオプションを調べずとも、コンパイラドライバ gcc が渡すオプションをそのままパクれば良いです。gcc/gcc.c の execute() 関数を下記のように書き換えると、cc1 の起動オプションが表示されます。
diff --git a/gcc/gcc.c b/gcc/gcc.c
index a716f708259..e48e5cca79b 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -3084,6 +3084,12 @@ execute (void)
const char *errmsg;
int err;
const char *string = commands[i].argv[0];
+ int kkk;
+
+ printf("\n------------------------------\n");
+ for (kkk = 0; commands[i].argv[kkk]; kkk++)
+ printf("%s ", commands[i].argv[kkk]);
+ printf("\n------------------------------\n");
errmsg = pex_run (pex,
((i + 1 == n_commands ? PEX_LAST : 0)
出力は下記のようになります。この例では、コンパイラは RISC-V 32bit ベアメタル向けを使っています。
------------------------------ /home/katsuhiro/share/projects/oss/crosstool-builder-new/buildroot/libexec/gcc/riscv32-unknown-elf/8.3.0/cc1 -quiet a.c -quiet -dumpbase a.c -march=rv32gc -mabi=ilp32d -auxbase a -o /tmp/ccdd2F4Z.s ------------------------------
この情報があれば、コマンドラインから単独で起動できますし、GDB で追うこともできます。
$ gdb /home/katsuhiro/share/projects/oss/crosstool-builder-new/buildroot/libexec/gcc/riscv32-unknown-elf/8.3.0/cc1 (gdb) b main Breakpoint 1 at 0x4308a0: main. (2 locations) (gdb) r a.c -dumpbase a.c -march=rv32gc -mabi=ilp32d -auxbase a -g -O0 -Wall -fdump-tree-all-raw -fdump-rtl-all -o a.s Starting program: /home/katsuhiro/share/projects/oss/crosstool-builder-new/buildroot/libexec/gcc/riscv32-unknown-elf/8.3.0/cc1 a.c -dumpbase a.c -march=rv32gc -mabi=ilp32d -auxbase a -g -O0 -Wall -fdump-tree-all-raw -fdump-rtl-all -o a.s Breakpoint 1, main (argc=15, argv=0x7fffffffd3c8) at /home/katsuhiro/share/projects/oss/crosstool-builder-new/./gcc/gcc/main.c:36 36 toplev toplev (NULL, /* external_timer */
ブレークポイントなども仕掛けられますし、変数の値を表示することもできます。解析がかなり楽になるはずです……たぶん。
目次: RISC-V - まとめリンク
SiFive の HiFive Unleashed を購入しました。現状、世界唯一かつ最速の Linux が動作する RISC-V 64bit SoC です。
ボードには SD カードが付属しており buildroot がインストールされています。電源を入れれば Linux が起動し、ユーザ root、パスワード sifive でログインできるようになっていました。
インストールされているカーネルは、
Linux buildroot 4.15.0-00044-g2b0aa1d #1 SMP Tue Mar 20 12:18:35 PDT 2018 riscv64 GNU/Linux
でした。うーん、4.19 かと思ったら、意外と古い?
Linux と buildroot だけでは面白くないので Debian ports から riscv64 向けのパッケージを引っ張ってきて Debian の環境を構築しました。
Debian の riscv64 向けポーティングは絶賛作業中らしく、ffmpeg など用意されていないパッケージもチラホラありますが、自分で用意する手間を考えれば、使えるだけでどれだけありがたいかわかるというものです。
元の SD カードを書き潰すのは若干ためらわれた(後で元に戻せなくなった時に面倒)ので、今は chroot で使っています。
Crowd Supply から購入しました。本体 $999, 送料 $40, 消費税が 5,000円くらい、合計で 11万円くらいです。SBC にしてはかなり良いお値段です。
送料を払うのですが、家には着払いで届く点にも注意しなければなりません。
UPS が米国→日本まで持ってきて、国内はクロネコヤマトが運びます。受け取りの際に、消費税を着払いでクロネコに払う必要があります。私は消費税のことを知らなくて、何で送料を 2回払うんだ??と混乱しました。
メモ: 技術系の話は Facebook から転記しておくことにした。かなり追記。
目次: RISC-V - まとめリンク
HiFive Unleashed に Debian を導入した記念に、いつもやっているベンチマークを取ってみました。
モナコインのハッシュ方式に使われている Lyra2REv2 のベンチマークです。1秒にいくつハッシュ値を計算できるか測ります。
おそらくクロスコンパイルでビルドすることもできるとは思いますが、curl, libssl などに依存していて意外と面倒です。Debian の力を借りてセルフコンパイルすると超簡単です。
測定結果ですが、結論から言うと、Unleashed はメチャクチャ遅いです。Unleashed の結果は下記のとおりです。4コアなので 4スレッド並列で測定しています。
CPU #0: 4.53 kH/s CPU #2: 4.53 kH/s CPU #1: 4.53 kH/s CPU #3: 4.53 kH/s Total: 18.12 kH/s
参考までに ROCKPro64 RK3399(Cortex-A72 x 2, Cortex-A53 x 4)で同じプログラムをコンパイルして測定すると、下記の結果になります。6スレッド並列です。
CPU #4: 64.17 kH/s CPU #5: 64.16 kH/s CPU #1: 34.07 kH/s CPU #2: 34.11 kH/s CPU #0: 33.97 kH/s CPU #3: 33.92 kH/s Total: 264.94 kH/s
CA72 は 64kH/s くらい、CA53 は 33kH/s くらいです。このプログラムは CubeHash に NEON 対応を入れた特別版ですが、NEON 対応を外しても CA53 は 29kH/s くらいは出ます。
買う前から Unleashed があまり速くないことは知っていましたが、4コア束になっても CA53 1コアに勝てないとは思っていなかったです……。
しかもこのボード、かなり高価(10万円以上する)なので、お蔵入りは避けたいんですが、拡張性に乏しくて(USB がない)、一体何に使えるのか謎です。
追加で ROCK64 上で測定したので、結果を載せておきます。
4 miner threads started, using 'lyra2rev2' algorithm. CPU #2: 31.29 kH/s CPU #0: 31.22 kH/s CPU #1: 31.23 kH/s CPU #3: 31.30 kH/s Total: 125.04 kH/s
RK3399 の Cortex-A53 とあまり変わりません。同じ CPU コアで動作周波数もほぼ同じなので、当然といえば当然ですけども。
メモ: 技術系の話は Facebook から転記しておくことにした。多少追記。
管理者: Katsuhiro Suzuki(katsuhiro( a t )katsuster.net)
This is Simple Diary 1.0
Copyright(C) Katsuhiro Suzuki 2006-2021.
Powered by PHP 5.2.17.
using GD bundled (2.0.34 compatible)(png support.)