コグノスケ


2019年 3月 3日

ROCKPro64 のシリアル文字化け - パッチ投稿

目次: ROCK64/ROCKPro64 - まとめリンク

(主に俺のために)ROCKPro64 のシリアル文字化けを直すべく、Rockchip RK3399 のシリアル UART2 の drive strength を 3mA から 12mA にするパッチを LKML(Linux Kernel Mailing List)に送ってみました。ま、ダメ元です。

ROCKPro64 だけ何でこんなに Rising time が長くなるのでしょう?

Rockchip RK3328 搭載の ROCK64 は、特に問題がないように見えます。ROCKPro64 同様に ROCK64 も RK3328 から Pi-2 コネクタに直で信号を出しているはずなのに。

RK3399 の方がプロセス進んでるから、I/O ドライブ性能が低いのでしょうか。結局、問題の原因は良くわからないままです。

パッチを送ってから気づいたのですが、タイトルに RK3399 向けのパッチと説明を忘れていたり、ROCKPro64 しか確認できていない症状なのに、共通ファイル rk3399.dtsi に変更入れていたり、色々マズいです。そんなもん ROCKPro64 のデバイスツリーに入れてよ……、ってリジェクトされる気がします。

おそらく他の RK3399 のボードも RK3399 と UART のピンを直結していれば、同じ症状が起きると思うんですが、私は他のボード持っていないからわかりません。

メモ: 技術系の話は Facebook から転記しておくことにした。加筆した。

編集者: すずき(更新: 2020年 10月 30日 00:49)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2019年 3月 4日

ROCKPro64 のシリアル文字化け - LKML での議論

目次: ROCK64/ROCKPro64 - まとめリンク

メンテナーの Heiko さんからは「共通部分を変えようとしているから、他のボードの関係者にも聞いてくれ」とのことでした。そりゃそうだなと、RK3399 のボードのデバイスツリーを変えていそうな人達に CC でメールしてみたところ、お返事がきました。

Tony さんは、ROC RK3399 PC と ROCKPro64 の 2つのバージョン(V2.0 と V2.1、私が持っているのは V2.1)など、色々なボードでの立ち上がり、立ち下がり時間の測定値を教えてくれました。いずれも私が観測しているような症状はないとのことです。

Robin さんは、アイパターンを見てくれて、やっぱり異常はないと教えてくれました。

念のため、ピンに何か繋いでいる(インピーダンスが低い、立ち上がり時間が遅く計測される)のか、何も繋いでいない(インピーダンスが高い、立ち上がり時間が速く計測される)のかも確認しましたが、UART-USB 変換ボードをジャンパケーブルで繋いでいるとのことでした。

うーん。話を総合すると、どうも私のボードの個体不良っぽいです。パッチは取り下げておきました。やりとりは面白かったですが、結果的には皆さんを混乱させてしまっただけでしたね。

編集者: すずき(更新: 2020年 10月 30日 00:49)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2019年 3月 5日

ROCKPro64 のシリアル文字化け - 結論

目次: ROCK64/ROCKPro64 - まとめリンク

ROCKPro64 のシリアル UART2 が文字化けする問題に決着がつきました。

LKML(Linux Kernel Mailing List)に生息するナイスガイ達のおかげで、自分が持っている ROCKPro64 だけが異常値を示していることがわかりました。皆、普通にオシロスコープ持っているみたいですし、アイパターンまで見ていた人もいて、LKML すげーな……と感心しました。

私のボードは、おそらくどこかにハンダ不良があり、RK3399 から UART2 ピンまでの抵抗値が異常に高くなっていると推測されます。

テスターで抵抗値を見ればわかるはずですが、ROCKPro64 はボードのシルクに部品番号が全く書いておらず、どこにプローブを当てたら良いかさっぱりわかりませんでした。残念。

メモ: 技術系の話は Facebook から転記しておくことにした。

編集者: すずき(更新: 2020年 10月 30日 00:49)

コメント一覧

  • kml 
    > 自分が持っている RockPro64 だけが異常値を示していることがわかりました。

    オシロの波形見てて気がつかなかったのかな?

    以下、具体例だが
    https://github.com/ayufan-rock64/linux-build/releases/download/0.7.9/bionic-minimal-rockpro64-0.7.9-1067-arm64.img.xz
    https://github.com/ayufan-rock64/linux-build/releases/download/0.7.14/bionic-minimal-rockpro64-0.7.14-1081-arm64.img.xz
    前者は、比較的マシだがその兆候は出てる。
    後者は、貴方が提示した写真とほぼ同等で、操作不能な程のレベル
    (どのkernel、例えば "armbian" でもその兆候は出ているが、その程度は上記前者レベル
     多少の取りこぼしはあるかもしれないが、まだ十分操作可能なレベル)

    何れも u-boot の段階では問題無いのに、kernelに制御が移った後で ご指摘の症状
    私の手持ち全てが(3台)同一症状、kernel依存と見るのが妥当だと思うな

    もし、貴方が指摘した際に使ったものと同一のkernelを使えば おそらく全数がそうなる

    それと、同等の報告が 既に去年の夏頃に挙がってる
     
    (2019年03月20日 21:30:58)
  • すずき 
    > オシロの波形見てて気がつかなかったのかな?

    えーと、私が他のカーネル(ayufan-rock64 とか)の動作を見なかったのか?という意味でしょうか?
    そういう意味でしたら linux-next 以外は見ていないです。


    > 何れも u-boot の段階では問題無いのに、kernelに制御が移った後で ご指摘の症状

    確かに U-Boot は文字化けしないですね。Drive Strength の設定を見るとデフォルト値(3mA)だったので、他の設定が影響しているのかもしれません。

    後で U-Boot の UART2 出力についても、オシロスコープで波形見てみます。


    > 私の手持ち全てが(3台)同一症状、kernel依存と見るのが妥当だと思うな

    情報ありがとうございます。

    うーん、そうなんですか。私は 1台しか持っていないので個体不良かどうか見分けがつかないです。

    海外の人たちはなぜ同じ症状に遭遇しないのだろう。。。
     
    (2019年03月21日 17:45:56)
