ツールのソースコードは 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はバイナリで出力する方に重きを置いており、エディト機能もなさそうで、設計の方向性が違いました……。残念。
目次: OpenCL
先日(2018年11月14日の日記参照)動かしたOpenVX + OpenCVのデモをAArch64上でも動かそうと思います。クロスコンパイルではなくARM上でセルフコンパイルします。環境はDebian 9、ボードはROCKPro64です。
前回同様OpenVXライブラリをビルドする必要がありますが、単純にmakeするとビルドに失敗します。
[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に不要なオプションが指定されていてビルドが失敗しているようなので、削除します。
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に対応できていないように見えます。
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ライブラリのビルドが通ったら、サンプルをビルドします。
$ 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でライブラリを作った場合は、ライブラリの生成先ディレクトリが異なります。下記のようにします。
$ 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に表示する例です。
$ DISPLAY=:1 \ LD_LIBRARY_PATH=/path/to/openvx/out/LINUX/aarch64/release/ \ ./a.out
もしcmakeでビルドしたライブラリを使う場合、ライブラリがバラバラのディレクトリに置かれているため、LD_LIBRARY_PATHに指定するパスがやや長くなります。
$ 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と指定してデバッグ情報を有効にしてビルドすることで、デバッグしやすくなります。
TightVNCサーバーを使うとアプリケーションの実行時に下記の警告が出ます。
Xlib: extension "RANDR" missing on display ":1".
警告が出ても動作はするのですが、気になる方は下記のようにTigerVNCをインストールするなど、RANDRに対応したVNCサーバーを使ってください。
# apt-get install tigervnc-standalone-server
目次: Windows
Windows 10は自動的にWindows Updateを実行し、勝手にPCを再起動することがあります。その際にウインドウの幅がズレることがあります。
ウインドウの幅が多少ズレても実用上害はありませんが、この状態と同時に発生する、フォント表示がボヤボヤになって、サイズがおかしくなり、非常に読みづらくなる症状が辛いです。目が痛くなってきます。
いずれの症状もPCを再起動すると直ります。直る理由すらわかりませんが、今のところ直らなかったことは一度もありません。
不思議なことにWindows Update後に必ずズレた状態になる訳ではなく、何か他の条件があるようです。人が見ていない夜中に再起動して、勝手にこの状態にハマるので、詳細は確認しようがないです。
最近のWindowsは再起動により、作業中のアプリケーションが全て終了され、当初かなりイライラしていました。
しかし今は「Windowsで大事な作業をしない」ことにより、諦めがつきました。デスクトップPCは勝手に再起動されては困るので、Windowsごと消しました。さようなら〜。
ノートPCは再起動されても特に問題ないのでWindowsを残しています。なぜなら最近Windows上で実行しているアプリケーションは、
しかないからです。あとは、たまに音楽プレーヤーやSteamを起動しますが、起動しっぱなしにはしません。たとえ強制終了されたとしても問題はありません。
この使い方はほぼシンクライアントですね。わざわざカスタムオーダーまでしてCore i5-8250と外部グラフィックスAMD Radeon RX550を積んだのに、彼らがSteam以外で活用されることはありません……。
つまり、もっとゲームをやりなさいということだな??
目次: ROCK64/ROCKPro64
ROCKPro64にはPCI Expressスロットが実装されています。せっかくあるので試そうと思い、玄人志向のSATAインタフェース増設カード(SATA3-PCIE-E2)と、USB 3.0インタフェース増設カード(USB3.0R-P2H2-PCIE)を買いました。
結論から先に言うとRK3399のPCI Expressコントローラは有効にできましたが、ROCKPro64の信号品質が良くないのかUSBのカードしか認識しませんでした。残念です。
唯一認識されるUSBのカードもPCI Expressのライザーカードで延長すると認識しなくなります。認識できるギリギリの信号なんですかね。
rockchip-pcie f8000000.pcie: PCIe link training gen1 timeout!
認識されないときはこんなエラーログが出ています。うーん。
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から転記しておくことにした。追記した。
目次: ROCK64/ROCKPro64
昔、私が投稿したパッチがLinux 4.20をデグレさせていました。Linux 4.20以降ではROCK64のUSBが動かなくなっています。全然気づきませんでした……。
Arch Linuxの人たちが「動かねーぞ??」とハマった挙句(リンク)に、指摘してくれたようです。
反省を込めて、ROCK64がデグレした理由をまとめておきます。
当時、私が直したのはピンに出力する信号の割り当て設定です。
GPIO0 A2
GPIO0 D3
上記のように、本来GPIO0 D3にはS/PDIF信号が割り当てられるはずですが、なぜか全く関係のないUSB電源供給信号が割り当てられており、S/PDIFが全く動作しない状態になっていました。
私のパッチはUSB電源供給信号のピンアサインをGPIO0 A2に直すパッチです。GPIO0 D3ピンからS/PDIFが無事出力できるようになりました。
しかし実装の間違いはこれだけではありませんでした。GPIO0 A2は信号の極性(Active High指定でしたが、本来はActive Lowが正しい)も間違っていたのです。
GPIO0 A2
私のパッチはピンアサインだけ直して、信号の極性を直さなかったため、USBの電源が常にダウンしてしまい、USBが全く動かなくなってしまったようです。
USB電源周りをいじったのに、USBの動作確認をせずにパッチを投稿してしまったのは、片手落ちだったなあと反省しきりです。
メモ: 技術系の話はFacebookから転記しておくことにした。
干支を3周しました。もう完全におじさんの仲間入りです。
若い人に自慢と説教だけはしないように気を付けよう。
せっかくHDMIディスプレイを買った(2019年2月2日の日記参照)ので、以前指摘されたRK3288のI2SとDMAがデグレしていないかどうか(2018年12月14日の日記参照)見るべく、linux-next + TinkerBoardのHDMI出力を確認しました。
映像は映り、音声も鳴りますが、48kHz ←→ 44kHzのLPCMを交互に再生すると、音声にバリバリとノイズが載ります。なぜかノイズが載らないときもあります。
ROCK64のアナログ出力でもこんな問題が起きていたので、同類だろうか?と不安になって、色々いじっていたのですが、どうも違う問題らしく、ディスプレイ側をON/OFFすると問題が発生するように見えます。
他のディスプレイで確認していないため、TinkerBoardが無罪とまでは言い切れませんが、おそらくディスプレイ側の問題でしょう。
目次: ROCK64/ROCKPro64
ROCKPro64のシリアルUART2が文字化けする問題に決着がつきました。
LKML(Linux Kernel Mailing List)に生息するナイスガイ達のおかげで、自分が持っているROCKPro64だけが異常値を示していることがわかりました。皆、普通にオシロスコープ持っているみたいですし、アイパターンまで見ていた人もいて、LKMLすげーな……と感心しました。
私のボードは、おそらくどこかにハンダ不良があり、RK3399からUART2ピンまでの抵抗値が異常に高くなっていると推測されます。
テスターで抵抗値を見ればわかるはずですが、ROCKPro64はボードのシルクに部品番号が全く書いておらず、どこにプローブを当てたら良いかさっぱりわかりませんでした。残念。
メモ: 技術系の話はFacebookから転記しておくことにした。
目次: ROCK64/ROCKPro64
メンテナーのHeikoさんからは「共通部分を変えようとしているから、他のボードの関係者にも聞いてくれ」とのことでした。そりゃそうだなと、RK3399のボードのデバイスツリーを変えていそうな人達にCCでメールしてみたところ、お返事がきました。
Tonyさんは、ROC RK3399 PCとROCKPro64の2つのバージョン(V2.0とV2.1、私が持っているのはV2.1)など、色々なボードでの立ち上がり、立ち下がり時間の測定値を教えてくれました。いずれも私が観測しているような症状はないとのことです。
Robinさんは、アイパターンを見てくれて、やっぱり異常はないと教えてくれました。
念のため、ピンに何か繋いでいる(インピーダンスが低い、立ち上がり時間が遅く計測される)のか、何も繋いでいない(インピーダンスが高い、立ち上がり時間が速く計測される)のかも確認しましたが、UART-USB変換ボードをジャンパケーブルで繋いでいるとのことでした。
うーん。話を総合すると、どうも私のボードの個体不良っぽいです。パッチは取り下げておきました。やりとりは面白かったですが、結果的には皆さんを混乱させてしまっただけでしたね。
目次: 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から転記しておくことにした。加筆した。
現在住んでいる家には私の作業部屋がないので、リビングの食事するテーブルで、ROCKPro64などのボードとオシロスコープとノートPCを置いて波形を見ています。
リビングのテーブルは広くて色々置けるものの、食事するときは邪魔なので撤去する必要があります。場合によって機材や配線の再セットアップが発生するのが難点です。あと、水が掛かる可能性があり、精密機械(オシロスコープとか)を置くには適していない気がしますが、他に置く場所もありません。
最近は、作業の中断から再開までの時間を短縮するため、リモートで作業するようにしています。ノートPCはリモートアクセス端末として使い、メインPCにリモートアクセスして作業しています。ノートPCのネットワークを切ったり、シャットダウンしたりしても、メインPCの開発、解析の環境はそのまま保持されますから、すぐに作業に復帰できるという寸法です。
ソフトウェアの開発をするなら十分な環境ですが、ROCKPro64のUART出力を解析したときのようにオシロスコープが必要になってくると、リモートアクセスだけではうまくいきません。今のところ、オシロスコープを常用することはないので問題はありませんが、今後必要になったときはもう一工夫いりますね……。
目次: GCC
目次: Linux
以前AArch64向けに開発環境を構築しました(その1、その2)。今回は流行りのRISC-Vに対して作成してみます。
全く違うアーキテクチャですが、AArch64向けと同じツール、ほぼ同じ手順が使えます。ツールを整備してくれた開発者の皆様には感謝の極みです。
さっと動かしてみたかったので、前回との変化点としてはbuildrootを使わず、busyboxのみの最小環境を作成しています。buildrootは後日チャレンジしたいと思います。
Crosstool-NGのct-ngのビルド方法は前回と全く同じ(2018年7月15日の日記を参照)なので、割愛します。
$ ./ct-ng menuconfig - Paths and misc options ---> [ ] Try features marked as EXPERIMENTAL 選択する - Target options ---> Target Architecture (alpha) ---> riscvに変更する [ ] Use the MMU 選択する Bitness: (32-bit) ---> 64-bitに変更する - Operating System ---> Target OS (bare-metal) ---> linuxに変更する - C-library ---> C library (musl) ---> glibcに変更する $ ./ct-ng build [00:34] /
設定もAArch64のときと大体同じですが、大きな違いはEXPERIMENTALを有効にする点です。通常はTarget Architectureの選択肢にRISC-Vが存在しません。
また、現時点だと32bit版はビルドエラーになるようなので、64bit版を選択しています。
AArch64のビルドとほぼ同じです。
$ git clone git://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git $ cd linux-next $ export ARCH=riscv $ export CROSS_COMPILE=riscv64-unknown-linux-gnu- $ make defconfig $ make all
ビルドが成功するとソースコードのトップディレクトリにvmlinuxが生成されるはずです。
AArch64ではqemuの -kernelオプションにImageファイルを渡せば起動しましたが、RISC-VではImageファイルを渡してもエラーになり起動しません。
調べてみると、qemuでRISC-V向けのLinuxを動作させるには、Imageではなくブートローダ付きのvmlinuxを渡してあげる必要があるみたいです。
$ git clone https://github.com/riscv/riscv-pk $ cd riscv-pk $ mkdir build $ cd build $ ../configure \ --enable-logo \ --host=riscv64-unknown-linux-gnu \ --with-payload=../linux-next-riscv/vmlinux $ make
成功するとbuildディレクトリの下にbblという名前のファイルができます。これがブートローダ+カーネルのバイナリです。bblはBerkeley Boot Loaderの略です。
このリポジトリの名前pkはProxy Kernelの略で、RISC-Vのプロセッサ開発を行う際に、周辺のハードウェアを作り込む代わりに、ホストのシステムコールを呼び便利な実行環境を提供するためのソフトウェアのようです。
プロキシカーネルに用事はないんですけど、付属品のブートローダに用事があります。
このriscv-pkはビルドシステムがちょっとイマイチで、buildディレクトリを作らずにconfigureやmakeをすると、ソースコードの入っているpkディレクトリが吹っ飛びます。ご注意ください……。
以前はbuildrootを使って全自動でinitramfsを生成してもらいましたが、今回は趣向を変えまして、手動でinitramfsを作ります。
$ git clone https://git.busybox.net/busybox $ cd busybox $ export CROSS_COMPILE=riscv64-unknown-linux-gnu- $ make menuconfig - Settings ---> [ ] Build static binary (no shared libs) (NEW) $ make
ビルドに成功するとbusyboxという実行ファイルが生成されるはずです。
次にinitramfsを作成します。基本的な流れはディレクトリに必要なファイルを配置し、cpioで固めるだけです。
$ mkdir initramfs-work-riscv $ mkdir initramfs-work-riscv/root $ cd initramfs-work-riscv/root $ mkdir bin $ cp ../../busybox/busybox bin/ $ ln -s busybox bin/sh $ ln -s bin/busybox init $ mkdir dev $ sudo cp -a /dev/tty* dev/ $ find . | cpio --format=newc -o > ../initramfs.cpio
本来はinit, sh以外のシンボリックリンクも作った方が良いです。このあと、qemuで動かしてみたらわかりますが、すごく不便です。/dev/ttyも横着してホストマシンのデバイスファイルをコピーするのではなく、mkdevで作るべきです。
が、しかし、美しいinitramfsは次回トライするbuildrootにお任せしましょう。今回は適当なまま行きます。
実行する設定はAArch64とは違います。qemuの引数は多すぎるし難しすぎるので、全く覚えられません。私の場合は、動かすたびにわからなくなるので、調べることが多いです。
$ qemu-system-riscv64 \ -machine virt \ -kernel riscv-pk/build/bbl \ -initrd initramfs-work-riscv/initramfs.cpio \ -serial stdio bbl loader vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv vvvvvvvvvvvvvvvvvvvvvvvvvvvv rrrrrrrrrrrrr vvvvvvvvvvvvvvvvvvvvvvvvvv rrrrrrrrrrrrrrrr vvvvvvvvvvvvvvvvvvvvvvvv rrrrrrrrrrrrrrrrrr vvvvvvvvvvvvvvvvvvvvvvvv rrrrrrrrrrrrrrrrrr vvvvvvvvvvvvvvvvvvvvvvvv rrrrrrrrrrrrrrrrrr vvvvvvvvvvvvvvvvvvvvvvvv rrrrrrrrrrrrrrrr vvvvvvvvvvvvvvvvvvvvvv rrrrrrrrrrrrr vvvvvvvvvvvvvvvvvvvvvv rr vvvvvvvvvvvvvvvvvvvvvv rr vvvvvvvvvvvvvvvvvvvvvvvv rr rrrr vvvvvvvvvvvvvvvvvvvvvvvvvv rrrr rrrrrr vvvvvvvvvvvvvvvvvvvvvv rrrrrr rrrrrrrr vvvvvvvvvvvvvvvvvv rrrrrrrr rrrrrrrrrr vvvvvvvvvvvvvv rrrrrrrrrr rrrrrrrrrrrr vvvvvvvvvv rrrrrrrrrrrr rrrrrrrrrrrrrr vvvvvv rrrrrrrrrrrrrr rrrrrrrrrrrrrrrr vv rrrrrrrrrrrrrrrr rrrrrrrrrrrrrrrrrr rrrrrrrrrrrrrrrrrr rrrrrrrrrrrrrrrrrrrr rrrrrrrrrrrrrrrrrrrr rrrrrrrrrrrrrrrrrrrrrr rrrrrrrrrrrrrrrrrrrrrr INSTRUCTION SETS WANT TO BE FREE [ 0.000000] OF: fdt: Ignoring memory range 0x80000000 - 0x80200000 [ 0.000000] No DTB passed to the kernel [ 0.000000] Linux version 5.0.0-rc7-next-20190225 (katsuhiro@blackbird) (gcc version 8.2.0 (crosstool-NG 1.23.0.610-db4fdf0)) #2 SMP Tue Feb 26 19:07:38 JST 2019 [ 0.000000] Initial ramdisk at: 0x(____ptrval____) (1691648 bytes) [ 0.000000] Zone ranges: [ 0.000000] DMA32 [mem 0x0000000080200000-0x0000000087ffffff] [ 0.000000] Normal empty [ 0.000000] Movable zone start for each node ... [ 0.346331] sit: IPv6, IPv4 and MPLS over IPv4 tunneling driver [ 0.348500] NET: Registered protocol family 17 [ 0.349051] Key type dns_resolver registered [ 0.370752] Freeing unused kernel memory: 192K [ 0.370952] This architecture does not have kernel memory protection. [ 0.371164] Run /init as init process can't run '/etc/init.d/rcS': No such file or directory Please press Enter to activate this console. / # ls -/bin/sh: ls: not found / # busybox uname -a Linux (none) 5.0.0-rc7-next-20190225 #2 SMP Tue Feb 26 19:07:38 JST 2019 riscv64 GNU/Linux
無事Linuxの起動画面を拝めました。良かった良かった。
< | 2019 | > | ||||
<< | < | 03 | > | >> | ||
日 | 月 | 火 | 水 | 木 | 金 | 土 |
- | - | - | - | - | 1 | 2 |
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 | - | - | - | - | - | - |
合計:
本日: