コグノスケ


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さん(2019/03/20 21:30)
    > 自分が持っている 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/21 17:45)
    > オシロの波形見てて気がつかなかったのかな?

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


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

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

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


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

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

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

    海外の人たちはなぜ同じ症状に遭遇しないのだろう。。。
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/03/13 09:51)

コメント一覧

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



2019年3月10日

誕生日

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

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

編集者:すずき(2019/03/13 00:10)

コメント一覧

  • hdkさん(2019/03/13 01:14)
    誕生日おめでとー!
  • すずきさん(2019/03/13 09:46)
    ありがとー!!
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

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以外で活用されることはありません……。

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

編集者:すずき(2023/09/24 13:24)

コメント一覧

  • コメントはありません。
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
編集者:すずき(2023/09/24 11:57)

コメント一覧

  • コメントはありません。
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/03/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スロットがない)ので、対象アーキテクチャを減らすか、ビルドの並列数を減らして、メモリを節約するしかなさそうです。

編集者:すずき(2023/09/24 09:15)

コメント一覧

  • コメントはありません。
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から転記しておくことにした。いろいろ追記した。

編集者:すずき(2023/09/24 09:15)

コメント一覧

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



2019年3月28日

マンガ紹介

目次: マンガ紹介

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

マンガ紹介 その1

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

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

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

マンガ紹介 その2

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

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

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

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

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

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

編集者:すずき(2022/08/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
編集者:すずき(2023/09/24 09:15)

コメント一覧

  • コメントはありません。
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から転記しておくことにした。いろいろ追記した。

編集者:すずき(2023/09/24 11:43)

コメント一覧

  • コメントはありません。
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 Linux JM
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 2024年
open/close 過去日記について

その他の情報

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