open/close この記事にコメントする



2019年 3月 6日

TinkerBoard の HDMI 出力

せっかく HDMI ディスプレイを買った(2019年 2月 2日の日記参照)ので、以前指摘された RK3288 の I2S と DMA がデグレしていないかどうか(2018年 12月 14日の日記参照)見るべく、linux-next + TinkerBoard の HDMI 出力を確認しました。

映像は映り、音声も鳴りますが、48kHz ←→ 44kHz の LPCM を交互に再生すると、音声にバリバリとノイズが載ります。なぜかノイズが載らないときもあります。

ROCK64 のアナログ出力でもこんな問題が起きていたので、同類だろうか?と不安になって、色々いじっていたのですが、どうも違う問題らしく、ディスプレイ側を ON/OFF すると問題が発生するように見えます。

他のディスプレイで確認していないため、TinkerBoard が無罪とまでは言い切れませんが、おそらくディスプレイ側の問題でしょう。

編集者: すずき(更新: 2019年 3月 13日 09:51)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2019年 3月 10日

誕生日

干支を 3周しました。もう完全におじさんの仲間入りです。

若い人に自慢と説教だけはしないように気を付けよう。

編集者: すずき(更新: 2019年 3月 13日 00:10)

コメント一覧

  • hdk 
    誕生日おめでとー! 
    (2019年03月13日 01:14:40)
  • すずき 
    ありがとー!! 
    (2019年03月13日 09:46:59)
open/close この記事にコメントする



2019年 3月 11日

ROCK64 の USB をデグレさせた

目次: ROCK64/ROCKPro64 - まとめリンク

昔、私が投稿したパッチが Linux 4.20 をデグレさせていました。Linux 4.20 以降では ROCK64 の USB が動かなくなっています。全然気づきませんでした……。

Arch Linux の人たちが「動かねーぞ??」とハマった挙句(リンク)に、指摘してくれたようです。

反省を込めて、ROCK64 がデグレした理由をまとめておきます。

当時、私が直したのはピンに出力する信号の割り当て設定です。

GPIO0 A2

  • 本来の出力: USB 電源供給 Enable/Disable 信号
  • 当時の出力: 何も割り当たっていない(が、なぜか動いていた…)

GPIO0 D3

  • 本来の出力: S/PDIF 信号
  • 当時の出力: USB 電源供給 Enable/Disable 信号

上記のように、本来 GPIO0 D3 には S/PDIF 信号が割り当てられるはずですが、なぜか全く関係のない USB 電源供給信号が割り当てられており、S/PDIF が全く動作しない状態になっていました。

私のパッチは USB 電源供給信号のピンアサインを GPIO0 A2 に直すパッチです。GPIO0 D3 ピンから S/PDIF が無事出力できるようになりました。

しかし実装の間違いはこれだけではありませんでした。GPIO0 A2 は信号の極性(Active High 指定でしたが、本来は Active Low が正しい)も間違っていたのです。

GPIO0 A2

  • 本来: USB 電源供給 Enable/Disable 信号
  • 実装: 何も割り当たっていない
  • パッチ後: USB 電源供給 Enable/Disable 信号(直った)
  • 本来の極性: Active Low
  • 実装の極性: Active High
  • パッチ後: Active High(変化なし)

私のパッチはピンアサインだけ直して、信号の極性を直さなかったため、USB の電源が常にダウンしてしまい、USB が全く動かなくなってしまったようです。

USB 電源周りをいじったのに、USB の動作確認をせずにパッチを投稿してしまったのは、片手落ちだったなあと反省しきりです。

メモ: 技術系の話は Facebook から転記しておくことにした。

編集者: すずき(更新: 2020年 10月 30日 01:43)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2019年 3月 16日

ROCKPro64 と PCI Express - 動作せず

目次: ROCK64/ROCKPro64 - まとめリンク

ROCKPro64 には PCI Express スロットが実装されています。せっかくあるので試そうと思い、玄人志向の SATA インタフェース増設カード(SATA3-PCIE-E2)と、USB 3.0 インタフェース増設カード(USB3.0R-P2H2-PCIE)を買いました。

結論から先に言うと RK3399 の PCI Express コントローラは有効にできましたが、ROCKPro64 の信号品質が良くないのか USB のカードしか認識しませんでした。残念です。

唯一認識される USB のカードも PCI Express のライザーカードで延長すると認識しなくなります。認識できるギリギリの信号なんですかね。

ROCKPro64 で PCI Express カードを認識できないときのログ
rockchip-pcie f8000000.pcie: PCIe link training gen1 timeout!

認識されないときはこんなエラーログが出ています。うーん。

有効にするだけでは動かない RK3399 の PCI Express コントローラ

RK3399 の PCIe コントローラもちょっと癖があって、ep-gpios プロパティを指定しないと probe 時にエラーで落ちます。このドライバは GPIO を使ってレギュレータを操作し、PCI Express への電源供給を制御したいようです。

通常、デバイスドライバで電源制御を実装したい場合 vpcie12v-supply のようなレギュレータを指定するプロパティを使いますが、なぜ GPIO を使っているのでしょうね……?

しかもうまくないことに ROCKPro64 の場合、既に PCI Express 用レギュレータのデバイスノードが定義されており、常に PCI Express の電源を ON にしています。そのため PCI Express のデバイスノードに GPIO を追加すると「もう使われているよ!」と怒られてしまいます。

どう直すのが正しいのかわかりませんが、とりあえず PCI Express のドライバを改造し、GPIO のエラー処理を削ったら先に進みました。しかし良くハングするようにもなりました。イマイチだ……。

後日、直すことができました(2019年 5月 9日の日記参照)。

メモ: 技術系の話は Facebook から転記しておくことにした。追記した。

編集者: すずき(更新: 2020年 10月 30日 01:02)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2019年 3月 17日

たまにズレちゃう Windows 10

Windows 10 は自動的に Windows Update を実行し、勝手に PC を再起動することがあります。その際にウインドウの幅がズレることがあります。


タイトルバーとウインドウの幅がずれる

ウインドウの幅が多少ズレても実用上害はありませんが、この状態と同時に発生する、フォント表示がボヤボヤになって、サイズがおかしくなり、非常に読みづらくなる症状が辛いです。目が痛くなってきます。

いずれの症状も PC を再起動すると直ります。直る理由すらわかりませんが、今のところ直らなかったことは一度もありません。

不思議なことに Windows Update 後に必ずズレた状態になる訳ではなく、何か他の条件があるようです。人が見ていない夜中に再起動して、勝手にこの状態にハマるので、詳細は確認しようがないです。

我が家での Windows の存在意義

最近の Windows は再起動により、作業中のアプリケーションが全て終了され、当初かなりイライラしていました。

しかし今は「Windows で大事な作業をしない」ことにより、諦めがつきました。デスクトップ PC は勝手に再起動されては困るので、Windows ごと消しました。さようなら〜。

ノート PC は再起動されても特に問題ないので Windows を残しています。なぜなら最近 Windows 上で実行しているアプリケーションは、

ブラウザ
強制終了されても最後に開いていたページを覚えている。
VNC クライアント
強制終了されても Linux マシンが動き続けているので問題ない。

しかないからです。あとは、たまに音楽プレーヤーや Steam を起動しますが、起動しっぱなしにはしません。たとえ強制終了されたとしても問題はありません。

この使い方はほぼシンクライアントですね。わざわざカスタムオーダーまでして Core i5-8250 と外部グラフィックス AMD Radeon RX550 を積んだのに、彼らが Steam 以外で活用されることはありません……。

つまり、もっとゲームをやりなさいということだな??

編集者: すずき(更新: 2019年 3月 23日 15:06)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2019年 3月 23日

初めての OpenVX on ARM

目次: OpenCL を調べる - まとめリンク

先日(2018年 11月 14日の日記参照)動かした OpenVX + OpenCV のデモを AArch64 上でも動かそうと思います。クロスコンパイルではなく ARM 上でセルフコンパイルします。環境は Debian 9、ボードは ROCKPro64 です。

ビルド

前回同様 OpenVX ライブラリをビルドする必要がありますが、単純に make するとビルドに失敗します。

OpenVX ライブラリのビルド on AArch64
[GCC] Compiling C99 vx_debug.c
gcc: error: unrecognized argument in option '-mabi=aapcs-linux'
gcc: note: valid arguments to '-mabi=' are: ilp32 lp64
gcc: error: unrecognized command line option '-mapcs'; did you mean '--specs'?
gcc: error: unrecognized command line option '-mno-sched-prolog'; did you mean  -Wno-sign-promo'?
gcc: error: unrecognized command line option '-mno-thumb-interwork'; did you mean '-fno-sched-interblock'?
concerto/finale.mak:289: recipe for target '/home/katsuhiro/projects/openvx/out/LINUX/aarch64/release/module/debug/vx_debug.o' failed

Makefile に不要なオプションが指定されていてビルドが失敗しているようなので、削除します。

concerto の Makefile からオプションを削除

diff --git a/concerto/compilers/gcc.mak b/concerto/compilers/gcc.mak
index aca2556..0295e39 100644
--- a/concerto/compilers/gcc.mak
+++ b/concerto/compilers/gcc.mak
@@ -125,9 +125,9 @@ endif
 endif

 ifeq ($(TARGET_FAMILY),ARM)
-$(_MODULE)_COPT += -mapcs -mno-sched-prolog -mno-thumb-interwork
+#$(_MODULE)_COPT += -mapcs -mno-sched-prolog -mno-thumb-interwork
 ifeq ($(TARGET_OS),LINUX)
-$(_MODULE)_COPT += -mabi=aapcs-linux
+#$(_MODULE)_COPT += -mabi=aapcs-linux
 endif
 endif

ちなみに cmake によるビルドも可能ですが、ARM に対応できていないように見えます。

make の設定からオプションを削除

diff --git a/cmake_utils/CMake_linux_tools.cmake b/cmake_utils/CMake_linux_tools
.cmake
index caaa017..dc2371f 100644
--- a/cmake_utils/CMake_linux_tools.cmake
+++ b/cmake_utils/CMake_linux_tools.cmake
@@ -32,10 +32,10 @@ if(BUILD_X64)
 else()
   if (TARGET_CPU STREQUAL "Atom")
     # architecture will be according to ATOM
-    set(ARCH_BIT -m32 )
+    # set(ARCH_BIT -m32 )
   else ()
     # need to force a more modern architecture than the degault m32 (i386).
-    set(ARCH_BIT "-m32 -march=core2" )
+    # set(ARCH_BIT "-m32 -march=core2" )
   endif (TARGET_CPU STREQUAL "Atom")
 endif()

正しい直し方ではありませんが、とりあえず x86 向けの設定を改造して、x86 用のオプションを外すとビルドが通ります。

サンプルのビルド

OpenVX ライブラリのビルドが通ったら、サンプルをビルドします。

concert でビルドしたライブラリを指定して、サンプルをビルド
$ cd openvx_tutorial/tutorial_exercises/solution_exercise1
$ g++ -I ../include -L /path/to/openvx/out/LINUX/aarch64/release/ solution_exercise1.cpp \
  -lopencv_imgproc -lopencv_highgui -lopencv_core -lopenvx

もし cmake でライブラリを作った場合は、ライブラリの生成先ディレクトリが異なります。下記のようにします。

cmake でビルドしたライブラリを指定して、サンプルをビルド
$ cd openvx_tutorial/tutorial_exercises/solution_exercise1
$ g++ -I ../include -L /path/to/openvx/build/sample/framework/ solution_exercise1.cpp \
  -lopencv_imgproc -lopencv_highgui -lopencv_core -lopenvx

実行する際は、HDMI 出力などの GUI 画面に表示してもよいですし、vncserver などの画面にも表示できます。下記の例は vncserver に表示する例です。

concert でビルドしたライブラリを指定して、サンプルを実行
$ DISPLAY=:1 \
  LD_LIBRARY_PATH=/path/to/openvx/out/LINUX/aarch64/release/ \
  ./a.out

もし cmake でビルドしたライブラリを使う場合、ライブラリがバラバラのディレクトリに置かれているため、LD_LIBRARY_PATH に指定するパスがやや長くなります。

cmake でビルドしたライブラリを指定して、サンプルを実行
$ DISPLAY=:1 \
  LD_LIBRARY_PATH=/path/to/openvx/build/sample/framework/:/path/to/openvx/build/sample/targets/c_model/:/path/to/openvx/build/sample/vxu/:/path/to/openvx/build/libraries/extras/:/path/to/openvx/build/libraries/debug/ \
  ./a.out

もし cmake でビルドしたライブラリでトラブルが起きたときは、cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo と指定してデバッグ情報を有効にしてビルドすることで、デバッグしやすくなります。

VNC と OpenCV

TightVNC サーバーを使うとアプリケーションの実行時に下記の警告が出ます。

VNC サーバーによっては下記の警告が出る
Xlib:  extension "RANDR" missing on display ":1".

警告が出ても動作はするのですが、気になる方は下記のように TigerVNC をインストールするなど、RANDR に対応した VNC サーバーを使ってください。

TigerVNC サーバーのインストール
# apt-get install tigervnc-standalone-server
編集者: すずき(更新: 2022年 9月 26日 17:48)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2019年 3月 24日

レジスタダンプ、書き換えツール memaccess

ツールのソースコードは GitHub に置いています

前職のころレジスタダンプと、レジスタ値書き換えのための fa という素敵なアプリ(Free Access の略と聞いた)を使っていました。

このアプリは、/dev/mem 経由でメモリの指定したアドレスを読んだり書いたりできるアプリです。何だそんなもの……と思うかもしれませんが、低レイヤデバッグには便利でして、開発の皆さんが愛用していたことを覚えています。

オリジナルの fa はデカくて無駄の多いコードだったので、何年か前に全部捨てて書き直しました。さらに他の人が書き直していなければ、今も使われているのではなかろうか?

現職とレジスタダンプ

なんと転職後もレジスタダンプが必要なシーンによく遭遇します。半導体の仕事と低レイヤデバッグは切っても切れない関係みたいです。

最初はカーネルドライバを書いて readl で読んで、printk して…、などとやっていましたが、あまりにも面倒くさくてやってられません。やっぱり fa のようなものが欲しいなあと思い立ち、土日でパパパーっと書いて、GitHub に放り込んでおきました。

アプリの実装は /dev/mem を mmap して読み書きするだけで、特に知識も要りません。たぶん誰でも書けます。

アプリの名前ですが、Free Access だと Wi-Fi スポットみたいで変だな……と思って、ma(memaccess, memory access の略)にしておきました。memory dump にしたかったのですが、有名なツールと同じ名前で紛らわしいのでやめました。

もし memory dump でレジスタ読み書きができれば、わざわざアプリを作る必要はなかったのですが、しかし memory dump はバイナリで出力する方に重きを置いており、エディト機能もなさそうで、設計の方向性が違いました……。残念。

編集者: すずき(更新: 2019年 3月 27日 21:52)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2019年 3月 25日

ROCKPro64 のシリアル文字化け - U-Boot との比較

目次: ROCK64/ROCKPro64 - まとめリンク

ROCKPro64 シリアル文字化けの話のまとめ、第二章。ROCKPro64 は「U-Boot だと文字化けしない」という指摘をいただいたので確認したところ、確かに文字化けしません。

Drive Strength の設定はデフォルト値(3mA)のままにも関わらず、オシロスコープで UART TX 側の波形を見ると Rise/Fall Time が 77ns/59ns と優秀な値です。


ROCKPro64 U-Boot のシリアル出力の波形

とりあえずボード不良ではなかったことがわかって良かったものの、何が原因で linux-next は文字化けしているかわからず、振出しに戻ってしまいました。

あえて波形を劣化させる設定?

電源 ON から波形を観察し続けると linux-next もブートプロンプトの途中までは波形が綺麗です。linux-next は途中で波形が鈍る設定をわざとしていることになります。

原因がわからないので、当てずっぽうでデバイスツリーの色々なノードを ON/OFF していったところ、io_domains ノードの audio-supply プロパティを変更すると UART TX の波形が劣化することがわかりました。

このプロパティを読み取るドライバは drivers/power/avs/rockchip-io-domain.c にあります。追ってみると RK3399 の GRF のレジスタ 0xff77e640 の bit 1(audio_gpio3d4a_ms)の値を設定していました。仕様書を見ると IO domain(とは何だ?)の駆動電圧を設定するビットでした。クリアすると 3.0V、セットすると 1.8V の意味です。

現在の linux-next は 1.8V 設定にしており、波形が鈍っています。U-Boot はレジスタに何も設定しないらしく、デフォルトの 3.0V 設定のままでした。

試しに linux-next 起動後、UART TX の波形が鈍ったことを確認したのちに、audio_gpio3d4a_ms を無理やりクリア、つまり IO domain works as 3.0V 設定に変えてみたところ、波形がシャキーンと綺麗になりました。

ああー、原因はこれだ。

どう直すべきか

レジスタの値を色々変えてみたところ、bit 1 audio_gpio3d4a_ms を 3.0V にするか、bit 1 audio_gpio3d4a_ms と bit 3 gpio1830_gpio4cd_ms を両方とも 1.8V 設定に変えると直ることがわかりました。

しかし ROCKPro64 の回路図を見ると、GPIO1830 は 3.0V で、VCCA1V8 は 1.8V に設定する方が正しいように見えます。

正しいはずの設定になのに UART の波形が鈍ってしまい、設定を間違えているはずの U-Boot は UART の波形が綺麗です。どうしてこうなるのか良くわかりません。原因はわかったものの、真因がわからなくて直し方もわからない、困ったタイプですね。

おまけ

IO domain を 3.0V に変更し、Drive Strength 12mA の設定と組み合わせると、Rise/Fall Time が 30ns/34ns とさらに速くなります。


IO domain 3.0V + Drive Strength 12mA のときの ROCKPro64 シリアル出力の波形

あまりに急激に立ち上がりすぎるせいか、良く見ると Rise Edge がオーバーシュートしていますね……。

メモ: 技術系の話は Facebook から転記しておくことにした。図を追加した。

編集者: すずき(更新: 2020年 10月 30日 00:50)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2019年 3月 26日

LLVM の本を買った

目次: LLVM を調べる - まとめリンク

コンパイラが良くわからないまま放置してきましたが、最近、きつねさんでもわかる LLVM(アマゾンへのリンク)を買って読んでいます。

タイトルの通り LLVM のフロントエンド、バックエンドをコードを交えて紹介する書籍です。かなりマニアックですね……。本の中でも言及されていますが、本を読むだけより、実際にコードを動かして試すのがおすすめとのことです。

LLVM のビルド

コードを変更するにせよ、そのまま動かすにせよ、まずビルドできないと始まらないので、ビルドにチャレンジします。環境は Debian Testing です。

Debian Testing の GCC は 8.2
$ gcc --version
gcc (Debian 8.2.0-21) 8.2.0
Copyright (C) 2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

まずは何も考えずに cmake, make してみました。

GCC 8.2 で LLVM をビルド、ダメだった
$ mkdir build
$ cmake ../llvm
$ make
...

[ 74%] Building NVCC (Device) object projects/openmp/libomptarget/deviceRTLs/nvptx/CMakeFiles/omptarget-nvptx.dir/src/omptarget-nvptx_generated_omp_data.cu.o
In file included from /usr/include/host_config.h:50,
                 from /usr/include/cuda_runtime.h:78,
                 from <command-line>:
/usr/include/crt/host_config.h:119:2: error: #error -- unsupported GNU version! gcc versions later than 7 are not supported!
 #error -- unsupported GNU version! gcc versions later than 7 are not supported!
  ^~~~~
CMake Error at omptarget-nvptx_generated_omp_data.cu.o.Debug.cmake:215 (message):
  Error generating
  /home/katsuhiro/share/projects/oss/clang/build/projects/openmp/libomptarget/deviceRTLs/nvptx/CMakeFiles/omptarget-nvptx.dir/src/./omptarget-nvptx_generated_omp_data.cu.o


make[2]: *** [projects/openmp/libomptarget/deviceRTLs/nvptx/CMakeFiles/omptarget-nvptx.dir/build.make:135: projects/openmp/libomptarget/deviceRTLs/nvptx/CMakeFiles/omptarget-nvptx.dir/src/omptarget-nvptx_generated_omp_data.cu.o] エラー 1
make[1]: *** [CMakeFiles/Makefile2:39936: projects/openmp/libomptarget/deviceRTLs/nvptx/CMakeFiles/omptarget-nvptx.dir/all] エラー 2
make: *** [Makefile:152: all] エラー 2

エラーメッセージを素直に解釈すると GCC 7 より後だとダメっぽいです。GCC 6.0 を使おうと思いましたが、Debian Testing に gcc-6 というパッケージはありますが、g++-6 は見当たりません。LLVM は C++ のコードがあるので GCC だけではビルドできないのです。無念……。

ひとまず GCC は諦め、Clang を試してみます。

Debian Testing の Clang は 7.0
$ clang --version
clang version 7.0.1-6 (tags/RELEASE_701/final)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin

通常と異なるコンパイラを使うときは cmake に CMAKE_C_COMPILER と CMAKE_CXX_COMPILER 変数を渡します。さて、ビルドできるでしょうか?

LLVM 7.0 で LLVM をビルド、うまくいった
$ cmake -G Ninja -D CMAKE_C_COMPILER=clang -D CMAKE_CXX_COMPILER=clang++ ../llvm
$ ninja

コンパイラのバージョンに敏感だと、将来ビルドできなくなりそうで不安になりますが、それはさておき。とりあえずビルドに成功したので、今後は clang を使うことにしましょう。

リンカが死ぬ

LLVM のビルドはリンクで死ぬほどメモリを使う(1プロセスが 8GB 使ったりする)ので、16コア CPU だからといって ninja -j16 などとするとリンクの時にメモリが足りなくなってリンカがクラッシュします。

恐ろしいことにメモリ 32GB だと全然足りなくて、ninja -j8 でもクラッシュします。LLVM の開発者は一体どんなモンスターマシンでビルドしているんでしょうか……。

私の PC はもうメモリを増設できない(空いている DIMM スロットがない)ので、対象アーキテクチャを減らすか、ビルドの並列数を減らして、メモリを節約するしかなさそうです。

編集者: すずき(更新: 2021年 5月 20日 16:16)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2019年 3月 27日

Clang の main 関数ってどこ?

目次: LLVM を調べる - まとめリンク

ふと Clang の main 関数ってどこにあるんだろう?と思って、grep したのですが、それらしい箇所がありません。

GDB で Clang の main にブレーク掛けてみると、llvm/tools/clang/tools/driver/driver.cpp がヒットしました。んん?clang ディレクトリではなく、llvm ディレクトリにあるんですか?ちょっと初見ではわかりませんでした。GDB ありがとう。

Clang というか LLVM の困ったところは、シンボルが多すぎて GDB の起動に数分かかることです。GDB がメモリを 1.5GB ほど使うのも特徴的です。デバッグのために 1GB メモリを使うなんて今まで見たことありません。

この時点で既に低性能 PC お断り感がビシビシ出ていますが、LLVM の極めつけはリンク時にリンカがメモリ 8GB も使う(しかも 1プロセスで)ことです。

その辺のショボい PC ではデバッグがどうこう言う前に、そもそもビルドできず門前払いです。LLVM ムチャクチャが過ぎる……。

RISC-V 向け LLVM ビルド

LLVM には RISC-V 向けの実装があるのですが、デフォルトでは有効になっていないようです。LLVM の CMakeLists.txt の LLVM_ALL_TARGETS に RISCV を足します。

LLVM の RISCV 向け実装を有効にする

diff --git a/CMakeLists.txt b/CMakeLists.txt
index ee6b77990b3..ce8f24afad1 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -327,6 +327,7 @@ set(LLVM_ALL_TARGETS
   MSP430
   NVPTX
   PowerPC
+  RISCV
   Sparc
   SystemZ
   WebAssembly

ビルドすれば RISC-V 用の LLVM やツールチェーンがビルドできます。

リンク時のメモリ節約方法(特定アーキテクチャ向け LLVM ビルド)

LLVM は何も指定せずにビルドすると、対応可能な全てのアーキテクチャに対応したバイナリをビルドしようとします。ビルドがメチャクチャ遅いので、cmake に LLVM_TARGETS_TO_BUILD でビルド対象を 1つだけに制限すると、ビルド、特に最後のリンクが速くなります。

RISCV のみをデバッグシンボル付きでビルドする
$ cmake -G Ninja \
  -D LLVM_TARGETS_TO_BUILD="RISCV" \
  -D CMAKE_C_COMPILER=clang \
  -D CMAKE_CXX_COMPILER=clang++ \
  -D LLVM_USE_LINKER=gold \
  -D CMAKE_BUILD_TYPE=RelWithDebInfo \
  -D LLVM_ENABLE_ASSERTIONS=ON \
  ../llvm

$ ninja

CMAKE_BUILD_TYPE に渡せる値は何種類かあります。Debug だとリンク時間がバカみたいに長く、リビルドが辛いです。Release だとビルドは速いですがデバッガがほぼ使えず、デバッグが辛いです。リリース相当だけどデバッグシンボルは付ける RelWithDebInfo が普段遣いには良いかもしれません。

メモ: 技術系の話は Facebook から転記しておくことにした。いろいろ追記した。

編集者: すずき(更新: 2021年 5月 20日 16:16)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2019年 3月 28日

マンガ紹介

目次: マンガ紹介 - まとめリンク

お気に入りのマンガ紹介シリーズ。

マンガ紹介 その 1

こわもてかわもて(1巻)(アマゾンへのリンク

子育ては奥さんにまかせきりで子供の扱いが良くわからない「こわもて」の爺ちゃん龍之介と、突然帰ってきた「かわもて」の孫の虎々(ことら)のコメディマンガ。

虎々のフリーダム加減は、よつばと!に似てるけど、周りの大人のキャラが違うので、作品としてはそんなに似てない気がする。今後が楽しみ。

マンガ紹介 その 2

我が驍勇(ぎょうゆう)にふるえよ天地〜アレクシス帝国興隆記〜(2巻)(アマゾンへのリンク

自国の貴族の罠により、故郷を隣国に攻め落とされ、親しい人も帰るべき地も失った王子が、英雄となり新たな帝国を築く(たぶん、タイトルから推測して)。王道の戦記物です。

主人公は不幸な生い立ちですが、復讐の鬼にはならず、器のデカさを感じます。2巻の時点ではまだまだ序盤ですから、今後はわからないですけども。画も迫力あっていい感じです。今後が楽しみです。

タイトルは最近あまり見ない厳つい感じですね。

異世界転生物に多いのですが、
「〜したら〜でした」
「〜が〜なんですが」
「〜は〜します」
のような説明的なタイトルって、個人的には冗長であまり好きじゃないです。面白いんだから、大丈夫だよ!もっと自信もって言い切って!!なんてことを思います。

その点、この本はタイトルからして目に留まって、とても印象的でした。

編集者: すずき(更新: 2022年 8月 30日 22:51)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2019年 3月 29日

LLVM IR の作り方

目次: LLVM を調べる - まとめリンク

いつも忘れるので、C 言語のコードから、オブジェクトコード、LLVM IR ビットコード、LLVM IR、アセンブラを生成する方法をメモしておきます。

C Source (.c) -> Object code (.o)

$ clang --target=riscv64 a.c -c -o a.o

C Source (.c) -> LLVM IR (.ll)

$ clang -c -S -emit-llvm a.c

C Source (.c) -> LLVM IR bitcode (.bc)

$ clang -c -emit-llvm a.c

LLVM IR (.ll) -> Assembly code (.S)

$ llc --march=riscv32 a.ll

LLVM IR (.ll) -> Object code (.o)

$ llc --march=riscv32 -filetype=obj a.ll
編集者: すずき(更新: 2021年 5月 20日 16:16)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2019年 3月 30日

GCC がない世界はどうなるか?

目次: GCC を調べる - まとめリンク

世界から gcc がなくなるとどうなるのか?と思ったので、試してみました。その世界では、少なくともターゲットとなる実機上でセルフコンパイルが可能になるまで、別の環境(例えば PC など)で、

  • clang
  • クロスコンパイル

を用いて世界を構築する必要があります。何もかも試すのは不可能なので、必要最小限の要素として、

  • ブートローダー(U-Boot)
  • カーネル(Linux)
  • libc(glibc, newlib)

を試すことにします。

最近は clang と gcc は互換性も高いし、楽勝でしょ〜などと生半可な知識で楽観視していましたが、実際やると何かもう全然ダメです。そもそも x86 向けのビルドが成功しません。クロスコンパイルなんか以ての外です。

RISC-V の人たちが GCC に真っ先に対応して、LLVM を放置している理由はこれかなあ?特に GNU, Linux 系システムをビルドしようと思ったら、LLVM だけでは話にならないのでは……??

U-Boot

まずは U-Boot です。

U-Boot を clang でビルド
$ make CC=clang defconfig
$ make CC=clang

うまくいきました。さすが!ARM とか AArch64 向けなら、U-Boot は良い選択肢のはずです。RISC-V は違うブートローダを使うので意味ありませんけど。

Linux

次は Linux です。

Linux を clang でビルド
$ make CC=clang defconfig
$ make CC=clang
HOSTCC scripts/asn1_compiler
HOSTCC scripts/extract-cert
Compiler lacks asm-goto support.
make: *** [arch/x86/Makefile:298: checkbin] Error 1

序盤でコケます。どうしたら良いんでしょう、これ。回避方法が見当たりません。

libc (glibc)

glibc を clang でビルド
$ mkdir build
$ cd build
$ ../configure --prefix="/usr" CC=clang
...
configure: error:
*** These critical programs are missing or too old: compiler
*** Check the INSTALL file for required versions.

まず configure が通りません。門前払いです。どうも clang を使ったとき、configure は GCC 3.x 系だと思うようで、そんな古いコンパイラはダメよ?と怒られてしまいます。どうしろと。

libc (newlib)

GNU 系列の glibc は clang に対応するとは思えませんし、newlib なら何とかしてくれるはず。

newlib を clang でビルド
$ mkdir build
$ cd build
$ ../newlib/configure --disable-multilib CC=clang CXX=clang++
...
In file included from ../../../newlib/libc/ssp/gets_chk.c:39:
In file included from /home/katsuhiro/share/projects/oss/newlib-cygwin/newlib/libc/include/limits.h:132:
In file included from /usr/lib/llvm-7/lib/clang/7.0.1/include/limits.h:37:
/usr/include/limits.h:145:5: error: function-like macro '__GLIBC_USE' is not defined
#if __GLIBC_USE (IEC_60559_BFP_EXT)
^
1 error generated.

ええ、そう思っていた時代が私にもありました。救世主だと勝手に思っていましたが、まさかのコンパイルできず。

注意

いずれの手順も CC=clang を付けなければ(=GCC を使えば)成功することは確かめていますが、私の実行したビルド手順が正しい保証はありません。

GCC → clang への切り替えを行う際に「CC=clang を付ける」が正しい手順とは限らないからです。ソフトウェアによっては clang 専用に別のビルド手順が存在するかもしれません。

ビルド失敗していることからもわかる通り、私は正しいビルド手順は発見できていません。知っていたらぜひ教えて欲しいです……。

メモ: 技術系の話は Facebook から転記しておくことにした。いろいろ追記した。

編集者: すずき(更新: 2022年 8月 13日 17:41)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2019年 3月 31日

ROCKPro64 のシリアル文字化け - 真因発見か?

目次: ROCK64/ROCKPro64 - まとめリンク

ROCKPro64 のシリアル文字化け問題に進展がありました。結論から先に言えば、現在の linux-next の I/O ドメイン audio_gpio3d4a_ms の電圧設定が間違っていそうです。直したらシリアルの波形が綺麗になりました。

RK3399 は I/O ドメイン(正式な名前かどうか知らない)といって、いくつかの出力ピンがグループになっています。グループごとに電源ピンがあり、電源ピンに何 V を供給しているか設定する必要があるようです。audio_gpio3d4a_ms ドメインの電源は APIO5_VDD 端子です。

要は APIO5_VDD 端子に 1.8V を供給するなら、audio_gpio3d4a_ms ドメインの設定も 1.8V にする必要があり、APIOD5_VDD 端子に 3.0V を供給するなら、audio_gpio3d4a_ms ドメインの設定も 3.0V にする必要があります。

ROCKPro64 の回路図を見ると、P.4 の Power Domain Map というページに audio_gpio3d4a_ms には電源 IC(RK808)の VLDO7 が繋がっていて、1.8V だと書いてあります。linux-next はこの記述を見て設定していると思われます。

しかし P.16 の回路図を見ると、APIO5_VDD 端子には VCC_3V0(その先は VLDO8)という 3.0V 出力ピンが繋がっています。つまり ROCKPro64 の回路図は自己矛盾しています。


APIO5_VDD の配線図


VCC_3V0 の配線図

配線ミスってるとか、そんなのありかよ……と思いつつ P.16 の回路図を信じることにして、audio_gpio3d4a_ms を 3.0V 設定にするパッチを LKML に送りました。

偉そうに書いていますが、私は P.16 の回路図には全く気づいておらず、LKML のナイスガイ達に助けられました。ありがたいことです。

関係ないドメインなのに、なぜ影響するのか?

UART2 信号が出ている GPIO4_C3 ピンは gpio1830_gpio4cd ドメインに属しており、audio_gpio3d4a_ms ドメインでは「ない」です。にも関わらず、なぜか audio_gpio3d4a_ms ドメインの設定ミスで UART2 の波形がおかしくなります。

Power Domain Map と回路図の意図を整理すると、Power Domain Map の設計は、下記の通りです。

  • audio_gpio3d4a_ms - APIO5_VDD - VCCA1V8_CODEC - VLDO7
  • gpio1830_gpio4cd - APIO4_VDD - VCC1V5 - VLDO6, VCC3V0_IO - VLDO8

一方の回路図はというと、全然接続が違いますし、端子がなかったりします。

  • VCCA1V8_CODEC - VLDO7
  • VCC_1V5 - VLDO6
  • VCC3V0_IO 存在しない
  • audio_gpio3d4a_ms - APIO5_VDD - VCC3V0 - VLDO8
  • gpio1830_gpio4cd - APIO4_VDD - VCC3V0 - VLDO8


VLDO 系の配線図

推測ですが、意図せずに 2つのドメインで電源ライン VLDO8 を共有したために、audio_gpio3d4a_ms ドメインの設定ミスが、gpio1830_gpio4cd 側のドライブ能力に影響していると思われます。

VLDO8 に想定してない負荷が掛かっているような気がしますが、大丈夫なんですかね……??まあ、コスパ重視だし、趣味のおもちゃですから、燃えたり爆発したりしなければ問題ないのかな。

(補足)audio_gpio3d4a_ms ドメインの設定は、GRF_IO_VSEL レジスタ(アドレス 0xff77e640 )のビット 1 です。

編集者: すずき(更新: 2020年 10月 30日 00:50)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



こんてんつ

open/close wiki
open/close Java API

過去の日記

open/close 2002年
open/close 2003年
open/close 2004年
open/close 2005年
open/close 2006年
open/close 2007年
open/close 2008年
open/close 2009年
open/close 2010年
open/close 2011年
open/close 2012年
open/close 2013年
open/close 2014年
open/close 2015年
open/close 2016年
open/close 2017年
open/close 2018年
open/close 2019年
open/close 2020年
open/close 2021年
open/close 2022年
open/close 2023年
open/close 過去日記について

その他の情報

open/close アクセス統計
open/close サーバ一覧
open/close サイトの情報